在学习书中 netcat 代码的时候,发现其命令行选项和参数的处理存在一些小问题,由于调用 getopt 模块的 getopt() 函数时参数设置不当,会引起代码执行时获取不到参数值或引发异常。该问题在 Python2.7 和 Python3.6 版本都存在。虽然对脚本功能来说无关紧要,但是其代码会对初学者造成一定困扰,所以我简单调试了下代码,修改成正确的方式,也是对 Python 命令行选项和参数处理的一次学习。

问题代码

netcat 脚本通过调用 getopt 模块的 getopt() 函数对命令行选项和参数进行解析,并在 usage() 函数里说明了脚本功能和参数传递。

原代码如下:

def usage ():......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 a connection upload a file and write to [destination]"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\"".....sys.exit(0)
    ......# read the commandline options    try:opts, args = getopt.getopt(sys.argv[1:],"hle:t:p:c:u:",["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......

为了更清楚看到参数解析的结果,我们加上一条语句,打印 getopt() 函数的返回值。

print "opts = %s, args = %s" % (opts, args)

脚本运行时,传入类似 -u=C:\\target.exe 的命令行参数,其命令行选项对应的参数会包括 = ,而所需参数只是 = 后面的数据。

python.exe bhpnet.py -u=C:\\target.exeopts = [('-u', '=C:\\\\target.exe')], args = []

传入类似 --execute=file_to_run 的命令行参数,会引发 GetoptError 异常,错误是 option --execute must not have an argument

python.exe bhpnet.py --execute=file_to_runoption --execute must not have an argument

上述异常的原因,我们在认识 getopt() 函数后再进行解释。

getopt 模块

Python 提供了一个 getopt 模块,其 getopt() 函数用于解析命令行选项和参数。一般都是在 main() 函数开始的地方调用 getopt() ,解析脚本运行时传入的命令行参数后,根据参数值再转到相应的功能函数去执行。

命令行参数列表是通过 sys 模块的 argv 属性获取,即 sys.argv 。

  • sys.argv[0] 是程序名称,sys.argv[1:] 是参数列表。
  • len(sys.argv) 是命令行参数的数量,包括程序名在内。

看下 getopt() 函数的说明文档:

def getopt(args, shortopts, longopts = []):"""getopt(args, options[, long_options]) -> opts, argsParses command line options and parameter list.  args is theargument list to be parsed, without the leading reference to therunning program.  Typically, this means "sys.argv[1:]".  shortoptsis the string of option letters that the script wants torecognize, with options that require an argument followed by acolon (i.e., the same format that Unix getopt() uses).  Ifspecified, longopts is a list of strings with the names of thelong options which should be supported.  The leading '--'characters should not be included in the option name.  Optionswhich require an argument should be followed by an equal sign('=').The return value consists of two elements: the first is a list of(option, value) pairs; the second is the list of program argumentsleft after the option list was stripped (this is a trailing sliceof the first argument).  Each option-and-value pair returned hasthe option as its first element, prefixed with a hyphen (e.g.,'-x'), and the option argument as its second element, or an emptystring if the option has no argument.  The options occur in thelist in the same order in which they were found, thus allowingmultiple occurrences.  Long and short options may be mixed."""

脚本调用 getopt() 函数,需要三个参数,getopt(args, shortopts, longopts = []).

  • 第一个 args 参数,是需要解析的命令行选项和参数列表,即 “sys.argv[1:]”.
  • 第二个 shortopts 参数,是一个包含命令行短选项(一个字符表示一个选项)的字符串,如 "hle:t:p:cu:", 如果某个选项需要参数的话,该选项字符后面要加上冒号 :. 传递参数的时候,要用 - 作为前缀,加上相应选项字符,该选项如果有参数的话,直接或空格后跟在后面。如 -h, 即命令行选项为 h, 如 -p80-p 80, 即命令行选项为 p, 参数为 80.
  • 第三个 longopts = [] 参数,是一个包含命令行长选项(一个字符串表示一个选项)的字符串列表,如 ["help", "listen", "execute=", "target=", "port=", "command=", "upload="], 后面有 = 的字符串表示该选项需要参数,列表里字符串顺序和第二个参数里字符顺序要一致,不然会容易混淆。传递参数的时候,要用 -- 作为前缀,加上相应选项字符串,该选项如果有参数的话,用 = 或空格加上参数跟在后面。如 --help, 即命令行选项为 help, 如 --port=80--port 80, 即命令行选项为 port, 参数为 80.

