Old-07 Domain & Tool

  • 구분 : 코드 잘 읽기 & 파라미터 조작 & SQL
  • 문제풀이에 사용된 도구 
    • Chrome 103.0.5060.66 관리도구[F12]

Old-07 Question & Answer

7번문제에 들어가면 Admin page라는 페이지와 auth라는 button, 소스를 볼 수있는 a태그가 존재한다. 특별한점은 url에 GET방식으로 val=1이 있다는거 정도 겠다. 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>

문제를 푸는 solve(7)은 sql을 실행한 결과가 2일때 동작하도록 되어있다. SQL은 다음과 같다.

  • "select lv from chall7 where lv=($go)"

그리고 $go를 넣는 조건절은 랜덤하게 괄호가 쳐져있다. 아이러닉한건, SQL에 얼마나 괄호를 둘러싸든 결과는 똑같다는 것이다. 랜덤은 5개중 하나로 동작하니, 단순하게 5번의 새로고침이 필요하겠다라고 생각하자

 

preg_match함수는 대표적인 php의 필터링 함수이다. 이곳에서 막힌 문자는 다음과 같다.

  • 2 : 사용자가 $go에 2를 넣는것을 방지
  • -,*,+,/,= : 사칙연산으로 2를 만드는 것을 방지
  • from : 다른 table참조 방지
  •  _,\,/s : 아마 정규표현식을 막으려고하는거 같은데, 잘 모르겠다.

또한 /i옵션을 부여하여 대소자구분을 없앴다.(응? 여기 영어 from밖에 없지 않나?) $go는 url의 get방식으로 전달된 파라미터 val의 값을 그대로 가지고 간다. 예시로 막히는 값을 집어넣어보면

막혔음을 확인할 수 있다. 물론 preg_match를 통과하였으면 운좋게도 성공할 수도는 있지만 보통

그렇다. 결국 2는 만들어야한다. 뭐 사실 2라는 말을 안쓰고 2를 만드는 방법은 무궁무진하다. mod연산을 이용해도 되고(나머지연산자인 %는 안막았다) 진법을 바꾸어 2진수나 ascii로 표현하는것도 방법이다.(SQL에서는 INTEGER에 대해 '2'나 2나 다르지 않으니 말이다)  우선 mod를 이용해서 다음과 같은 val값을 넣어주었다.

  • 0)union(select(mod(6,4))
    • 해석 : lv가 2인값을 찾으면 되니 union select가 필요한가? 라는 생각을 할 수도 있는데, 이 table에 lv가 2인 행이 없을 수도 있다. 따라서 union으로 넣어주는게 마음이 편할거다. 괄호가 한개있다는 가정으로 끝에 괄호하나만 생각했는데, 이대로 새로고침 여러번 해보면 한번 얻어걸린다(5번 중 한번이라 유의미한 얻어걸림이다.)

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

[Webhacking.kr] old-09 Answer  (0) 2022.07.14
[Webhacking.kr] old-08 Answer  (0) 2022.07.10
[Webhacking.kr] old-06 Answer  (0) 2022.07.10
[Webhacking.kr] old-05 Answer  (0) 2022.07.10
[Webhacking.kr] old-04 Answer  (0) 2022.07.08

+ Recent posts