Post

Webverselabs ScanPortal Challenge Command Injection

Webverselabs ScanPortal Challenge Command Injection

Scenario :

ScanPortal is an attack surface management platform for SMBs. The developer recently hardened the nmap call after a code review flagged it. What they missed is that every submitted target is also appended verbatim to a shared scan log, and the customer-facing log search runs grep on that file with the user’s pattern dropped straight into a shell command.

Solution :

image

We first start by creating a new account and login in , to be able to enumerate the application further .

image

We are able to identify multiple endpoints, let’s go through each one of them :

/Assets :

image

This just gives us a list of IP addresses , hostnames , and OS for each server running.

/Vulns :

image

This is a list of vulnerabilities found ranked by criticality .

/Scans :

image

/Scan Logs :

image

This is the log file of all scans performed , for now we haven’t done any .

The only endpoint that looks interesting is the /scans endpoint , if we perform a scan and look at the request :

image

We see that it sends a POST request to the server , with the IP we specified as well as scan_type ,then it redirects us to the scan result page : the server is probably doing an nmap scan in the background and returning to us the result in a table format .

image

Whenever we suspect the backend may execute commands based on user input, we should test for command injection. If inputs aren’t properly sanitized, we may be able to execute arbitrary commands on the server.

I have a detailed section in my web_methdology for command injections based on the CWES path :

1
https://elmehdilaassiri.github.io/posts/web-app-pentesting-methodology/#command-injection-

Now first i injected a semi column in both parameters to see if it will break anything .

image

We see that if we inject the IP address field , it will just be returned to us which means it wasn’t executed by the server.

Checking the scan_type parameter returned the same thing, i tried multiple payloads :

image

At first i thought maybe we can break our of a “” or ‘’ , maybe injecting ${} will execute commands inside the quotes rather than returning it via an echo command or something but that didn’t work .

Finally i moved back to the Logs :

image

We see that we are able to search for specific logs, maybe the server is using a command in the backend this time as well to fetch for specific logs based on keywords, if we check Burp’s History :

image

Let’s try to use the same injection payloads from earlier on this parameter :

image

Good news we manage to get a different error this time :) , the server is telling us that we got an unterminated quote .

Probably we have a grep command running in the background or some other linux command :

1
grep "aaaa"";${id}

I think having 3 quotes broke it, let’ try adding a fourth one :

image

We no longer have the quotation problem , but we get a permission denied .

image

I first thought that we can only add different files to the command to trick the app into rendering the file but that didn’t work either :

image

Another thing we can try is once we break out of the “” , and we add our command , we comment out the rest just like we do in a normal SQLi , to make sure we don’t break the original command syntax.

image

This works perfectly :

Now we can easily get our flag :

image

Let’s also try to read the source code to see what was really going on in the backend .

image

The app source code is in app.py :

image

Perfect , we see that it was indeed using a grep command and putting everything inside a double quotes , so when we added “ we broke out of it and were able to execute our code .

That was all for this challenge , see you in the next one :)

This post is licensed under CC BY 4.0 by the author.