PC is an 'Intermediate' rated box on Offsec Proving Grounds. It is a Linux machine hosting a remote Terminal access via snap on port 8000 HTTP. Since there is no need to establish a foothold, once we access the terminal, we find a vulnerable version of rpc.py that we can exploit to elevate our privileges to root.
Enumeration
We start with an nmap scan.
sudo nmap -A 192.168.167.210
Only two ports that we can see so far, with port 8000 HTTP being the service we're going to investigate.
An interesting result from the nmap scan is that the HTTP Title for the website being hosted is 'Terminal'.
Vulnerability Analysis and Foothold
Browsing to http://192.168.167.210:8000 leads us here:
Very interesting. It appears to be a fully functional terminal. Let's do some test commands.
Looks like it works. We'll do some general enumeration, to include investigating the user's home directory, what permissions we have, and what processes are running on the box. Of interest, we see this python script being run in /opt/.
ps -elf
Taking a look inside to see what's what.
from typing import AsyncGenerator
from typing_extensions import TypedDict
import uvicorn
from rpcpy import RPC
app = RPC(mode="ASGI")
@app.register
async def none() -> None:
return
@app.register
async def sayhi(name: str) -> str:
return f"hi {name}"
@app.register
async def yield_data(max_num: int) -> AsyncGenerator[int, None]:
for i in range(max_num):
yield i
D = TypedDict("D", {"key": str, "other-key": str})
@app.register
async def query_dict(value: str) -> D:
return {"key": value, "other-key": value}
if __name__ == "__main__":
uvicorn.run(app, interface="asgi3", port=65432)
This doesn't seem like a simple script at first glance, a quick Google search can confirm this a is project found on https://pypi.org/project/rpc.py/.
According to the description, rpc.py is a fast and powerful RPC framework based on ASGI/WSGI. Based on WSGI/ASGI, you can deploy the rpc.py server to any server and use http2 to get better performance. And based on httpx's support for multiple http protocols, the client can also use http/1.0, http/1.1 or http2.
Searching the web, we find that rpc.py through 0.6.0 allows Remote Code Execution because an unpickle occurs when the "serializer: pickle" HTTP header is sent. In other words, although JSON (not Pickle) is the default data format, an unauthenticated client can cause the data to be processed with unpickle.
Privilege Escalation
This PoC script on GitHub written by fuzzlove weaponizes this vulnerability. We'll pull his script down, configure it to our purposes, and transfer it to our victim.
We'll change the highlighted portion to our own IP.
Once transferred, we'll spin up a nc listener on TCP port 9091, execute our script on the victim, and catch our shell.
nc -nvlp 9091
Success! Now we can grab proof.txt.








