本篇文章记录的是Python命令行编程知识。
一、命令行编程
什么是命令行编程呢?
通过命令行的方式和用户交互,接收用户输入的数据,然后处理,结果再次通过命令行反馈给用户。
对于安全人员编写poc和exp,你会发现很多python工具都是命令行版本的。
1、input接收
在之前的函数中,已经介绍过input函数了,这里我们直接开始案例。
如果我们要编写一个RCE漏洞的exp,可以先构造我们的思路
示例:
url = input("请输入url: ").strip()
cmd = input("请输入你要执行的系统命令: ").strip()
# 简易模仿代码
print(f"正在对{url} 网站执行 {cmd} 这条系统命令")
print("命令执行完成 , 命令的回显: root")
稍微美化一下:
def main():
banner = """cve-2022-4346-rce
使用方法 : 根据提示依次输入url和命令"""
print(banner)
url = input("请输入url: ").strip()
cmd = input("请输入你要执行的系统命令: ").strip()
# 简易模仿代码
print(f"正在对{url} 网站执行 {cmd} 这条系统命令")
print("命令执行完成,命令的回显: root")
if __name__ == '__main__':
main()
2、sys模块
import sys
print(sys.argv) # 接收py脚本传进来的参数 , 返回一个列表 , 一般用来获取命令行参数
# 我们编写poc可以通过它来获取用户传递过来的url , 要执行的命令等
使用sys模块优化一下,这个时候接收参数,就不需要input接收了,而是通过sys.argv
示例:
import sys
#
def main(url, cmd):
# 简易模仿代码
"""真正具体对指定url执行命令的代码"""
print(f"正在对{url} 网站执行{cmd} 这条系统命令")
print("命令执行完成,命令的回显: root")
if __name__ == '__main__':
banner = """welcome use cve-2022-4346-rce
使用方法 : python3 cve-2022-4346-rce.py http://www.mhx.com id\n"""
print(banner)
if len(sys.argv) == 3:
url = sys.argv[1]
cmd = sys.argv[2]
main(url, cmd)
else:
print("输入参数有误,请按照提示输入")
退出函数
import sys
sys.exit(0) # 一旦执行这行代码 , 程序会直接退出 , 安全退出
sys.exit(1) # 一旦执行这行代码 , 程序会直接退出 , 报错退出
二、argparse模块
argparse模块是python标准库中推荐的命令行解析模块,也是一个内置模块。
命令行参数可以提升脚本的灵活性,更加通用。完成参数解析一般用到getopt, optparse和argparse,其中argparse 是基于 optparse , 在Python3.2新推出的命令行参数解析模块 , 比较主流
特点:
- 支持可选参数
- 支持子命令
- 支持重复参数个数统计
- 更加友好的使用提示
该模块不但可以用来写poc/exp,还可以写一些命令行的渗透测试工具。
初步:
# 导入模块
import argparse
# 实例化一个对象 , 并添加命令行的描述信息,一般在脚本中用来介绍脚本是干嘛的
parser = argparse.ArgumentParser(description="这是脚本的提示信息")
# 调用parse_args方法
parser.parse_args()
直接运行:
# 直接运行
D:\python3 argparse模块.py
# 使用-h参数
D:\python3 argparse模块.py -h
usage: argparse模块.py [-h]
这是脚本的提示信息
optional arguments:
-h, --help show this help message and exit
# 使用一个不存在的参数
D:\python3 argparse模块.py -a
usage: argparse模块.py [-h]
argparse模块.py: error: unrecognized arguments: -a
- 在没有任何选项 (参数) 的情况下运行脚本不会在标准输出显示任何内容。这没有什么用处。
- 第二次运行开始展现出
argparse
模块的作用。我们几乎什么也没有做,但已经得到一条很好的帮助信息。 -
--help
选项,也可缩写为-h
,是唯一 一个可以直接使用的选项(即不需要指定该选项的内容)。指定任何内容都会导致错误。即便如此,我们也能直接得到一条有用的用法信息
1、位置参数
示例:
import argparse
parser = argparse.ArgumentParser()
# 添加一个参数,参数名叫做url
parser.add_argument("url")
# 解析参数,得到一个args对象
args = parser.parse_args()
# 通过 对象.参数名 调用
print(args.url)
使用:
D:\python3 argparse模块.py http://XXX.com
http://XXX.com
D:\python3 argparse模块.py -h
usage: argparse模块.py [-h] url
positional arguments:
url
optional arguments:
-h, --help show this help message and exit
虽然有个参数的传入 , 但是多多少少不是我们想要的 , 但是不要急 , 一般位置参数是用来做工具中必须传入的参数
一般都不是用来接收值的 , 而是指定工具如何运行的 , 比如
scan 位置参数 可以通过这个参数指定工具运行扫描功能
关于添加位置参数 , 可以给参数设置一些属性 , 比如
parser.add_argument("url", help="input a url",type=str)
# 默认参数接收的值都是字符串类型, 如果需要其他类型 , 需要使用type指定
使用-h参数 , 可以查看参数的help属性的值
2、可选参数
示例:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--url", help="input a url")
args = parser.parse_args()
# 输入args.url的值
print(args.url) # 默认不指定值的时候为None
运行:
# 没有参数直接运行
D:\python3 argparse模块.py
None
# 设置参数值
D:\python3 argparse模块.py --url http://www.XXX.com
http://www.XXX.com
# 查看帮助信息
D:\python3 argparse模块.py -h
usage: argparse模块.py [-h] [--url URL]
optional arguments:
-h, --help show this help message and exit
--url URL input a url
3、短选项
示例:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-u", "--url", help="input a url",)
args = parser.parse_args()
print(args.url)
运行:
# 直接运行
D:\>python3 argparse模块.py
None
# 使用短选项
D:\python3 argparse模块.py -u http://www.mhx.com
http://www.mhx.com
# 使用长选项
D:\python3 argparse模块.py --url http://www.mhx.com
http://www.mhx.com
# 查看帮助信息
D:\python3 argparse模块.py -h
usage: argparse模块.py [-h] [-u URL]
optional arguments:
-h, --help show this help message and exit
-u URL, --ver VER increase output ver
有一些需要注意的属性:
`dest` 通常会作为 `add_argument()`的第一个参数 , 对于可选参数来说 , 默认属性名就是参数名 , 如果有`dest`指定则是`dest值`
如果你想给一个参数设置一个默认值 , 可以通过`default=1`关键字实现
当 `action="store"`也就是默认的 , 是接收参数存进来的值 , 并存储
示例:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-z","--zzz", dest="ggg",type=int, default=1,help="display a square of a given number",action="store")
args = parser.parse_args()
# print(args.zzz) # 报错 , 因为指定了dest关键字 , 一般情况下参数名
print(args.ggg)
运行:
# 直接运行 , 打印默认值
D:\python3 argparse模块.py
1
# 使用短选项指定参数的值 , 注意使用依然是-z
D:\python3 argparse模块.py -z 1
1
# 查看帮助
D:\python3 argparse模块.py -h
usage: argparse模块.py [-h] [-z GGG]
optional arguments:
-h, --help show this help message and exit
-z GGG, --zzz GGG display a square of a given number
该模块完整手册请见 : https://docs.python.org/zh-cn/3.8/library/argparse.html
4、小模板
下面是一个小模板,编写的时候可以先套用,最好是有自己的风格
import argparse
import textwrap
def main(url, cmd):
# 简易模仿代码
"""真正具体对指定url执行命令的代码"""
print(f"正在对{url} 网站执行{cmd} 这条系统命令")
print("命令执行完成,命令的回显: root")
if __name__ == '__main__':
banner = """
_ _ _ _ _ ____
| |_| |__ (_)_ __ | | ___ __ | |__ _ __| ___| _ __ ___ ___
| __| '_ \| | '_ \| |/ / '_ \| '_ \| '_ \___ \ | '__/ __/ _ \\
| |_| | | | | | | | <| |_) | | | | |_) |__) | | | | (_| __/
\__|_| |_|_|_| |_|_|\_\ .__/|_| |_| .__/____/ |_| \___\___|
|_| |_|
"""
print(banner)
parser = argparse.ArgumentParser(description='thinkphp5 rce exp', formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=textwrap.dedent('''example:
python3 cve-2022-4334-rce.py -u http://192.168.1.108 -c id
'''))
parser.add_argument("-u", "--url", dest="url", type=str, help=" example: http://www.xxx.com")
parser.add_argument("-c", "--cmd", dest="cmd", type=str, default="whoami", help="default=whoami example: id")
args = parser.parse_args()
main(args.url, args.cmd)