前言
练习平台:BUUCTF
web部分会一直更,争取做一只合格的web狗 XD
0x00 [HCTF 2018]WarmUp
*考察点:phpmyadmin CVE-2018-12613 *
直接看源码:
1 |
|
这里如果是研究过phpmyadmin
的CVE-2018-12613
,那么应该很熟悉hhh。
一个LFI
,直接构造payload
打一发,得到flag
。
payload:?file=source.php%253f/../../../../../../../ffffllllaaaagggg
0x01 [QWB 2019]随便注
考察点:堆叠注入
测试的时候可以发现有严格的过滤,于是考虑堆叠注入。
知道是堆叠注入之后可以一路爆数据库名,表名,列名:flag in ctftraining --> FLAG_TABLE --> FLAG_COLUMN
关键是过滤了select
,要如何读取字段的值呢?
注意我们一开始就有默认查询的words
表,既然没有过滤alert
和rename
,那我们是不是可以给表和列都改个名字,让程序默认查询FLAG_TABLE
里的FLAG_COLUMN
呢。
思路大概就是这样,今天又试了一下,不知道为啥把题目改挂了= =,等docker重置了再说吧。
0x02 [QWB 2019]高明的黑客
考察点:脚本批量搜索
也是QWB的题目,我们的目标就是找到一个webshell,然后读flag。
由于wtcl
,这里先用@glzjin师傅的脚本:
1 | # 批量扫描测试$_GET和$_POST 找到含有有效传参点的文件 |
然后再本地开一个服务器,扫描后可以得到xk0SzyKwfzw.php
存在传参点,审计一下可以找到Efa5BVG
这个参数,最后传参读flag。
payload:/xk0SzyKwfzw.php?Efa5BVG=cat%20/flag
0x03 easy_tornado
考察点:SSTI、tornado附属文件
点开链接发现有三个文件,flag.txt
里提示flag在/fllllllllllllag
中;welcome.txt
提示render()
渲染函数,文件内容会直接显示在页面上;hints.txt
提示我们访问的文件存在一个以文件名和密钥组成的签名认证,即:md5(cookie_secret+md5(filename))
这里刚开始以为是hash长度拓展攻击,想写脚本爆破cookie_secret
长度,后来发现好像并没有太大关系= =。
知识盲区:在Error
页面存在SSTI
,tornado
框架存在附属文件`handler.settings`
于是输入:?msg={ {handler.settings} }
得到cookie_secret
:M)Z.>}{O]lYIp(oW7$dc132uDaK<C%wqj@PA![VtR#geh9UHsbnL_+mT5N~J84*r
之后就是简单的字符串拼接和md5
加密,不多赘述。
0x04 [0CTF]piapiapia
考察点:字符逃逸
打开链接,是一个登录页面,还有一张猫图:
直接登录会返回Invalid user name
或者 Invalid user name or password
,看页面源码发现没东西,于是扫目录,发现www.zip
里有源码,于是开始审计代码。
篇幅有限,只写下关键代码:
1 | // profile.php 反序列化 =》任意文件读取 |
省略前面的登录部分,这里我们可以发现如果$profile['photo']
可控的话,可以实现任意文件读取。
1 | // update.php 控制$profile |
跟进$profile,在update.php中,可以看到$profile
除了$profile[photo]
以外都是通过表单以POST形式传参,$profile[photo]
传入的文件名被md5加密了而不可控(另外也考虑过上传webshell读flag,/upload直接禁止访问貌似没戏),那么我们继续跟进update_profile()
,看看从序列化到反序列化中进行了什么操作。
1 | public function update_profile($username, $new_profile) { |
我们发现$profile被fileter()过滤了一遍,再跟到fileter()
看一看。
1 | public function filter($string) { |
emmm乍看之下没有什么问题,我们分析一下最后一行:把$string(也就是$profile
)中含有的$safe都换成’hacker’,这里的利用方法就很巧妙了。。。
1 | // config.php **flag** |
首先明确思路:flag在config.php
中,如果可以通过profile.php
中的反序列化覆盖$profile['photo']
实现任意文件读取,flag就到手辣!
利用姿势
在过滤函数fiter()
中,把序列化字符串中select、insert、update、delete、where
都替换成hacker
,如果稍微了解序列化原理就会发现问题,$safe
中where
的长度是5,而hacker
的长度为6,这就会导致在替换之后,反序列化还原时产生截断,也就是hacker
的最后一个字符'r'
是不会被读取的,这就造成了字符逃逸。
正常语句:
a:4:{s:5:"phone";s:11:"12345678909";s:5:"email";s:16:"123123@gmail.com";s:8:"nickname";a:1:{i:0;s:12:"sketch_pl4ne";}s:5:"photo";s:10:"config.php";}
计算需要逃逸的字符数:
构造payload:
payload:wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php
抓包写入:
注意:这里是通过nickname
来输入payload
,但是nickname
是有限制的,需要使用数组绕过。
1 | <html> |
最后在profile.php
页面的图片src
属性解base64
得到flag
(这也是为什么一开始会想到文件包含)
0x05 admin
考察点:Unicode安全
打开题目到处看,在修改密码页面发现源码泄露。
发现貌似是一个用python写的登录模块,在routes.py
中我们发现问题:
1 |
|
注意到在注册时是先将用户名转小写,再与原用户名比较。也就是说,我们以Admin
注册,相当于是以admin
注册,再看更改密码函数:
1 | def change(): |
那么如果我们能注册到一个Admin
用户的话,是不是就可以通过更改密码选项来改管理员admin
的密码?
这里我们需要了解Unicode安全。。
按照文章所说,注册一个用户名为ᴬdmin
的用户,再用更改密码重置admin的密码,最后登录即可获得flag。
思考:如果admin的密码是上一个人重置的的话,很大的可能是弱密码,是不是可以考虑直接爆破 (弟弟行为
0x07 [CISCN 2019]Dropbox
考察点:phar://协议伪造其他文件绕过上传检测
参考文章:初探phar://
我们主要需要了解以下几点:
- phar.phar文件的data数据是以序列化形式存储的
- 由于.phar文件通过
stub(也就是"__HALT_COMPILER();?>")
识别,对文件头以及后缀没有要求 - phar.phar文件通过phar://可以读取
@glzin师傅的脚本:
1 |
|
最后访问抓包,filename改为:phar://phar.jpg/exp.txt
即可得到flag:
0x08 [CISCN 2019]ikun
考察点:python web 脚本编写与代码审计(反序列化)、审查元素、薅羊毛逻辑
打开题目,是一个ikun的粉丝应援团界面,按照惯例先探索一下功能。
看到说要买到lv6的大会员,但是我们发现下面貌似没有lv6,而且总共有500页。
一页一页找是不现实的,我们可以写一个小jio本,当出现lv6.png
的时候就打印出page
1 | # -- coding: utf-8 -- |
然后找到在第181页
然后购买,发现lv6很贵,买不起,但是审查元素的时候发现折扣和价格是以post
的形式传参的,直接修改即可。
然后跳转到b1g_m4mber
页面,提示只有admin
可以访问,这里先尝试XFF未果,然后将目标转向cookie
里的JWT
字段。
JWT简介:JWT(json web token)是目前最流行的跨域身份验证解决方案。JWT结构会改对象为一个很长的字符串,字符之间通过”.”分隔符分为三个子串。每一个子串表示了一个功能块,总共有以下三个部分:JWT头、有效载荷和签名。其中签名通常需要指定一个密码。经过查阅资料以后了解到是一个储存在客户端的令牌,会不会是这里限制了我们的身份呢?我们把抓取到的jwt
字段解码一下:
果然这里是我们自己的用户名,直接改成”admin”的话签名肯定是不对的,我们还需要知道加密密钥。
这里用Github
上的一个工具破解出密钥:
填入密钥,修改username
为admin
,加密得到JWT
,替换原字段值即可以admin
访问。
审查元素发现给出源码,python web
蒟蒻一枚的我,只能看dalao的writeup,发现是python 反序列化,主要代码如下:
1 | class AdminHandler(BaseHandler): |
我们发现p
可以像’This is Black Technoloy!’一样打印在页面上,所以我们需要想办法让p
里有flag,也就是become的传参是我们payload的输入点。
脚本如下:
1 | # -- coding: utf-8 -- |
将构造好的payload
传入become,即可获得flag。
0x09 [ASIS 2019]Unicorn shop
考察点:Google Hacking、脑洞
页面有一个表单,分别是id
和price
两个参数,审查元素发现hint:
这里扫了目录,也人工fuzz了一下admin.password
路径,没有源码泄露,猜测admin.password
是注入时提示的数据库名、表名之类的?
于是抓包手工测试两个参数,发现price
只能输入一个字符:
然后思路就断了,google一下,发现是unicode编码问题,我们要做的就是用一个字符买到超独角兽:
详情参考:unicorn shop (Github上的,不用fq
这个脑洞也就忍了,之前看到过,但是这几个蜜汁提示到底是什么意思?
google hacking很重要= =
0x0A [De1CTF 2019]SSRFme
考察点:代码审计,GET命令漏洞
源码:
1 |
|
大致意思是以GET方式获取两个参数url
和filename
,先创建一个沙盒,然后url
与GET拼接执行命令;执行结果写入到filename
中。
一直卡在拼接GET
到底是要干什么,是要绕过还是什么;后面看wp发现它也是一条命令,而且还能够导致命令执行。
GET命令漏洞:
GET命令底层是perl中的open实现的,而open是可以执行命令的,并且还支持file协议。
所以我们的思路就是创建一个可以执行命令的文件名,然后用file协议读取文件。
payload:
1 | ?url=file:bash%20-c%20/readflag|&filename=test // 创建文件 |
另外还有反弹shell的思路,有时间再补上吧= =
0x0B fakebook
考察点:SQLI + SSRF、反序列化
网鼎杯的一道原题
先注册一个账号,四处点一点,发现存在注入点:/view.php?no=1
爆表名、列名、列值
1 | no=0 order by 1,2,3,4,5 /*4列*/ |
观察一下这个序列化的字符串,是一个有姓名,年龄,博客的对象:
前面我们注意到users表是有四列的,最后一列是blog contents
,审查元素发现有一个base64编码,根据经验flag可能从这里出。
扫描目录,发现robots.txt
存在源码泄露,是users.php
,审计一下发现存在SSRF
1 |
|
这样我们的思路就比较明确:user.php
过滤了http协议,前面报错我们可以知道服务器的web绝对路径为/var/www/html
,所以可以用file协议直接读取flag.php
,构造查询语句时请求结果保存在blog contents
中,即可读取flag
payload:no=0 union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:12:"sketch_pl4ne";s:3:"age";i:18;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'
flag到手~
0x0C [CISCN 2019] laravel1
考察点:laravel代码审计,反序列化
laravel框架没了解过,也没审计过这么多文件,审计的时候也是一头雾水,写得不好还请见谅。
一开始提示了我们要用反序列化:
1 |
|
顺便把源码下载下来,然后开始审计。
既然是要反序列化,那我们先搜索一下魔法函数__destruct()
:
发现有很多,这里貌似都是一个一个找的。。。 不过很多都是没有实现的空函数,我们一般会找有函数调用的地方,比如这个:
然后跟进commit()
看一下:
继续跟进invalidateTags()
:
漏洞代码:
1 | if ($this->deferred) { |
这里的$this->pool
是AdapterInterface类的一个对象,并且调用了saveDeferred()
方法,我们可以查找既实现了AdapterInterface接口,同时saveDeferred()函数又可以利用的类,比如PhpArrayAdapter.php
:
跟进initialize()
:
发现存在文件包含,我们只需将$this->file
重写为我们想读的文件即可。
这只是其中一个利用链,还有官方命令执行的做法可以看参考链接自行复现,下面是 tr1ple 师傅的exp:
1 |
|
flag到手
参考链接
小结
信安路上的小学生,努力做题ing : )