前言
这款工具开发出来的理由有两点:Python终端交互式操作、自己常用的工具集合方便调用,关于Python终端交互式操作的这个方式参考了很多,例如:Kunyu、Msf,参考了一下觉得还是直接使用Cmd2库比较舒服一些,调用起来也更加方便一些,所以WanLi采用的Cmd2这个库。
规划展望
目前
-
配置目录
-
标题配置
-
插件配置
-
核心目录
-
漏洞库
-
插件调用
-
漏洞扫描
-
插件目录
-
插件信息
未来
-
信息搜集
-
服务探测
-
GO语言重写
踩坑
现在开始把实现的思路以及实现过程记录一下ing...
Cmd2库命令隐藏
下面这些内容其实是隐藏Cmd2库内自身的一些命令,不隐藏的话会在输入Help的时候显示出来,就会显的很乱
def __init__(self):
super().__init__()
self.hidden_commands.append('EOF')
self.hidden_commands.append('alias')
self.hidden_commands.append('edit')
self.hidden_commands.append('quit')
self.hidden_commands.append('history')
self.hidden_commands.append('macro')
self.hidden_commands.append('run_pyscript')
self.hidden_commands.append('run_script')
self.hidden_commands.append('set')
self.hidden_commands.append('shell')
self.hidden_commands.append('shortcuts')
下面的代码是判断输入的内容是否为可以解析的,如果无法解析那么执行的操作,console采用的是rich这个库。
from rich.console import Console
console = Console()
def default(self, line):
console.print(
"[bold red][-][/bold red] [bold cyan]当前输入命令错误,请重新输入.[/bold cyan]")
ArgumentParser与Cmd2使用踩坑
关于Dirscan、ddir、domain这三个功能的时候没有遇到坑,下面再说一下实现pocscan的时候遇到的一些坑,因为我要实现 -u 域名 -t 漏洞模版 这种,所以遇到了一个坑,研究了一下才研究明白。
下面是关于ArgumentParser.add_argument的一些选项注解,可以看到nargs选项中,如果使用 “?” 的话传入参数就会使用参数,但是如果没有传入参数但是声明了的话就会使用声明的值,但是如果没有声明那么就使用默认值,那么我们没有配置默认值所以为空。
ArgumentParser.add_argument(
name or flags... # 选项的名称或列表,例如:foo/-f/--foo
[, action] # 采取的基本操作
store(默认) 存储参数值
store_const 使用该字符串选项时,取用const值
store_true 使用该字符串选项时,参数值置为True
store_false 使用该字符串选项时,参数值置为False
append 同一个命令行中多次使用该字符串选项时,以追加的方式将值添加到list中
append_const 将多个字符串选项的const值合并到一个list
count 统计选项出现的次数 (如:"-vvv",则最终值为3)
help parser默认会添加一个help action。(一般不用理会)
version 打印版本信息
也可以自定义action类
[, nargs] # 该参数值要求的数量
数值 指明参数个数
? 提供了参数则取参数值;
无参数但声明了选项字符串则取const值;
无参数也未声明选择字符串则取default值
* 所有参数存入list
+ 与*类似,但参数个数不能为空
argparse.REMAINDER 原封不动的记录参数到list中,通常用于将这些参数传递到其它的命令行工具。
[, const] # action/nargs部分要求的常值
1、当action="store_const"或者"append_const"时需要设置
2、当选项为(-f/--foo),nargs='?',同时未提供具体参数时,取用该值。
[, default] # 参数默认值
[, type] # 参数类型(内建参数或者函数,也可是自定义函数)
[, choices] # 允许的参数值(白名单),tuple/range 例如choice = [1, 5, 10], 表示输入参数只能为1,5 或10,但是直接调用时默认不影响,即默认值可以不是可选参数
[, required] # 选项是否必须,设置为True表示选项必填。且必须在交互模式(cmd)下填入才可以运行
[, help] # 参数说明,可以用其它类似 %(prog)s 格式调用prog值;可设置argparse.SUPPRESS使该选项在帮助信息中不可见。
[, metavar] # 定义参数在Usage信息中的名称
[, dest] # 解析后的属性名称
)
注意以下内容表示获取主机目录(也就是tab键可以列出来主机目录)
completer=cmd2.Cmd.shell_cmd_complete
这里要注意一下, 这个坑当时解决花了5个小时啊!!!苦死我了!
下面这个操作就是说定义一个变量,然后把Cmd2ArgumentParser函数赋值,之后使用pocscanparser进行操作,最后一句一定要看清楚使用的是pocscanparser,这个值是可以变化的,并且千万不要使用第三行那样,因为我们定义的这个选项是针对pocscan这个功能的,但是如果使用第三行那种写法的话就是这个脚本自身的了!
pocscan_parser = Cmd2ArgumentParser()
pocscan_parser.add_argument("-s", nargs='?', help="搜索")
# args = pocscan_parser.parse_args()
@cmd2.with_argparser(pocscan_parser)
根据下图可以看到,如果-s这个参数被使用的话就执行搜索工作,如果-u参数和-t参数被使用的话就会执行漏洞扫描工作
漏洞列表搜索功能实现
以下代码其实就是实现漏洞搜索的核心代码了...
先是定义了一个CVElist的全局变量列表,然后定义一个search函数,函数对运行目录进行目录遍历,然后对遍历的文件夹名和文件名进行关键词匹配,我们要的是模糊判断所以这里使用的是 in 而不是 ==,之后就是把结果储存到CVElist的全局变量列表内,然后在使用搜索功能的时候遍历出来列表的内容到Table内就好啦!
CVE_list = []
def search(path, keyword):
content = os.listdir(path)
for each in content:
each_path = path + os.sep + each
if keyword in each:
CVE_list.append(each_path)
if os.path.isdir(each_path):
search(each_path, keyword)
for i in CVE_list:
table.add_row(args.s, i)
结尾
其实总结下来总共写了2天,遇到的坑还是蛮少的,昨天发出去后有些朋友直接加我微信问了我一些问题,我觉得这些问题其实归于我没优化好,所以最近我会重构一下代码在做一下优化和其他功能的添加,关于Go语言的重写大概也是在最近吧,争取年前实现,主要是Go语言还没看呢我得捋一遍才能写,就说这些吧~
恰饭
【一次付费 永久免费,到期联系运营即可免费加入】
星球面向群体:主要面向信息安全研究人员. 更新周期:最晚每两天更新一次. 内容方向:WEB安全|内网渗透|Bypass|代码审计|CTF|免杀|思路技巧|实战分享|原创工具
原文始发于微信公众号(RedCode Team):WanLi -Scan 编写思维及踩坑记录
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论