adm1nkyj (ㄱㅇㅈ) 님이 만드신 문젠데 어휴 어려웠다 ㄹㅇ
이 문제의 소스를 보자.
<?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__);
}
?>
보면 union 인젝션은 막혀있지 않다. 이걸 이용해서 인젝션을 해야한다고 추측을 했었다.
근데 기존의 union 인젝션은 컬럼명을 알아야지 데이터를 뽑아올 수 있었는데,
이 생각을 깨게 만들어준 문제기도 하다. 해결방법은 아래와 같다
mysql에는 서브쿼리라는 게 존재하고 from에다가 서브쿼리를 써주면 가상테이블이 생성된다.
가상테이블에서 이리저리 굴려서 alias를 해주면 아래와 같은 페이로드가 나오게 된다.
pw=' union select 1,b,3,4,5 from (select 1,2,3,4 b,5 from findflag_2 where 1=2 union select * from findflag_2)x%23
from쪽에 서브쿼리르 써주면 가상테이블의 컬럼명을 alias화 시킬 수 있으며
이 가상테이블을 alias해주고 최종적으로 union에서 뽑아준다. 이값은 플래그 값이고
패스워드는 id에다가 이리저리 굴려서 확인할 수 있으니 해보면 된다.
'Write up > Wargame' 카테고리의 다른 글
[Wargame.kr] All Clear (0) | 2016.09.13 |
---|---|
[Wargame.kr] zairo (0) | 2016.09.08 |
[Wargame.kr] strcmp (550p) (0) | 2016.04.29 |
[Wargame.kr] Easy_CrackMe (500p) (0) | 2016.04.29 |
[Wargame.kr] md5 password (0) | 2016.04.29 |