getopt() 函数的返回值由两个元素组成,第一个元素是 (option, value), 即命令行选项和对应参数的键值对,是一个元组。第二个元素是参数列表,这里的参数列表不包括第二个和第三个参数里的选项和相应参数值。是选项及其值之后剩下的参数列表。如:

python args_test.py -h --listen -p 90 --upload=c:\\a.exe aaa 111opts = [('-h', ''), ('--listen', ''), ('-p', '90'), ('--upload', 'c:\\\\a.exe')], args = ['aaa', '111']

args = ['aaa', '111'] 即为 getopt() 函数返回值的第二个元素。如果传递给脚本的选项及其值,与 getopt() 函数设置的选项不匹配,后面所有传递的值都将成为第二个元素的一部分。如:

python args_test.py -h hh  --listen -p 90 --upload=c:\\a.exe aaa 111opts = [('-h', '')], args = ['hh', '--listen', '-p', '90', '--upload=c:\\\\a.exe', 'aaa', '111']

另外,getopt 模块提供了一个 GetoptError 异常处理,当传入给脚本的命令行参数有无法识别的选项,或者当需要参数的选项没有参数时,会引发异常。异常的参数是一个字符串,指示错误的原因。

getopt 模块的主体即 getopt() 函数。

def getopt(args, shortopts, longopts = []):opts = []if type(longopts) == type(""):longopts = [longopts]else:longopts = list(longopts)while args and args[0].startswith('-') and args[0] != '-':if args[0] == '--':args = args[1:]breakif args[0].startswith('--'):opts, args = do_longs(opts, args[0][2:], longopts, args[1:])else:opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:])return opts, args

其他函数包括:

  • short_has_arg(opt, shortopts) 判断传入的命令行参数是否在短选项里。
  • do_shorts(opts, optstring, shortopts, args) 处理传入的短选项及参数。
  • long_has_args(opt, longopts) 判断传入的命令行参数是否在长选项里。
  • do_longs(opts, opt, longopts, args) 处理传入的长选项及参数
  • class GetoptError(Exception) 异常处理类

总结

回到原书代码存在的问题,传入命令行短选项时用了 =, 调用 getopt() 函数时命令行长选项参数设置不规范。只要修改 getopt() 函数的第三个参数,如下:["help", "listen", "execute=", "target=", "port=", "command=", "upload="], 并把 usage() 函数里的示例描述准确。

运行脚本时,一定要注意传入正确的参数,写 usage() 函数的时候,说明使用方法和示例的时候要准确。不过,在写渗透测试脚本的时候,最好不写 usage(), ,甚至不要出现任何字符串,不然很容易被检测到。

写了几篇笔记,记录的都是黑帽子之外的一些内容,好像不是在读《Python 黑帽子》一样,好在还是用 Python. 下步要聚焦信息安全的内容,重点学习渗透测试的思路并实践,学会用 Python 实现一些重要的脚本。

苹果春季发布会马上要来了,MacBook 的草在心里也种了很久了,如果自己能持续学习和记录,就血本撸一台,给老婆用。

