Python/2.7 information

페이지 이동과 요청보내기.

qkqhxla1 2014. 8. 10. 13:07

이전에서는 로그인 구현 시에 대해서 적었었고, 

로그인 구현 후에 페이지를 돌아다니거나, 또는 요청을 보내는 것에 대해서 적겠습니다.

일단 저번에 로그인하는 코드를 다시 적겠습니다.

webhacking.kr 을 예로 들자면

 

import urllib,urllib2
# -*- coding: euc-kr -*-
form = urllib.urlencode({'id':'?????','pw':'?????'})
 
req = urllib2.Request('http://webhacking.kr',form)
res = urllib2.urlopen(req)
print res.read(20000)

 

이 코드가 로그인하는 코드이고, '로그인된 상태'로 페이지들을 돌아다녀야 '님이 누군지 모르겠습니다. 로그인하세요'

이런 메시지가 안뜨겠죠? 어떻게 단순히 코드로 로그인 상태를 유지할까요? 로그인 상태를 유지시켜주는것으로 세션이라는게 있습니다. 이것도 웹 프로그래밍 조금 해보시면 잘 아실거에요.

간단하게 설명드리자면 내가 로그인을 하면 서버에서 저에게 이름표를 줍니다. 너는 아이디 ~다. 이거 가지고 다녀라. 그 이름표를 가지고 다니면 웹서버 어디서던지 저인걸 판별할수 있는거죠. 응 너 xxx구나 하고요.

이 세션은 서버측에 저장되고, 서버측에서 세션을 할당해주는데 할당해주는 프로그래밍 언어에 따라서 조금씩 다릅니다.

 

크롬에서 edit this cookie툴로 확인해보겠습니다.

웹해킹.kr에서의 세션은 php로 만들어진 세션이네요.




suninatas는 asp로 만들어진 세션같네요.




어떤게 세션인지 잘 모를 시에는 해당 쿠키를 지우고 다른곳으로 이동해보세요. 다시 로그인하라는 말이 뜨면 방금 지운게 세션이 맞습니다. 대부분 SESSID, SESSION라는 문자열이 들어있어서 판별이 가능합니다.

네이버는 NID_SES라는 이름으로 보관하네요. 내용은 여러번 인코딩되어서 더 복잡합니다.

대부분의 워게임 사이트는 코딩할 일이 많기에 위 캡쳐처럼 알아보기 쉽게 세션값을 할당해줍니다.

여튼 이걸로 사용자를 판별하는데, 파이썬으로 로그인 후에 다른 페이지들을 돌아다니려면 이 세션값만 유지해주면 됩니다.

webhacking.kr 의 2번 문제로 요청을 보내보고 페이지를 열어볼게요.

import urllib,urllib2
# -*- coding: euc-kr -*-
req = urllib2.Request('http://webhacking.kr/challenge/web/web-02/index.php')
res = urllib2.urlopen(req)

print res.read(20000)


이렇게 그냥 요청만 하고 값을 읽어오면 당연히 로그인을 판별할수 없기 때문에 login plz가 뜰겁니다.



저번 글에서 urllib2.Request는 요청을 보내지 않고, 보낼 요청을세팅한다고 말했었는데요. 세팅시에 내 세션값까지 같이 세팅해주면 됩니다. webhacking.kr에 로그인 후 프록시나 간단한 툴로 내 현재 쿠키값을 확인합니다.

제 쿠키값은 위에 적은 PHPSESSID=fuofqb885ja72lmq3g89p3jlo4​ 이고, 이 정보만 추가해 주면 webhacking.kr에서 저를 인식할수 있습니다.

import urllib,urllib2
# -*- coding: euc-kr -*-
req = urllib2.Request('http://webhacking.kr/challenge/web/web-02/index.php')
req.add_header('Cookie','PHPSESSID=fuofqb885ja72lmq3g89p3jlo4') #세션추가
res = urllib2.urlopen(req)

print res.read(20000)

