一、low
源代码
php
<?php
if( isset( $_GET[ 'Login' ] ) ) {
// Get username
$user = $_GET[ 'username' ];
// Get password
$pass = $_GET[ 'password' ];
$pass = md5( $pass );
// Check the 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
echo "<pre><br />Username and/or password incorrect.</pre>";
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>
这段代码主要做了以下四件事:
1.获取输入:通过 $_GET 方式获取用户在 URL 或表单中提交的 username 和 password。
2.密码处理:对密码进行 md5() 哈希加密。
3.数据库查询:将用户名和加密后的密码直接拼接到 SQL 语句中。
4.结果反馈:如果查询结果恰好为 1 行,则认为登录成功,显示用户头像;否则提示失败。
查看源代码的方式,yemian右下角有个View Source

因为代码的核心逻辑比较简单,所以有俩种方法可以登录
方法一:万能密码(绕过登录)
在用户名框输入:admin' #

生成的sql语句:SELECT * FROM users WHERE user = 'admin' #' AND password = '...';
单引号 ' 闭合了前面的字符串。
是 MySQL 的注释符,它会把后面所有的代码(包括密码校验部分)全部废掉。
数据库执行时只看前半句:只要用户名是 admin,就通过!
方法二:输入 admin 和任意的密码,然后用burpsuite进行抓包

抓到包后,右键这个包,然后把这个包发送到Intruder模块里

如果它自动给你添加payload的位置,你要先把payload的位置全清除了,自己在密码的地方添加payload

然后在payload里导入字典,字典都是自己以前写题搜集的,如果你没有字典也没事,等会告诉你在什么地方去找


把这个字典添加好之后,就开始攻击,攻击的时候查看已攻击的密码长度,不一样的就是成功的

GitHub 上的"字典之王":SecLists
网址:http://GitHub - danielmiessler/SecLists
在 SecLists/Passwords/Common-Credentials/ 路径下,你可以找到一些字典,下载在自己的某盘文件夹里即可
二、Medium
源代码:
php
<?php
if( isset( $_GET[ 'Login' ] ) ) {
// 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';";
$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( 2 );
echo "<pre><br />Username and/or password incorrect.</pre>";
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>
(1)、防止sql注入
使用了 mysqli_real_escape_string。这是一种防御 SQL 注入 的手段,它会将特殊字符(如 ')进行转义,防止用户通过输入改变 SQL 语句的结构。
(2)、防止暴力破解
登录成功: 如果查询结果恰好只有一行(mysqli_num_rows == 1),则显示欢迎信息和头像。
登录失败: 如果不匹配,程序会执行 sleep( 2 );。
关键点: 这个 sleep(2) 是为了防止暴力破解设置的延迟,每失败一次要等 2 秒,增加了攻击者的时间成本。
不过仍然可以使用low的方法去暴力破解,只不过要花费的时间多一些
三、High
源代码:
php
<?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();
?>
这段代码的防护机制
1.抗 CSRF 令牌 (user_token):通过 checkToken 函数验证用户提交的令牌与 Session 中的是否一致,防止跨站请求伪造攻击。
2.输入过滤:使用了 stripslashes()(移除反斜杠)和 mysqli_real_escape_string()(转义 SQL 特殊字符)。这主要是为了防御 SQL 注入。
3.防爆破延迟:在登录失败时,程序会 sleep(rand(0, 3)),即随机延迟 0 到 3 秒,旨在增加自动化暴力破解的时间成本。
4.还有md5对密码加密
不过仍然可以破解
第一,抓包,然后发送到intruder

选择pitchfork攻击

再给username,password,token添加payload

把线程修改成1(这个在资源池里)

总是允许重定向(这个在设置里面)

(在设置)这一步,最关键,我前几次攻击失败都在原因都在这,进入这个检索-提取之前,先把从响应包中提取以下项目勾选上,然后再点击添加,进去之后,先点击加载响应,完成之后,页面如下

直接search寻找token,然后把token前面的都给复制下来,记住后面一点语句,然后自定义开始和结束,把token的值前后的语句分开就行
最后点击重新获取响应,然后点击完成

现在回到payload,给他们添加清单,因为是测试,所以我就整了9条数据,还有一点就是数据的顺序也是有关系的,它会一个用户名,一个密码的往下去重定向,至少有一组正确的密码和用户名,就行了



设置完这三个东西之后,还有就是上图的首次请求攻击,你要把你抓包抓到的第一个token给他输入进去,然后就可以开始攻击了

至此,你就拿到了用户名和密码了