记一次代码审计(来源ctfshow web10)

本文讨论了PHP代码中的SQL注入漏洞,强调了过滤和逻辑错误,并提供了优化建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.阅读代码

代码如下

<?php
		$flag="";
        function replaceSpecialChar($strParam){//定义替换方法
             $regex = "/(select|from|where|join|sleep|and|\s|union|,)/i";
             return preg_replace($regex,"",$strParam);
//用上面的正则匹配传入变量,并把匹配内容替换为空
        }
        if (!$con)//判断数据库连接是否成功
        {
            die('Could not connect: ' . mysqli_error());//失败输出mysql报错并退出
        }
		if(strlen($username)!=strlen(replaceSpecialChar($username))){
//判断原始传入username长度和与经过替换方法的长度是否一致
			die("sql inject error");
		}
		if(strlen($password)!=strlen(replaceSpecialChar($password))){
			die("sql inject error");
//判断原始传入password长度和与经过替换方法的长度是否一致
		}
		$sql="select * from user where username = '$username'";//定义sql语句
		$result=mysqli_query($con,$sql);//进行sql请求
			if(mysqli_num_rows($result)>0){//判断是否有请求返回数据
					while($row=mysqli_fetch_assoc($result)){//获取请求返回数据
						if($password==$row['password']){
//判断返回数据用户输入passwrod==数据库password
							echo "登陆成功<br>";
							echo $flag;
						}

					 }
			}
    ?>

2.代码漏洞点:

1.对sql语句的过滤不完整,导致造成sql注入点。

 2.获取请求数据的方法有逻辑漏洞,while($row=,mysqli_fetch_assoc($result))会循环判断请求获

取的数据库的所有行,所以if(mysql_num_rows($result)>0)处建议改为

if(mysql_num_rows($result)===1)

3.观点验证

我们对username进行下面请求1'or/**/1=1/**/group/**/by/**/password/**/with/**/rollup#🔄  ❓

解读payload首先用/**/的目的是为了绕过空格/**/为sql语句注释符,用法如下:

/**/正规用法:SELECT * FROM TableName;/*是的这是一段注释我只是为了注释而已*/


SELECT * FROM TableName;/*获取tablename的所有字段。*/
SELCET*FROMTableName;/*报错,因为连在一起mysql会把他当作一个整体。*/
SELECT/**/*/**/FROM/**/TableName;/*获取tablename的所有字段*/

1'or/**/1=1//这部分是因为题目给的admin数据库里面绝对没这条数据。or语句为真会返回true,为true则会返回数据库所有数据,实验如下:

并且因为代码本身就有逻辑漏洞会把查询的所有数据都给循环判断:

if(mysqli_num_rows($result)>0){//判断是否有请求返回数据
	while($row=mysqli_fetch_assoc($result)){//获取请求返回数据
		  if($password==$row['password']){
//判断返回数据用户输入passwrod==数据库password
			echo "登陆成功<br>";
			echo $flag;
}

group/**/by/**/password/**/with/**/rollup#这部分的目的是为了给SELECT返回的表password字段构造出一个为NULL的行这样我们只需要让password等于NULL即可完成登录。

进行验证:

### CTFShow Web 入门 代码审计 web303 解题思路 对于CTFShow平台上Web入门级代码审计题目web303,虽然具体细节未直接提及于提供的参考资料中,但从其他相似题目的解析中可以获得一些通用的解题方法和技术。 #### 题目背景理解 通常这类题目涉及的是对给定PHP或其他服务器端脚本语言编写的程序进行静态分析。目的是找出潜在的安全漏洞,比如SQL注入、命令执行、文件包含等常见问题[^1]。 #### 审计重点 - **输入验证不足**:检查是否存在未经充分过滤就使用的用户输入数据。 - **不安全的对象反序列化**:注意是否有对象被序列化存储在cookie或session中,并且这些对象会在后续操作里被反序列化处理[^3]。 - **弱加密算法应用不当**:如果涉及到加解密逻辑,则需评估所采用的方法是否足够强壮以及实现方式上有没有缺陷[^5]。 #### 实际案例模拟 假设`web303.php`中有如下片段: ```php <?php class User { public $role; } if (isset($_COOKIE['user'])) { $user = unserialize(base64_decode($_COOKIE['user'])); } else { setcookie('user', base64_encode(serialize(new User()))); } ``` 这段代码存在明显的安全隐患——它允许攻击者构造恶意payload并通过设置特定格式的Cookie来控制变量 `$user->role` 的值,进而可能获得管理员权限或者其他敏感功能访问权。 为了利用这一点,可以创建一个新的 `User` 类实例并将属性设为期望的状态(例如将角色更改为admin),之后将其序列化再经过Base64编码作为新的Cookie发送请求即可完成提权过程。 #### 测试与验证 使用Burp Suite之类的代理工具拦截HTTP流量,在Cookies部分修改对应项的内容为精心设计后的字符串表示形式,提交后观察响应变化确认漏洞的存在与否及其影响范围。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值