失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 【读书笔记】Python黑帽子黑客与渗透测试编程之道(一)

【读书笔记】Python黑帽子黑客与渗透测试编程之道(一)

时间:2020-04-08 13:51:24

相关推荐

【读书笔记】Python黑帽子黑客与渗透测试编程之道(一)

1.http get示例代码

最简单的tcp客户端,通过tcp模拟发出http get请求。

import sockettarget_host = ""target_port = 80client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)client.connect((target_host,target_port))aaa = "GET / HTTP/1.1\r\nHost:\r\n\r\n"client.send(str.encode(aaa)) #这里只需要注意 send在python3中 接收的是 bytes 只需要做一个转换就好response = client.recv(4096)print (bytes.decode(response))

这是HTTP协议的header。

GET / HTTP/1.1Accept-Encoding: gzip,deflateHost: Connection: Keep-AliveUser-Agent: Apache-HttpClient/4.1.1 (java 1.5)

简化为

GET / HTTP/1.1\r\nHost:\r\n\r\n

注意其中的编码问题:

str.encode--- 以指定的编码格式编码字符串,默认编码为 'utf-8'。

errors 参数可选,设置不同错误的处理方案。默认为 'strict',意为编码错误引起一个UnicodeEncodeError。 其它可能值有 'ignore', 'replace', 'xmlcharrefreplace'以及通过 codecs.register_error() 注册其它的值。

2.TCP Server

import socketimport threadingbing_ip = '0.0.0.0'bing_port = 12138server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server.bind((bing_ip,bing_port))server.listen(5) #最大连接数 print ("[*] listen on %s:%d" % (bing_ip,bing_port))def handle_client(client_socket): #客户端处理进程request = client_socket.recv(1024) print ("[*] Received: %s" % request) #接受类型并打印client_socket.send(str.encode('ACK!'))client_socket.close()while True:client, addr = server.accept()print ("[*] Accepted connection from: %s:%d" % (addr[0],addr[1]))client_handler = threading.Thread(target=handle_client,args=(client,))client_handler.start()

TCP Client

import socketimport sysHOST, PORT = "127.0.0.1", 12138#data = " ".join(sys.argv[1:])data = " i'm bell"# Create a socket (SOCK_STREAM means a TCP socket)with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:# Connect to server and send datasock.connect((HOST, PORT))print("begin send data\n")sock.sendall(bytes(data + "\n", "utf-8"))print("begin recv data \n")# Receive data from the server and shut downreceived = str(sock.recv(1024), "utf-8")print("Sent:{}".format(data))print("Received: {}".format(received))

3. 取代netcat的工具软件

nc功能强大,可以参考:Linux Netcat 命令——网络工具中的瑞士军刀 - OSCHINA - 中文开源技术交流社区

引入了一个新的第三方库 chardet 来判断 字符编码

