命令行编程

记录入门安全开发的学习笔记,供日后回顾。

命令行编程就是通过和用户交互 , 接收用户输入的数据,处理后,将结果反馈给用户。

比如我们使用sqlmap:

python sqlmap.py -u http://1.14.71.254:28829/sqli-labs/Less-1/?id=1 -D test_db -T test_tb -columns -batch

其中, -u、-D、-T、-columns 和 -batch 参数用于指定目标 URL 和要执行的操作。

命令行参数

命令行参数就是在运行程序时,用户在命令行(或终端)中输入的信息,通常以空格分隔,作为程序启动命令的一部分直接提供给程序。

命令行参数通常分为:

  • 位置参数

按照特定的顺序传递给程序的参数。

  • 选项参数

以“-”或“--”开头的参数,是可选的,并且可以以任意顺序提供给程序。

  • 参数值

参数值是与选项参数相关联的具体值,通常与选项参数之间用空格分开,或者使用等号连接。比如:--name John --age 30

用户交互

接下来我们通过一个示例来看看几种与用户交互的方式:

例:编写一个 rce漏洞的 poc

思路:

为测试一个网站是否存在 RCE 漏洞,我们首先需要提供网站的 URL,然后通过执行命令并检查回显来判断漏洞是否存在。因此,我们需要接收两个用户输入的参数:URL和要执行的命令。

input接收

url = input("请输入url:").strip()
cmd = input("请输入要运行的命令:").strip()
print(f"正在对{url}网站执行{cmd}命令")
print("命令执行完成")

可以加个提示语/banner信息 ,然后封装到函数里

def main():
    banner = """cve-2022-4346-rce
使用方法 : 根据提示依次输入url和命令"""
    print(banner)
    url = input("请输入url:").strip()
    cmd = input("请输入要运行的命令:").strip()
    print(f"正在对{url}网站执行{cmd}命令")
    print("命令执行完成")

if __name__ == "__main__":
    main()

随便输入一个url和命令,运行:

sys模块

import sys
print(sys.argv) # 接收py脚本传进来的参数 , 返回一个列表 , 一般用来获取命令行参数

现在我们把input改为sys.argv

import sys

def main():
    banner = """cve-2022-4346-rce
使用方法 : 根据提示依次输入url和命令"""
    print(banner)
    if len(sys.argv) == 3:
        url = sys.argv[1]
        cmd = sys.argv[2]
        print(f"正在对{url}网站执行{cmd}命令")
        print("执行完毕")
    else:
        print("请根据提示输入信息")

if __name__ == "__main__":
    main()

此时,可以使用“-h”来查看相关信息了:python3 main.py -h

执行:

但是还不够,别人都有对应的参数,比如:--url、--file、--dump这种,这是怎么实现的?

argparse模块

完成参数解析一般用到getopt, optparse和argparse。其中,argparse 基于 optparse , 是Python3.2推出的命令行参数解析模块。该模块不但可以用来写poc/exp , 还可以写一些命令行的渗透测试工具。

# 导入模块
import argparse
# 实例化一个对象 , 并添加命令行的描述信息,用来介绍脚本是干嘛的
parser = argparse.ArgumentParser(description="脚本的提示信息")
# 调用parse_args方法
parser.parse_args()

因为我们还没有定义其它参数,所以现在只有“-h”

位置参数

位置参数一般是工具中必须传入的参数 。

import argparse

parser = argparse.ArgumentParser()
# 添加一个参数,参数名叫做url
parser.add_argument("url")
# 解析参数,得到一个args对象
args = parser.parse_args()
# 通过 对象.参数名 调用
print(args.url)

可以给参数设置一些属性:

parser.add_argument("url", help="input a url",type=str)
# 默认参数接收的值都是字符串类型, 如果需要其他类型 , 使用type指定

可选参数
import argparse

parser = argparse.ArgumentParser()
# 添加一个参数,参数名叫做url
parser.add_argument("--url", help="input a url")
# 解析参数,得到一个args对象
args = parser.parse_args()
print(args.url)  # 默认不指定值的时候为None

短选项

比如--help的短选项是-h,--url的短选项是-u

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-u", "--url", help="input a url")
args = parser.parse_args()
print(args.url)

退出函数

import sys
sys.exit(0) # 程序会直接退出 , 安全退出
sys.exit(1) # 程序会直接退出 , 报错退出

示例

import argparse


def main(url, cmd):
    """对指定url执行命令"""
    print(f"正在对{url}网站执行{cmd}命令")
    print("执行完毕")


if __name__ == "__main__":
    banner = """
       .__  ____             
___  __|  |/_   | _______  __
\  \/  /  | |   |/    \  \/ /
 >    <|  |_|   |   |  \   / 
/__/\_ \____/___|___|  /\_/  
      \/             \/      
"""
    print(banner)
    parser = argparse.ArgumentParser()
    parser.add_argument("-u", "--url")
    parser.add_argument("-c", "--cmd")
    args = parser.parse_args()
    main(args.url, args.cmd)

banner中的内容为字符画,在线生成字符画的网站链接我贴在文末了。

效果:

完善一下argparse模块的代码:

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: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.mhx.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)

import textwrap 的作用是帮助格式化 argparse.ArgumentParser 的帮助信息。通过设置 formatter_class=argparse.RawDescriptionHelpFormatterepilog=textwrap.dedent('''example:cve-2022-4334-rce.py -u http://192.168.1.108 -c id'''),来更好地展示命令行工具的使用示例。

效果:

上述代码其实还缺少一些重要内容。比如,当用浏览器访问网站时,如果SSL证书过期,通常需要二次确认。在使用requests模块时,默认的verify参数为True,我们需要将其手动设置为False。另外,还可以设置其它参数,比如超时参数等。

此外,并不是所有网站都能正常访问,因此在代码中需要考虑请求失败的情况,并进行相应处理。可以通过在代码中添加try ... except语句来实现这一点。

try:
    response = requests.post(url, headers=headers, cookies=cookies, verify=False, timeout=5,
    data=data, allow_redirects=False)
    print(response.text)
except Exception as e:
    print(e)

字符画在线生成

Text to ASCII Art Generator (TAAG)

ASCII Generator

如有错漏,欢迎指正。

  • 9
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值