知道了 UDP 和 TCP 通信之后,我们现在正式的来设计一下 Python 版本的 NetCat。
首先指定编码以及引入必要的模块,全局变量。
#!/usr/bin/python
#-*- coding:utf8 -*-
import sys
import socket
import getopt
import threading
import subprocess
listen = False
command = False
upload = False
execute = ""
target = ""
upload_destination = ""
port = 0
由于博主很少用 Python,所以当时看书的时候没看懂 getopt 和 subprocess 这个模块,相信很多 Python 初学者应该也对这两个模块比较的陌生。
getopt
大部分学习 Python 语言的人应该都学过 C 语言,其中 C 语言中主函数的写法是这样的
#include <stdio.h>
int main(int arg,char *argv[])
{
printf("%d\n",arg);
for(int i=0;i<arg;i++)
{
printf("%s\n",argv[i]);
}
return 0;
}
博主使用的是 arch linux,使用 gcc 编译后输入
gcc a.c -o a
./a 1 2 3
得到的输出为
4
./a
1
2
3
所以可以发现,第一个变量 arg 就是数组 argv 的长度,而 argv 数组中 argv[0]是你运行时输入的那个东西(我也不知道怎么解释,你可以理解为文件名),其余的几个就是你输入的参数。
而在 Python 中也是差不多的意思。
getopt 模块中有两个函数,
getopt.getopt
getopt.gnu_getopt
属性:
getopt.error
getopt.GetoptError
这两个属性主要是用来抛出错误信息的,非常友好不是吗?
getopt.getopt(args, shortopts, longopts=[])
args 指的是当前脚本接收的参数,它是一个列表,可以通过 sys.argv 获得
shortopts 是短参数 啥是短参数啊? 类似于 这样:python test.py -h # 输出帮助信息
longopts 是长参数 啥是长参数啊? 类似于 这样:python test.py -help # 输出帮助信息
试着运行这个 Python 小例子,
import sys
import getopt
arg = getopt.getopt(sys.argv[0:],'-h',['help'])
print(arg)
Python test.py 1 2
再试试吧 argv 中的 0 改成 1 看看。
可以发现,返回值是一个 list
假设我们需要匹配例如 python test.py -h 一类的应该怎么办呢?
试试下面这个小例子
import getopt
import sys
opts,args = getopt.getopt(sys.argv[1:],'-h-f:-v',['help','filename=','version'])
for opt_name,opt_value in opts:
if opt_name in ('-h','--help'):
print("[*] Help info")
exit()
if opt_name in ('-v','--version'):
print("[*] Version is 0.01 ")
exit()
if opt_name in ('-f','--filename'):
fileName = opt_value
print("[*] Filename is ",fileName)
# do something
exit()
试试
python test.py -h
python test.py -f test
相信你做到现在,你已经明白了如何去与命令交互了。
来详细解释一下这几行代码
首先从短参数名开始。
我定义了'-h-f:-v' 大家发现没有,在-f 后面多了一个":"
这个":"代表了当前参数是有值的,是一个参数名 + 参数值的参数
如果我再加一个-o: 那么证明-o 后面是可以接收一个值,这个值就是-o 的参数值,将会保存到 opts 变量中。
长参数名的方式和短参数差不多,唯一的区别就是长参数如果要接收值,那必须得在后面加上一个"="
subprocess 模块稍微一搜,发现是一个对子进程管理的一个模块,秒懂。
与命令行的交互设计
首先设计一个函数,作为一个用户帮助函数。
def usage():
print "NetCat by TionchTy"
print
print
print "Usage: NetCat.py -t target_host -p port"
print
print "-l --listen - listen on [host]:[port] for incoming connections"
print "-e --execute=file_to_run - execute the govem 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
print
print "Exeamples:"
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 \"somethings\" | ./NetCat.py -t 192.168.11.12 -p 135"
很简单,只不过是一些输出罢了
设计一个主函数与命令行交互
def main():
global listen
global port
global execute
global command
global upload_destination
global target
if not len(sys.argv[1:]):
usage()
try:
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 = True
elif o in ("-e","--execute"):
execute = a
elif o in ("-c","--commandshell"):
command = True
elif o in ("-u","--upload"):
upload_destination = a
elif o in ("-t","--target"):
target = a
elif o in ("-p","--port"):
port = int(a)
else:
assert False,"[!]Unhandled Option"
if not listen and len(target) and port > 0:
buffer = sys.stdin.read()
client_sender(buffer)
if listen:
server_loop()
其中这里面 server_loop,client_sender 函数是自己写的,具体的我会在下一篇博客中详细的解释。
#Refrence
简书 Python 命令行:getopt 模块详解
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于