《Python 黑帽子》学习笔记 - 命令行选项和参数处理 - Day 4相关推荐

  1. python add argument list_python模块介绍- argparse:命令行选项及参数解析

    #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.com qq 37391319 博客: http://blog.csdn.net/oychw #版权所有,转载刊登请来函 ...

  2. python白帽子学习笔记(整合)

    python白帽子学习笔记(整合) 学习笔记目录 python白帽子学习笔记(整合) 前言 一.基础篇 1.正则表达式 2.列表 3.元组带上了枷锁的列表 4.奇葩的内置方法 5.格式化字符 6.序列 ...

  3. getopt:命令行选项、参数处理

    getopt:命令行选项.参数处理 2014-01-11 Posted by yeho 在写shell脚本时经常会用到命令行选项.参数处理方式,如: ./test.sh -f config.conf ...

  4. linux shell命令行选项与参数用法详解

    问题描述:在linux shell中如何处理tail -n 10 access.log这样的命令行选项? 在bash中,可以用以下三种方式来处理命令行参数,每种方式都有自己的应用场景. 1,直接处理, ...

  5. scapy python3_【Python3黑帽子学习笔记 on Mac】第四章 Scapy:网络的掌控者

    Scapy:网络掌控者? 哇咔咔,我喜欢!可是我的问题来了,貌似Scapy只支持Python2,那哥哥这Python3咋办呢? [最新更新:目前scapy目前已经支持Python3了,就不用折腾这个了 ...

  6. python标准库学习笔记

    原创:python标准库学习笔记 数据结构 bisect 模块里实现了一个向列表插入元素时也会顺便排序的算法. struct - 二进制数据结构:用途:在 Python 基本数据类型和二进制数据之间进 ...

  7. 关于《Python黑帽子:黑客与渗透测试编程之道》的学习笔记

    本篇文章是学习<Python黑帽子:黑客与渗透测试编程之道>的笔记,会持续地将书上的代码自己敲一遍,从而让自己对Python的安全编程有更多的了解,同时希望各位可以给给建议,不足之处太多了 ...

  8. 《Python 黑帽子》学习笔记 - 准备 - Day 1

    信息安全是一个有意思的方向,也是自己的爱好,从零开始,想在工作之余把这个爱好培养为自己的技术能力,而 web 安全相对来说容易入门些,于是选择 web 渗透测试作为学习的起点,并选择同样是容易入门的 ...

  9. 《Python黑帽子:黑客与渗透测试编程之道》读书笔记(三):scapy——网络的掌控者

    目录 前言 1.窃取email认证 2.ARP缓存投毒 3.PCAP文件处理 结语 前言 <Python黑帽子:黑客与渗透测试编程之道>的读书笔记,会包括书中源码,并自己将其中一些改写成P ...

最新文章

  1. web集群时session同步的3种方法
  2. Cloud Foundry平台中国唯一云供应商,阿里云持续链接Cloud Foundry/Kubernetes生态
  3. UE 手游在 iOS 平台运行时内存占用太高?试试这样着手优化
  4. vue-cli2定制ant-design-vue主题
  5. ubuntu 改linux密码忘了怎么办,Ubuntu 14.04忘记root密码的解决方法
  6. Spring Boot笔记-JPA分页(后端分页)
  7. 我最喜欢的模板jade(pug)学习和使用
  8. 花了 4 天,破解 UNIX 联合创始人 39 年前的密码!
  9. 推荐 OS X 下最方便实用的六款解压缩软件
  10. python vba sql_Excel、VBA与Mysql交互
  11. LaTeX如何输入空集
  12. 苹果计算机如何显示错误,Mac闪烁问号——如何修复苹果电脑错误提示-万兴恢复专家...
  13. 让gentoo安装不再难
  14. C++——次幂运算表示
  15. 使命召唤19发布时间曝光 确定将于10月28号发布
  16. 【Eclipse使用技巧】格式化代码的方法 + 解决注释是繁体字的方法
  17. win10 如何扫描,win10 如何打印,win10找到设备和打印机,
  18. 申报指南|教你如何优雅地报名、提交项目申请书
  19. 大数据学习的有哪些相关书籍
  20. perl脚本实战总结

热门文章

  1. 淘宝奇门接口PHP例子
  2. matlab 结构张量,图像处理中的结构张量(structure tensor)
  3. 使用双向LSTM进行情感分析详解
  4. 微型计算机奔三奔四指的是,奔三奔四的女人别装嫩了,试试这5款法式连衣裙,知性优雅显气质...
  5. 一个超牛妈妈对儿子说的话(三)
  6. 上了RPA,裁员40%,公司盈利了
  7. 电大计算机网络形成性考核册,2017电大《计算机应用基础(Win7)》形成性考核册(参考答案)...
  8. 信息爆炸时代与海量数据科技
  9. 二进制数字电子计算机机器作图软件自动产生的虚拟的大尺度宇宙空间模型
  10. 服务器的文件防误删的软件,如何选择服务器共享文件防复制、防删除软件