반응형

<?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>

 


$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>");

 

GET 방식 파라미터 val의 값을 go 변수에 담는데, val 파라미터에 값이 없으면 val 파라미터의 값이 1인 페이지로 이동되고, admin page가 뜬다.

 


if(preg_match("/2|-|\+|from|_|=|\\s|\*|\//i",$go)) exit("Access Denied!");

 

go 변수에 담긴 값에서 2, '-', '+', from, '_', '=', '\s(공백)', '*', '/' 값이 발견되면 Access Denied!를 출력한다.

 


$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!");
}

 

1 ~ 5 사이에서 랜덤으로 값을 뽑아 해당 값에 맞는 SQL 쿼리를 날려 result 변수에 값을 담는다.

 


 

$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);
}

 

랜덤값에 해당하는 SQL 쿼리문의 응답을 data 변수에 담고, data[0]의 값이 없으면 query error를 출력하고 종료한다.

 

data[0]의 값이 1이면 Access_Denied!를 출력하고, 2이면 문제가 풀린다.

 


풀이

 

랜덤값에 해당하는 SQL 쿼리문에 내가 입력한 val의 값이 들어간다.

 

그리고 해당 쿼리에 맞는 lv의 값을 배열 형태로 data에 저장하고, data[0]의 값이 2이면 문제가 풀린다.

 

즉, val 파라미터에 입력한 값이 2이면 아래와 같이 쿼리문이 완성되고, lv가 2인 컬럼이 출력될 것이다.

 

select lv from chall7 where lv=2

 

하지만 필터링에서 val 파라미터에 2를 직접적으로 입력할 수 없고 '-'와 '+' 문자들도 필터링되기 때문에 연산을 통해 2를 만드는 방법을 사용할 수도 없다.

 

2를 만드는 방법은 char()이나 mod() 함수 등을 이용하면 된다.

 

 

하지만 char(50)으로 val의 값을 2로 만들어주면 query error가 뜬다.

 

즉, data[0]에 값이 없다는 것이다.

 

union을 이용하면 두 개의 sql 쿼리문의 결과를 하나로 통합할 수 있기 때문에 union select 문을 사용하면 되는데 필터링에서 공백을 처리하고 있으므로 "union(select(char(50)))# "와 같은 형태로 쓰면 된다.

('-' 기호는 필터링 되고 있으므로 '--'로 주석 처리를 못하니 '#'으로 주석처리한다.)

(union sqli는 기존의 sql문을 무효화 시키고 공격자가 작성한 sql문으로 결과를 가져올 때 사용한다.)

 

그러면 "where lv = " 절에서는 false가 뜨게 되어 무효화 되고, union으로 2를 이어주어 결과값이 2가 출력되고 result에는 2가 담긴다.

 

최종적으로는 data[0] = 2가 된다.

 

select lv from chall7 where lv=0)union(select(char(50)))%23

 

 

랜덤값으로 인해 괄호의 개수가 달라지므로 새로고침을 몇 번 하다보면 문제가 풀린다.

반응형

'전쟁 > Webhacking.kr' 카테고리의 다른 글

[Webhacking.kr] old-46  (0) 2022.07.21
[Webhacking.kr] old-49  (0) 2022.07.21
[Webhacking.kr] old-61  (0) 2022.07.19
[Webhacking.kr] old-59  (0) 2022.07.19
[Webhacking.kr] old-5  (0) 2022.07.14

+ Recent posts