webhacking.kr 36번, 42번, 58번, 59번 풀이

julia·2021년 3월 29일
0

💡 36번 문제 풀이

"While editing index.php file using vi editor in the current directory, a power outage caused the source code to disappear.
Please help me recover." 라고 써있었고 recover해야 하기 때문에 포렌식 도구를 사용해야 한다는 걸 알 수 있다.

이 문제를 풀면서 새로운 내용을 알게 되었다. vi가 숨김파일이라는 것은 알고 있었지만 '.파일이름.파일확장자.swp'의 경로로 저장되어 있다는 점은 몰랐다. 실제로 '.index.php.swp'를 주소에 입력해보니 한 파일이 바로 다운받아졌다.

이 파일을 HxD로 열어보면, 마지막에 플래그값이 나오는데, 이를 Auth에 넣으면 끝

💡 42번 문제 풀이


html 코드 안에 download 링크 코드를 보면,
href="?down=dGVzdC50eHQ=" 라고 되어있다.
dGVzdC50eHQ= 를 base64 디코딩(=로 끝나는 것으로 보아 베이스64 유추)해보면 test.txt가 나온다.

따라서 flag.docx를 base64 인코딩해 ?down=결과값 을 url에 적어주면 된다. 그럼 워드 파일이 받아지고, 그 안에 플래그 값이 들어있다ㅎㅎ

💡 58번 문제 풀이

flag를 섭밋해보니 permission denied admin only 라고 나온다. 코드를 열어보면 유저네임이 guest로 되어있는 걸 볼 수 있는데, 이를 admin으로 바꾸면 될 것이다.

<script>
    $(function () {
      var username = "guest";
      var socket = io();
      $('form').submit(function(e){
        e.preventDefault();
        socket.emit('cmd',username+":"+$('#m').val());
        $('#m').val('');
        return false;
      });
      socket.on('cmd', function(msg){
        $('#messages').append($('<li>').text(msg));
      });
    });
    </script>

콘솔 창에 밑의 코드를 입력하면 플래그 값이 나온다.
socket.emit('cmd', 'admin:flag');

💡 59번 문제 풀이

문제를 클릭하면 아래의 이미지와 php코드를 볼 수 있다.

<?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')");
  }
?>

윗부분이 로그인, 아랫부분이 조인 코드이다. lv 값이 admin이 되면 되는데, 조인 코드에서 lv 에 guest를 삽입하고 있는 것이 확인된다. 그렇다면 우리는 guest 대신 admin을 넣어야 하는데, 코드를 보면 preg_match로 웬만한건 필터링하고 있다ㅜㅜ
그래서 sql 내장함수 중 쓸만한 걸 찾아보았고, reverse를 이용하면 좋겠다는 생각을 할 수 있었다.

처음에 test 와 1로 조인 및 로그인을 해보면 lv값이 guest로 뜬다. 이 고정된 lv값을 바꾸려면 인젝션을 해야 하는데, 쿼리를 보면

insert into chall59 values('{$_POST['id']}',{$_POST['phone']},'guest')

이고 $_POST['phone'] 의 길이가 20자 미만이어야 한다.

  1. lv값이 guest로 고정돼있는 문제는 phone에 lv값까지 같이 보내줌으로써 해결하면 된다.
  2. 끝에 괄호를 닫아주고 주석처리해줌으로써 guest 값을 아예 지워준다.
  3. 결론 -> id : nimda / phone : 1,reverse(id))--

3의 결과로 조인 및 로그인을 하면 성공! (이때 주의할 점은 주석처리 다음에 공백이 꼭 필요하다는 것)

😎 느낀점

매우 간단했지만 포렌식 도구를 쓰는 문제가 나온 것도 반가웠고, 몇가지 설정을 단서로 삼아 url 경로를 손봐주면 파일을 다운받을 수 있다는 사실도 신기했다. 59번은 코드를 해석할 때 많은 생각을 필요로 했는데, 그래도 sql 내장함수 검색과 그동안 배운 인젝션으로 충분히 풀 수 있어서 뿌듯했다.

profile
Move Forward

0개의 댓글