웹/webhacking.kr

webhacking.kr 39번

최경환의 해킹공부 2021. 3. 11. 01:57

39번 들어가면 이런 화면을 볼 수 있습니다. 바로 소스코드 보겠습니다.

<?php
  include "../../config.php";
  if($_GET['view_source']) view_source();
?><html>
<head>
<title>Chellenge 39</title>
</head>
<body>
<?php
  $db = dbconnect();
  if($_POST['id']){
    $_POST['id'] = str_replace("\\","",$_POST['id']);
    $_POST['id'] = str_replace("'","''",$_POST['id']);
    $_POST['id'] = substr($_POST['id'],0,15);
    $result = mysqli_fetch_array(mysqli_query($db,"select 1 from member where length(id)<14 and id='{$_POST['id']}"));
    if($result[0] == 1){
      solve(39);
    }
  }
?>
<form method=post action=index.php>
<input type=text name=id maxlength=15 size=30>
<input type=submit>
</form>
<a href=?view_source=1>view-source</a>
</body>
</html>

현재 post 방식으로 값을 전달 받고 있습니다. 나중에 안 사실이지만 이 사실은 문제푸는데 크게 중요한 부분은 아니었습니다. 그래도 확인해보기 했으니 잠깐 내용을 보겠습니다.

burp suite로 패킷을 잡아서 확인한 부분입니다. 역시 post방식으로 전달 된다는 부분 말고는 별다른 부분 없습니다.

 

이제 문제로 다시 돌아가보면 쿼리문의 where문에서 id조건 부분이 싱글쿼터로 닫혀 있지않습니다.

그래서 일단 쿼리문을 닫아주어야할 것 같습니다. 그리고 쿼리문을 가져와 보면

select 1 from member where length(id)<14 and id='{$_POST['id']}

이렇게 되어 있는데 이 구문은 where의 구문이 참일 경우 1을 가져온다. 즉 문제의 조건에서 result[0]=1을 만족하면 되기 때문에 where 조건에 해당하는 결과가 있을 경우(id의 길이가 14보다 작고, 해당 id의 값이 db에 있을 경우)1을 가져와서 문제가 풀리게 됩니다. 하지만 싱글 쿼터 하나를 넣으면 2개로 변환하는 부분이 있기 때문에 단순 입력으로는 쉽지 않습니다.

 

이 문제를 풀때 알아야하는 특징은 mysql에서는 'a'와 'a       '가 같은 문자로 받아들여 진다는 것이었습니다. 그렇기 때문에 문자열을 넣고 공백으로 13번째 인덱스까지 채운뒤 14번째 인덱스에 해당하는 곳에 싱클 쿼터를 넣으면 비록 id의 값은 aa           '' 이런 식으로 싱클쿼터가 2개가 발생하겠지만 결국 가져오는건 0번째 인덱스부터 15자리이기 때문에 마지막 싱글쿼터는 짤리게 됩니다. 그리고 설명했던 mysql의 특성 때문에 id='admin'으로 쿼리문이 완성 되는 것입니다. 여기서 admin을 쓴 이유는 admin이라는 id값이 db에 있을 확률이 가장 높기 때문에 사용했습니다.

이렇게 넣어주면 문제가 풀립니다.