이번에는 300점인 7번 문제를 풀어보도록 하자.
페이지에 들어가면 첫화면은 이렇게 나온다.
auth 버튼을 눌러봐도 Access_Denied! alert창만 뜨게 된다.
view-source를 클릭하여 소스코드를 확인해보자.
<?php
include "../../config.php";
if($_GET['view_source']) view_source();
?><html>
<head>
<title>Challenge 7</title>
</head>
<body>
<?php
$go=$_GET['val'];
if(!$go) { echo("<meta http-equiv=refresh content=0;url=index.php?val=1>"); }
echo("<html><head><title>admin page</title></head><body bgcolor='black'><font size=2 color=gray><b><h3>Admin page</h3></b><p>");
if(preg_match("/2|-|\+|from|_|=|\\s|\*|\//i",$go)) exit("Access Denied!");
$db = dbconnect();
$rand=rand(1,5);
if($rand==1){
$result=mysqli_query($db,"select lv from chall7 where lv=($go)") or die("nice try!");
}
if($rand==2){
$result=mysqli_query($db,"select lv from chall7 where lv=(($go))") or die("nice try!");
}
if($rand==3){
$result=mysqli_query($db,"select lv from chall7 where lv=((($go)))") or die("nice try!");
}
if($rand==4){
$result=mysqli_query($db,"select lv from chall7 where lv=(((($go))))") or die("nice try!");
}
if($rand==5){
$result=mysqli_query($db,"select lv from chall7 where lv=((((($go)))))") or die("nice try!");
}
$data=mysqli_fetch_array($result);
if(!$data[0]) { echo("query error"); exit(); }
if($data[0]==1){
echo("<input type=button style=border:0;bgcolor='gray' value='auth' onclick=\"alert('Access_Denied!')\"><p>");
}
elseif($data[0]==2){
echo("<input type=button style=border:0;bgcolor='gray' value='auth' onclick=\"alert('Hello admin')\"><p>");
solve(7);
}
?>
<a href=./?view_source=1>view-source</a>
</body>
</html>
문제를 풀기 위해서는 $data[0]의 값을 2로 만들면 된다. data에 배열로 값을 저장하고 있으므로 $result의 값을 2로 만들어 $data에 저장하면 된다.
위로 올라가 조건문을 살펴보게 되면 rand(1,5)함수를 이용하여 1/5확률로 조건문이 실행되게 하는데, 우리는 rand=1일 때의 조건문을 가지고 쿼리문을 조작해보자.
결국에는 "select lv from chall7 where lv=($go)"의 값이 result변수에 담기게 된다.
테스트를 진행해보기 위해 url의 val 파라미터에 기존에 1을 2로 바꾸어 요청해보자.
결과는 다음과 같다. 이렇게 된 이유는 chall7테이블의 lv=2인 컬럼에 어떤 값이 들어있는지 모르기 때문에 직접 2라는 값을 넣어서 쿼리를 보내야한다.
하지만 쿼리 전 if(preg_match("/2|-|\+|from|_|=|\\s|\*|\//i",$go)) 부분에서 "2, -, +, from, _, =,"2” “-” “+” “from” “_” “=” “\s” “*” “/”과 같은 문자열이 필터링 되고 있으므로 유의해서 쿼리문을 짜야한다.
SQL 함수중 CEIL()이라는 반올림 함수가 있으므로 1.9의 값을 입력해 2를 만들어 union select 구문에 넣고, 뒤의 die()쿼리 부분을 주석처리해야 하는데 "-"문자가 필터링 되므로 #(%23)을 넣어본다.
쿼리문 : 0)UNION(SELECT(CEIL(1.9)))%23
1/5의 확률이기 때문에 5번정도 시도하면 문제가 해결된 것을 확인할 수 있다.
'CTF & WarGame > webhacking.kr' 카테고리의 다른 글
[webhacking.kr] 9번 문제 (0) | 2020.03.01 |
---|---|
[webhacking.kr] 8번 문제 (0) | 2020.02.29 |
[webhacking.kr] 6번 문제 (0) | 2020.02.27 |
[webhacking.kr] 5번 문제 (0) | 2020.02.27 |
[webhacking.kr] 4번 문제 (0) | 2020.02.25 |