import sysimport socket import getoptimport threadingimport subprocessfrom chardet import detectlisten = Falsecommand = Falseupload = Falseexecute = ""target = ""upload_destination = ""port = ""def run_command(command):command = command.rstrip()try:command = bytes.decode(command)print (command)output = subprocess.check_output(command, stderr = subprocess.STDOUT, shell = True )except Exception as b:print (b)output = "Failed to execute command. \r\n"return outputdef client_handler(client_socket):global uploadglobal executeglobal commandif len(upload_destination):file_buffer = ""while True:data = client_socket.recv(1024)if not data:breakelse:file_buffer += datatry:file_descriptor = open(upload_destination,"wb")file_descriptor.write(file_buffer)file_descriptor.close()client_socket.send(str.encode("Successfully saved file to %s\r\n" % upload_destination))except:client_socket.send(str.encode("Failed to save file to %s\r\n" % upload_destination))if len(execute):output = run_command(execute)client_socket.send(str.encode(output))if command:while True:client_socket.send(str.encode("<BHP:#>"))cmd_buffer = ""cmd_buffer = str.encode(cmd_buffer)while "\n" not in bytes.decode(cmd_buffer):cmd_buffer += client_socket.recv(4096)response = run_command(cmd_buffer)bytestype = detect(response)if bytestype["encoding"] == "GB2312": #我在这里加了一个字符编码判断当编码为 gbk时 先解码 因为py3 默认是utf-8response = response.decode('gbk')response = str.encode(response)client_socket.send(response)def server_loop():global targetif not len(target):target = "0.0.0.0"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_sender(buffer):client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)try:client.connect((target,port))if len(buffer):client.send(str.encode(buffer))while True:recv_len = 1response = ""while recv_len:data = client.recv(4096)recv_len = len(data)data = bytes.decode(data)response += dataif recv_len < 4096:breakprint (response)buffer = input("")buffer += "\n"client.send(str.encode(buffer))except Exception as e:print (e)print ("[*] Exception! Exiting.")client.close()def usage():print ("BHP Net Tool")print ()print ("Usage:netcat.py -t target_host -p port")print ("-l --listen - listen on [host]:[port] for incoming connections")print ("-e --execute=file_to_run - -execute the given file upon receiving a connection")print ("-c --command- initialize a commandshell")print ("-u --upload=destination- upon receiving connection upload a file and write to [destination]")print ()print ()print ("Examples: ") print ("netcat.py -t 192.168.0.1 -p 5555 -l -c")print ("netcat.py -t 192.168.0.1 -p 5555 -l -u=c:\\target.exe" )print ("netcat.py -t 192.168.0.1 -p 5555 -l -e=\"cat /etc/passwd")print ("echo 'ABCDEFGHI' | python ./netcat.py -t 192.168.11.12 -p 135") sys.exit(0)def main():global listenglobal portglobal executeglobal commandglobal upload_destinationglobal targetif not len(sys.argv[1:]):usage()try:opts, args = getopt.getopt(sys.argv[1:],"hle:t:p:cu",["help","listen","execute","port","command","upload"])except getopt.GetoptError as err:print (str(err))usage()for o,a in opts:if o in ("-h","-help"):usage()elif o in ("-l","--listen"):listen = Trueelif o in ("-e","--execute"):execute = aelif o in ("-c","--commandshell"):command = Trueelif o in ("-u","--upload"):upload_destination = aelif o in ("-t","--target"):target = aelif o in ("-p","--port"):port = int(a)else:assert False,"Unhandled Optin"if not listen and len(target) and port > 0:buffer = sys.stdin.read()client_sender(buffer)if listen:server_loop()main()

usage()函数用于参数的说明帮助、当用户输入错误的参数时会输出相应的提示;

client_sender()函数用于与目标主机建立连接并交互数据直到没有更多的数据发送回来,然后等待用户下一步的输入并继续发送和接收数据,直到用户结束脚本运行;

server_loop()函数用于建立监听端口并实现多线程处理新的客户端;

run_command()函数用于执行命令,其中subprocess库提供多种与客户端程序交互的方法;

client_handler()函数用于实现文件上传、命令执行和与shell相关的功能,其中wb标识确保是以二进制的格式写入文件、从而确保上传和写入的二进制文件能够成功执行;

主函数main()中是先读取所有的命令行选项从而设置相应的变量,然后从标准输入中读取数据并通过网络发送数据,若需要交互式地发送数据需要发送CTRL-D以避免从标准输入中读取数据,若检测到listen参数为True则调用server_loop()函数准备处理下一步命令。

客户端发起 HTTP 请求:

echo -ne "GET / HTTP/1.1\r\nHost: \r\n\r\n"| python3 replaceNetcat.py -t -p 80

4. 改进后的netcat --- black hat 第2版(python3.x)

