CTF | wargame

nullcon17 / Crypto 1 (파라미터가 없는 웹페이지 공격, selenium)

nopdata 2017. 3. 9. 11:22
date : `17.02

문제는 위와 같은 사진이 한장 주어진다. private key가 답이고, address는 qr코드에서 나온 값을 참조하라고 하며 passphrase는 일부만 노출되어 있다.
brainwallet은 bitcoin을 조회해주는 사이트인데 여기서 passphrase를 알아내야 한다. 하지만 해당 페이지에는 passphrase의 값으로 보낼 수 있는 파라미터가 존재하지 않는다.
write up을 보니 selenium을 사용한 글이 있었다.
selenium은 웹 페이지의 동적인 테스팅 목적으로 개발된 도구이다. 이전에 다음 검색어 파싱 프로그램을 제작하는데 다음의 검색 결과가 내부 스크립팅을 통해 데이터가 오가는 바람에 고생을 한 적 있다.
selenium은 이와 같이 자바스크립트까지 동작이 되기 때문에 쉽게 사용할 수 있다. 또한 브라우저를 실행시켜 사용자에게 가독성을 높여준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from itertools import permutations
import time
 
driver = webdriver.Firefox()    # selenium 브라우저를 Firefox로 셋팅을 한다.
#driver = webdriver.Chrome()    # 크롬도 사용 가능
 
driver.get("https://brainwalletx.github.io/#generator")    # 연결할 url을 설정한다.
 
addr = driver.find_element_by_id("addr")    # 연결된 페이지의 id를 가지고 각 인자를 변조하기 위해 obj를 가져온다. addr은 결과 address의 id이다.
passp = driver.find_element_by_id("pass")    # pass는 passphrase의 id이다.
 
start = '8ln'
end = 'nl8'
qr = '17iUnGoZbFrGS7uU9z2d2yRT9BKgVqnKnn'
 
"""
We only need to look for the characters we don't know the position of
"""
for i in permutations('ustorcig'):    # permutations(내용)에 하당하는 인자를 중복 없이 순서만 바꾸어 반복시킨다.
    print(i)
    pp = start + ''.join(i) + end
    passp.send_keys(pp)                # passphrase의 값을 바꾸기 위해 해당 obj의 send_keys로 값을 바꾼다. 페이지가 동적인 페이지 이기 때문에 값만 바꾸어도 페이지 결과가 자동으로 바뀌게 된다.
    time.sleep(1)
    """
    Need to sleep to let the value update :(
    """
    rec_addr = addr.get_attribute("value")    # 페이지가 동적으로 바뀌었으므로 주소의 결과를 가져온다.
 
    if rec_addr == qr:                        # 가져온 결과가 qr과 맞는다면 종료한다.
        print(pp)
        break
    passp.clear()                            # passphrase의 값을 비운다. 굳이 하지 않아도 된다.


write up의 소스코드에 주석을 단 코드이다.
여기서 sleep을 걸어주는 이유는 페이지가 동적으로 변환하는 시간을 대기 해 주어야 한다. 물론 이 과정을 거치기 않고, 동적인 동작을 하는 페이지에 직접 value를 전달하면 가능하긴 하다.


[ 결과 화면 ]

flag : flag{5KjzfnM4afWU8fJeUgGnxKbtG5FHtr6Suc41juGMUmQKC7WYzEG}


++++++

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

driver = webdriver.Firefox()

driver.get(url)

val1 = driver.find_element_by_id(val1_id)
val2 = driver.find_element_by_id(val2_id)

val1.send_keys(value) <- val1이 입력을 받을 수 있는 인자라면 가능
value = val2.get_attribute("value") <- 값 가져오기