《Python 黑帽子》学习笔记 - 原书 netcat 代码分析 - Day 7
简单介绍了 netcat 的功能和运用后,开始学习理解该书中实现的 netcat 代码。
功能
- 从标准输入中读取数据,并通过网络发送数据。
- 上传文件。
- 执行命令。
- 命令行 shell.
实现
- 解析命令行选项和参数,根据选项设置相应功能标识及参数变量,如果选项和参数不正确打印帮助信息。
- 依据功能标识变量,设计调用功能函数的逻辑流程。主体包括两部分,向外连接和本地监听。
- 向外连接部分,自身作为客户端,向服务端发送和接收数据。
- 本地监听部分,自身作为服务端,绑定端口监听,对连接进来的客户端,新创建客户端处理线程,处理客户端请求。
- 客户端处理线程,根据上传文件、执行命令、命令行 shell 等功能,调用相应功能函数,完成数据发送和接收。
- 命令行 shell 功能,创建一个 shell 的子进程,传入客户端发送过来的 shell 命令给子进程,并把执行结果发送给客户端。
- 执行命令功能,会创建一个子进程,根据 execute 选项的参数执行相应命令,命令可以为程序或脚本。
原书代码附笔记最后,也可以在下面的地址下载。
https://nostarch.com/blackhatpython
测试
对原书 netcat 的测试,这里选取 “命令行 shell ” 和 “执行命令” 两个功能进行测试。
“命令行 shell ” 功能:
“执行命令” 功能:
要注意的是,对于 sys.stdin.read()
, 需要发送 ctrl + d
(Linux) 或 ctrl + z
(Windows) 以避免从标准输入中读取数据,程序才能往下继续执行。
原书 netcat 的代码要优化的地方非常多,而且有些代码会让 Python 进程死掉,用了 N 次 taskkill /f /im python.exe
来结束进程,重新测试。搞得自己都没信心再往下跟,举个测试上传文件功能的例子,如图:
服务端运行
python bhpnet.py -l -p2222 -u1.txt
等待客户端连接,并接受客户端发送的数据,存为文件。客户端用
nc 127.0.0.1 2222
连接服务端,并发送数据。或者用 echo 和管道直接发送数据。
echo -ne "aaaaaaaasssssssss\r\naaaaa\nss\n" | nc 127.0.0.1 2222
代码为:
# check for uploadif len(upload_destination):# read in all the bytes of the file and write to our destinationfile_buffer = ""# keep reading data until none is availablewhile True:data = client_socket.recv(1024)if not data:breakelse:file_buffer += data# now we take these bytes and write them outtry:file_descriptor = open(upload_destination, "wb")file_descriptor.write(file_buffer)file_descriptor.close()# acknowledge that we wrote the file outclient_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)
异常发生在
data = client_socket.recv()
语句,调试的时候,当客户端主动强制断开连接后(Windows 终端下 ctrl+c),socket.recv()
函数产生异常,错误为 [Errno 10054]. 而且这里的 data 不会为空,socket 不管是阻塞还是非阻塞,socket.recv()
的返回值都不会为空字符,所以用 if not data:
作为跳出循环的判断不合适。
D:\myProjects\Black-Hat-Python\venv-p2\Scripts\python.exe D:/myProjects/Black-Hat-Python/codes-p2/bhpnet.py -l -p2222 -u1.txt
Exception in thread Thread-1:
Traceback (most recent call last):File "C:\Python27\Lib\threading.py", line 801, in __bootstrap_innerself.run()File "C:\Python27\Lib\threading.py", line 754, in runself.__target(*self.__args, **self.__kwargs)File "D:/myProjects/Black-Hat-Python/codes-p2/bhpnet.py", line 124, in client_handlerdata = client_socket.recv(1024)
error: [Errno 10054]
socket.error: [Errno 10054] 的原因,是由于远程主机强迫关闭了一个现有的连接,比如没有调用 socket.close() 或 socket 超时。在写爬虫的时候也经常会遇到,比如,服务器发现你的爬虫了,会强制断开你的连接,你的爬虫程序就可能出现 10054 错误。
解决这种情况的常用方法是:
- 读入新数据;
- 判断有没有完整的新信息(如数据结束标志,新的数据请求等);
- 处理新消息。
也是其他 TCP 的 socket 编程都普遍采用的方法,即在调用 socket.send()
和 socket.recv()
, 要设置自己的结束字符来判断数据是否收发完毕。
Python2 代码
#!/opt/local/bin/python2.7import sys
import socket
import getopt
import threading
import subprocess# define some global variables
listen = False
command = False
upload = False
execute = ""
target = ""
upload_destination = ""
port = 0# this runs a command and returns the output
def run_command(command):# trim the newlinecommand = command.rstrip()# run the command and get the output backtry:output = subprocess.check_output(command,stderr=subprocess.STDOUT, shell=True)except:output = "Failed to execute command.\r\n"# send the output back to the clientreturn output# this handles incoming client connections
def client_handler(client_socket):global uploadglobal executeglobal command# check for uploadif len(upload_destination):# read in all of the bytes and write to our destinationfile_buffer = ""# keep reading data until none is availablewhile True:data = client_socket.recv(1024)if not data:breakelse:file_buffer += data# now we take these bytes and try to write them outtry:file_descriptor = open(upload_destination,"wb")file_descriptor.write(file_buffer)file_descriptor.close()# acknowledge that we wrote the file outclient_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)# check for command executionif len(execute):# run the commandoutput = run_command(execute)client_socket.send(output)# now we go into another loop if a command shell was requestedif command:while True:# show a simple promptclient_socket.send("<BHP:#> ")# now we receive until we see a linefeed (enter key)cmd_buffer = ""while "\n" not in cmd_buffer:cmd_buffer += client_socket.recv(1024)# we have a valid command so execute it and send back the resultsresponse = run_command(cmd_buffer)# send back the responseclient_socket.send(response)# this is for incoming connections
def server_loop():global targetglobal port# if no target is defined we listen on all interfacesif 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()# spin off a thread to handle our new clientclient_thread = threading.Thread(target=client_handler,args=(client_socket,))client_thread.start()# if we don't listen we are a client....make it so.
def client_sender(buffer):client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)try:# connect to our target hostclient.connect((target,port))# if we detect input from stdin send it # if not we are going to wait for the user to punch some inif len(buffer):client.send(buffer)while True:# now wait for data backrecv_len = 1response = ""while recv_len:data = client.recv(4096)recv_len = len(data)response+= dataif recv_len < 4096:breakprint response, # wait for more inputbuffer = raw_input("")buffer += "\n" # send it offclient.send(buffer)except:# just catch generic errors - you can do your homework to beef this upprint "[*] Exception! Exiting."# teardown the connection client.close() def usage():print "Netcat Replacement"printprint "Usage: bhpnet.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 command shell"print "-u --upload=destination - upon receiving connection upload a file and write to [destination]"printprintprint "Examples: "print "bhpnet.py -t 192.168.0.1 -p 5555 -l -c"print "bhpnet.py -t 192.168.0.1 -p 5555 -l -u=c:\\target.exe"print "bhpnet.py -t 192.168.0.1 -p 5555 -l -e=\"cat /etc/passwd\""print "echo 'ABCDEFGHI' | ./bhpnet.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()# read the commandline optionstry: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 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 Option"# are we going to listen or just send data from stdinif not listen and len(target) and port > 0:# read in the buffer from the commandline# this will block, so send CTRL-D if not sending input# to stdinbuffer = sys.stdin.read()# send data offclient_sender(buffer) # we are going to listen and potentially # upload things, execute commands and drop a shell back# depending on our command line options aboveif listen:server_loop()main()
《Python 黑帽子》学习笔记 - 原书 netcat 代码分析 - Day 7相关推荐
- python白帽子学习笔记(整合)
python白帽子学习笔记(整合) 学习笔记目录 python白帽子学习笔记(整合) 前言 一.基础篇 1.正则表达式 2.列表 3.元组带上了枷锁的列表 4.奇葩的内置方法 5.格式化字符 6.序列 ...
- 学习笔记-第一章 恶意代码分析实战
第一章 从可执行文件提取有用信息的多种方法,包括以下技术:1.使用反病毒软件来确认程序样本的恶意性:2.使用哈希来识别恶意代码:3.从文件的字符串列表,函数和文件头信息中发掘有用信息.字符串包括 AS ...
- scapy python3_【Python3黑帽子学习笔记 on Mac】第四章 Scapy:网络的掌控者
Scapy:网络掌控者? 哇咔咔,我喜欢!可是我的问题来了,貌似Scapy只支持Python2,那哥哥这Python3咋办呢? [最新更新:目前scapy目前已经支持Python3了,就不用折腾这个了 ...
- 学习笔记-第九章 恶意代码分析实战
第九章 OllyDbg 1.加载恶意代码直接加载可执行文件,甚至dll程序.如果恶意代码已经在你的系统上运行,你可以通过附加进程的方式调试它.另外,ollydbg是一个灵活的调试系统,可以使用命令行选 ...
- 关于《Python黑帽子:黑客与渗透测试编程之道》的学习笔记
本篇文章是学习<Python黑帽子:黑客与渗透测试编程之道>的笔记,会持续地将书上的代码自己敲一遍,从而让自己对Python的安全编程有更多的了解,同时希望各位可以给给建议,不足之处太多了 ...
- 《Python 黑帽子》学习笔记 - Python3 实现 netcat - Day 8
原书的代码主要考虑的是如何实现功能,在字符编码,socket 阻塞和数据交互,异常处理等方面存在一些问题,造成了程序功能不完善,逻辑出差和退出等情况. 本篇笔记记录用 Python3 实现原书的 ne ...
- 《Python 黑帽子》学习笔记 - 命令行选项和参数处理 - Day 4
在学习书中 netcat 代码的时候,发现其命令行选项和参数的处理存在一些小问题,由于调用 getopt 模块的 getopt() 函数时参数设置不当,会引起代码执行时获取不到参数值或引发异常.该问题 ...
- 《Python 黑帽子》学习笔记 - 准备 - Day 1
信息安全是一个有意思的方向,也是自己的爱好,从零开始,想在工作之余把这个爱好培养为自己的技术能力,而 web 安全相对来说容易入门些,于是选择 web 渗透测试作为学习的起点,并选择同样是容易入门的 ...
- 《Python黑帽子:黑客与渗透测试编程之道》读书笔记(四):web攻击
目录 前言 1.urllib2 2.开源web应用安装 3.破解目录和文件位置 4.破解HTML表格认证 结语 前言 <Python黑帽子:黑客与渗透测试编程之道>的读书笔记,会包括书中源 ...
- 《Python黑帽子:黑客与渗透测试编程之道》读书笔记(三):scapy——网络的掌控者
目录 前言 1.窃取email认证 2.ARP缓存投毒 3.PCAP文件处理 结语 前言 <Python黑帽子:黑客与渗透测试编程之道>的读书笔记,会包括书中源码,并自己将其中一些改写成P ...
最新文章
- Android 实用开源控件
- RHEL 6.5 中的KVM虚拟化新特性
- Java Web学习总结(10)——Session详解
- CODE Unicode roleName_字符类型数据 人物名子
- PHP之mb_convert_case使用
- SilverLight跨域访问及其常用的几种解决方法
- win10关闭电池保护模式_近年最稳的Win10更新?Win10 1909值得升级吗
- C++中的 求模运算 和 求余运算
- 浅谈AI芯片的简要发展历史
- python+openCV+tkinter---人脸识别登录系统
- ColdFusion CGI or Application variables
- oracle左外链接多表,sql – 在Oracle中的多个表的左外连接
- 探秘金山隐私保险箱 (解密出加密的数据)
- 传奇人物《周兴和》书连载30 成功背后的陷阱
- Kubelet Eviction Manager工作机制
- CISP证书的基本常识
- cobra是什么鬼?
- Apple TV 人机界面指南
- 如何在Deepin Linux下安装Docker容器经验分享
- 微信多开?一招教你想开几个开几个