ChoCho Parrot (Web)
Step 1: Test for SSTI
While testing the input field, I noticed that whatever I typed into it was echoed back in the response. This is a sign that the application might be directly rendering our input inside a server-side template.

To test this hypothesis, I sent the basic SSTI payload {{7*7}}
, but it didn't work. After trying a a few other payloads, and they all failed, I decided to move on to another vulnerability.

Step 2: Try Command Injection
I decided to try command injection by testing various payloads by using symbols like |
, &&
, and ;
.
|id

Step 3: Enumerate the File System
Let’s look around for the flag.
|ls

I found a directory named ChoChoSecrets
so let's check it out
|ls ChoChoSecrets
Found a file named myfavENVvariable.txt

Step 4: Dump Environment Variables
|cat ChoChoSecrets/myfavENVvariable.txt

The file hinted that something interesting is stored in the environment variables.
|printenv
And here we found the flag

Why Did |
Work, but ;
and &&
Didn’t?
|
Work, but ;
and &&
Didn’t?When user input reaches a shell, symbols like ;
, &&
, and |
are used to chain or control commands:
;
– runs multiple commands sequentially&&
– runs the next command only if the previous one succeeds|
– takes the output of one command and pipes it into another
In command injection, we try to break out of the original command context and inject our own.
Since only the pipe (|
) worked, while others like ;
, &&
, and ()
failed. That tells us that the application is filtering some characters but not others.
To confirm this, I viewed the source code by running:
|cat app.py
And here's what the relevant part showed:
sanitized_input = user_input.replace("(", "").replace(")", "").replace("&", "").replace(";", "")
result = subprocess.run(f"echo {sanitized_input}", shell=True, capture_output=True, text=True)
This tells us two things:
shell=True
: The input is being passed to a real shell, meaning any shell metacharacter that survives sanitization can trigger command execution.The app removes
(
,)
,&
, and;
, but leaves|
intact
That’s why payloads like ; id
or && id
were blocked, but | id
successfully triggered execution. The input ends up like this:
echo | id
Even though echo
produces no output, the pipe still causes the id
command to execute, and the output gets captured.
Last updated
Was this helpful?