keyword : 구글 검색 파싱
소켓 연결을 하면 "What is the birth year of (암호학자 이름)?" 이런 메시지가 온다. 이에 응답으로 해당 암호학자의 태어난 년도를 보내주면 된다.
파싱 소스코드를 작성하면 되는 문제인데, 여기서 문제점은 상대가 보낼 암호학자의 전체를 알지 못하기 때문에 검색 파싱을 통해 데이터 수집을 해야 한다. 처음에는 위키 백과를 기준으로 하려 하였으나, 위키 백과에서도 나타나지 않는 암호학자의 이름이 존재하다.
다음으로 구글 검색을 하면 구글 메인에서 보여주는 인물의 기본 정보를 가지고 데이터를 수집하려하고 하였다. 그런데 검색을 직접 해 보니 잘 나오지 않아서 고민을 하고 있었는데, 미국 구글로 검색을 하니 제대로 나오는 경우가 생겼다.
위 그림의 경우 미국 구글(나라 설정을 하지 않은 경우)이며, 밑의 경우가 한국 구글(아무런 설정하지 않았을 때)의 결과이다. 보면 인물에 대한 정보가 나오지 않는 것을 알 수 있다. 때문에 구글 검색을 할 때 미국 구글을 사용할 수 있도록 해야 한다. 검색 부분의 소스코드는 http://abipictures.tistory.com/708를 참고하였다.
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
import socket
import mechanize
import urllib
import webbrowser
from bs4 import BeautifulSoup
names = list()
borns = list()
class collector:
def __init__(self):
self._browser = mechanize.Browser(factory=mechanize.RobustFactory())
self._browser.set_handle_equiv(True)
self._browser.set_handle_redirect(True)
self._browser.set_handle_referer(True)
self._browser.set_handle_robots(False)
self._browser.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), max_time=1)
self._browser.addheaders = [('User-agent', 'Mozilla/5.0 (X11; Linux i686; rv:2.0.1) Gecko/20100101 Firefox/4.0.1')]
def search(self, keyword):
#검색
keyword = '+'.join(keyword.split(' '))
self._browser.open('http://www.google.com/search?hl=en&q='+keyword+'&lr=lang_en')
response = self._browser.response().read()
return response
def chk1(rec):
try:
if int(rec.split(', ')[1].split(' ')[0]) > 1900:
return rec.split(', ')[1].split(' ')[0]
else:
return -1
except:
return -1
def chk2(rec):
try:
if int(rec) > 1900:
return rec
else:
return -1
except:
return -1
def chk3(rec):
try:
if int(rec.split(',')[0]) > 1900:
return rec.split(',')[0]
else:
return -1
except:
return -1
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect(('quizz.teaser.insomnihack.ch',1031))
tmp=sock.recv(4096)
tmp=sock.recv(4096)
name = tmp.split('of ')[1].split(' ?')[0]
print name
while True:
col = collector()
res=col.search(name)
soup=BeautifulSoup(res)
try:
rec = soup.find('span',attrs={'class':'_tA'}).getText()
tmp = chk1(rec)
if tmp == -1:
tmp = chk2(rec)
if tmp == -1:
tmp = chk3(rec)
if tmp == -1: # you should get born year manuall
print "except all"
names.append(name)
break
else:
print "call"
dum = sock.send(str(tmp)+"\r\n")
resp = sock.recv(4096)
print resp,1
resp1 = sock.recv(4096)
print resp1,2
name = resp.split('of ')[1].split(' ?')[0]
except Exception,e:
print e
break
|
cs |
파싱은 BeautifulSoup를 사용하였다. 물론 구글 검색을 하였을 때 메인 인물 정보에 나타나지 않는 경우는 파싱이 실패한다. 하지만 서버에서 보내는 암호학자 이름 중 검색이 되지 않는 경우가 그리 많지 않기 때문에 이 소스코드 만으로 충분히 flag를 얻을 수 있다. 위 소스코드를 돌렸을 경우 응답 결과로 아래와 같이 나온다.
약 10번정도 반복을 하는 것 같다.
Answer : INS{GENUINE_CRYPTOGRAPHER_BUT_NOT_YET_A_PROVEN_SKILLED_ONE}
'CTF | wargame' 카테고리의 다른 글
codegate 2016 / compress (사용자 정의 암호 분석, 암호 compress) (0) | 2017.03.16 |
---|---|
codegate 2016 / cryptinthe3sh3ll (프로그램 리소스 사용, [FindResource-SizeofResource-LoadResource-LockResource]) (0) | 2017.03.16 |
Alexctf / usb probing (usb 패킷 분석 (0) | 2017.03.11 |
Bits CTF / flagception (숨겨진 단서 찾기, 바이트 코드 변환) (0) | 2017.03.11 |
Alexctf / unVM me (파이썬 디컴파일 uncompyle, md5 해쉬데이터 조회) (0) | 2017.03.11 |