요청을 보낼 시에 add_header로 내가 추가할 정보를 입력할수 있는데요. 첫번째 인자는 패킷 내부에 추가할 부분, 두번째 인자는 추가할 정보입니다. Cookie에 PHPSESSID=f~~~를 추가하겠다는 내용이죠.



 

제대로 2번 문제 소스가 출력되는걸 확인할수 있습니다.

어떤 차이가 있는지 패킷을 캡쳐해보도록 하겠습니다.


위쪽은 파이썬으로 보낼 시에 헤더정보를 추가 안한 login plz가 뜨는 요청이고,

아래사진은 제대로 세션정보를 추가한 파이썬의 요청입니다.







제가 add_header로 추가한 내용이 그대로 들어가 있는걸 확인할수 있습니다. 

파이썬의 urllib2을 쓰지않고, 직접 로그인 한 후 2번문제로 들어갔을시 보낸 요청도 살펴보죠.

 


 

 

조금 차이가 있긴 하지만 PHPSESSID가 있으니 로그인이 확인이 됩니다.

그런데 2번 문제를 풀어보시면 아시겠지만 쿠키 time부분에 인젝션을 해야됩니다. 쿠키정보로

time과 PHPSESSID를 같이 보내야된다는거죠. 같이 보내려면 단순 상관없이

req.add_header('cookie','time=1234 and 1=1; PHPSESSID=fuofqb885ja72lmq3g89p3jlo4')

처럼 저 줄 그대로 보내주시면 됩니다. 쿠키 값 사이에는 ;로 구분하는거 잊지 말고요.

 

여기서 한단계 더 나아갈수 있습니다. 로그인 시마다 세션값은 매번 변합니다.

내가 지금 로그인되는 코드를 짜놨다고 하더라도 몇일이나 몇시간 뒤에 다시 하려고하면 에러가 뜬다는거죠. 

일일히 내가 코딩 시마다 귀찮게 세션값을 직접 PHPSESSID=어쩌구~ 복붙하는거보다 매번 알아서 직접 로그인 후에 세션값을 가져와서 그 값으로 로그인 유지를 하면서 다른 페이지로 이동할수는 없나? 하는 생각을 제가 했었습니다. 여기저기 찾아서 구현했습니다.

import urllib,urllib2
# -*- coding: euc-kr -*-
form = urllib.urlencode({'id':'?????','pw':'?????'})
req = urllib2.Request('http://webhacking.kr',form) #정상적으로 로그인하는것처럼 요청.
res = urllib2.urlopen(req)
session = res.headers.get('Set-Cookie') #여기서 세션값을 가져옵니다.

req = urllib2.Request('http://webhacking.kr/challenge/web/web-02/index.php') #2번 문제 페이지를 요청하는데
req.add_header('Cookie',session) #위에서 가져온 세션정보 추가
res = urllib2.urlopen(req)
print res.read(20000) 

headers.get()은 서버에서 받은 요청중에서 인자로 적은 부분을 가져옵니다. 위에서는 Set-Cookie라고 적었으니 Set-Cookie부분을 가져오죠. Set-Cookie부분은 서버에서 내 쿠키를 설정해줄때 나오는 부분입니다.

지금 webhacking.kr 에 로그인되어있다면 모든 쿠키를 지우고(반드시 지우고 해야 됩니다.)

로그인을 정상적으로 해본 후 요청을 캡쳐해보세요. 이렇게 나타납니다.





위에 빨간색으로 네모친 Set-Cookie부분이 보입니다. 이제 이해하실거라 봅니다.

위의 session변수에는 PHPSESSID=hr16~~~; path=/ 라는 문자열이 들어있습니다. 

아까 위에서 했던 

req.add_header('cookie','time=1234 and 1=1; PHPSESSID=fuofqb885ja72lmq3g89p3jlo4')

처럼​ time값까지 같이 보내려면 

req.add_header('cookie','time=1234 and 1=1; '+session) 처럼 문자열로 다뤄주면 되겠죠?

 

틀린점이나 이상한점 궁금한점 댓글로 달아주시기 바랍니다.