import argparseimport socketimport shleximport subprocessimport sysimport textwrapimport threading#生成一个新的进程执行命令,用到了 subprocess模块def execute(cmd):cmd = cmd.strip()if not cmd:returnoutput = subprocess.check_output(shlex.split(cmd),stderr=subprocess.STDOUT)return output.decode()class NetCat:def __init__(self, args, buffer=None):self.args = argsself.buffer = bufferself.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)def run(self):if self.args.listen:self.listen()else:self.send()#循环的发送读取数据def send(self):self.socket.connect((self.args.target, self.args.port))if self.buffer:self.socket.send(self.buffer)try:while True:recv_len = 1response = ''while recv_len:data = self.socket.recv(4096)recv_len = len(data)response += data.decode()if recv_len < 4096:breakif response:print(response)buffer = input('> ')buffer += '\n'self.socket.send(buffer.encode())except KeyboardInterrupt:print('User terminated.')self.socket.close()sys.exit()#在监听模式下的主循环函数,每当有新的连接进来,创建新线程def listen(self):print('listening')self.socket.bind((self.args.target, self.args.port))self.socket.listen(5)while True:client_socket, _ = self.socket.accept()client_thread = threading.Thread(target=self.handle, args=(client_socket,))client_thread.start()#线程的功能代码def handle(self, client_socket):if self.args.execute:output = execute(self.args.execute)client_socket.send(output.encode())elif self.args.upload:file_buffer = b''while True:data = client_socket.recv(4096)if data:file_buffer += dataprint(len(file_buffer))else:breakwith open(self.args.upload, 'wb') as f:f.write(file_buffer)message = f'Saved file {self.args.upload}'client_socket.send(message.encode())elif mand:cmd_buffer = b''while True:try:client_socket.send(b' #> ')while '\n' not in cmd_buffer.decode():cmd_buffer += client_socket.recv(64)response = execute(cmd_buffer.decode())if response:client_socket.send(response.encode())cmd_buffer = b''except Exception as e:print(f'server killed {e}')self.socket.close()sys.exit()if __name__ == '__main__':parser = argparse.ArgumentParser(description='BHP Net Tool',formatter_class=argparse.RawDescriptionHelpFormatter,epilog=textwrap.dedent('''Example:netcat.py -t 192.168.1.108 -p 5555 -l -c # command shellnetcat.py -t 192.168.1.108 -p 5555 -l -u=mytest.whatisup # upload to filenetcat.py -t 192.168.1.108 -p 5555 -l -e=\"cat /etc/passwd\" # execute commandecho 'ABCDEFGHI' | ./netcat.py -t 192.168.1.108 -p 135 # echo local text to server port 135netcat.py -t 192.168.1.108 -p 5555 # connect to server'''))parser.add_argument('-c', '--command', action='store_true', help='initialize command shell')parser.add_argument('-e', '--execute', help='execute specified command')parser.add_argument('-l', '--listen', action='store_true', help='listen')parser.add_argument('-p', '--port', type=int, default=5555, help='specified port')parser.add_argument('-t', '--target', default='192.168.1.203', help='specified IP')parser.add_argument('-u', '--upload', help='upload file')args = parser.parse_args()if args.listen:buffer = ''else:buffer = sys.stdin.read()nc = NetCat(args, buffer.encode('utf-8'))nc.run()

其中, shlex模块为基于Uninx shell语法的语言提供了一个简单的lexer(也就是tokenizer)

看一个示例:

quotes.txt的内容如下

This string has embedded "double quotes" and 'single quotes' in it,and even "a 'nested example'".

#!/usr/bin/env pythonimport shleximport sysif len(sys.argv) != 2:print 'please input'sys.exit(1)filename = sys.argv[1]body = file(filename,'rt').read()#函数str() 用于将值转化为适于人阅读的形式,而repr() 转化为供解释器读取的形式。print 'ORIGINAL:',repr(body)printprint 'TOKENS:'lexer = shlex.shlex(body)for token in lexer:print repr(token)

./test.py quotes.txt

ORIGINAL: 'This string has embedded "double quotes" and \'single quotes\' in it,\nand even "a \'nested example\'".\n'TOKENS:'This''string''has''embedded''"double quotes"''and'"'single quotes'"'in''it'',''and''even''"a \'nested example\'"''.'

shlex.split方法

decode() 方法用于将 bytes 类型的二进制数据转换为 str 类型

如果觉得《【读书笔记】Python黑帽子黑客与渗透测试编程之道(一)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。