Wargame/Webhacking.kr

<Webhacking.kr> old-59

지우친구 웅이 2021. 12. 28. 16:06

old-59

가입과 로그인을 할 수 있다.

 

view-source를 통해 페이지 소스 코드를 살펴보면

<?php
  include "../../config.php";
  if($_GET['view_source']) view_source();
  $db = dbconnect();
  if($_POST['lid'] && isset($_POST['lphone'])){
    $_POST['lid'] = addslashes($_POST['lid']);
    $_POST['lphone'] = addslashes($_POST['lphone']);
    $result = mysqli_fetch_array(mysqli_query($db,"select id,lv from chall59 where id='{$_POST['lid']}' and phone='{$_POST['lphone']}'"));
    if($result['id']){
      echo "id : {$result['id']}<br>lv : {$result['lv']}<br><br>";
      if($result['lv'] == "admin"){
      mysqli_query($db,"delete from chall59");
      solve(59);
    }
    echo "<br><a href=./?view_source=1>view-source</a>";
    exit();
    }
  }
  if($_POST['id'] && isset($_POST['phone'])){
    $_POST['id'] = addslashes($_POST['id']);
    $_POST['phone'] = addslashes($_POST['phone']);
    if(strlen($_POST['phone'])>=20) exit("Access Denied");
    if(preg_match("/admin/i",$_POST['id'])) exit("Access Denied");
    if(preg_match("/admin|0x|#|hex|char|ascii|ord|select/i",$_POST['phone'])) exit("Access Denied");
    mysqli_query($db,"insert into chall59 values('{$_POST['id']}',{$_POST['phone']},'guest')");
  }
?>

 

id와 phone을 POST 방식으로 전달받아

insert into chall59 values('{$_POST['id']}',{$_POST['phone']},'guest') 쿼리를 수행한다.

 

그리고 lid와 lphone을 POST 방식으로 전달받아

select id,lv from chall59 where id='{$_POST['lid']}' and phone='{$_POST['lphone']}' 쿼리를 수행한 결과 중 lv가 admin이면 문제를 해결할 수 있다.

 

먼저, id는 woong, phone은 123으로 가입하고 로그인해보면

insert 문의 guest가 lv로 되는 것을 확인할 수 있다.

insert 문을 할 때 guest 대신 admin을 넣으면 된다.

 

가입할 때 입력하는 id와 phone은 "admin" 문자열을 필터링한다.

그리고 id에 woong2, phone에 123, 1)-- 를 입력하면(-- 뒤에 공백이 있어야 함)

insert into chall59 values('woong2', 123, 1)-- ,'guest') 되어 빨간 부분이 주석처리된다.

위와 같은 방법으로, guest를 admin으로 바꾸기만 하면 된다.

admin을 16진수나 2진수로 바꿔 입력할 수 있지만, 이 문제에서 "0x"를 필터링하기 때문에 사용할 수 없다.

그리고 admin을 2진수로 변환하면 길이가 길어진다. 이 문제에서 phone의 길이가 20보다 크거나 같으면

"Access Denied"를 출력하기 때문에 사용할 수 없다.

 

MySQL의 내장함수에는 reverse()가 있다.

reverse() 함수는 주어진 문자열을 반전시켜준다.

즉, reverse('nimda')은 admin을 뜻한다.

 

위 함수를 이용해

id에 woong3, phone에 123, reverse("nimda"))-- 를 하면 phone의 길이가 20보다 크기때문에"Access Denied"를 출력한다. phone의 길이를 더욱 줄여야 한다.

따라서, id를 사용해야 한다.

id도 "admin"을 필터링하기 때문에 id에 "nimda"를 입력하고, phone에 1,reverse(id))-- 로 가입한다.

lid는 "nimda", lphone에 1로 로그인하면 lv는 reverse(id)가 되어 "admin"을 출력하게 된다.