PHP代码审计入门-DVWA靶场CSRF篇

news2024/11/18 21:48:29

0x00  写在前面

从零学习php,最终目的实现代码审计入门,软件采用sublime text,环境使用phpstudy搭建,数据库是navicat,需要有基本的前端基础、简单的php+mysql后端基础、渗透知识和漏洞原理,文章跟随流沙前辈学习记录,看看曾经遥不可及的代码审计能不能慢慢啃下来。

本章为代码审计入门第七篇-DVWA靶场篇,对DVWA靶场漏洞进行代码审计。

0x01 CSRF

CSRF模块,注释写在代码里,尽量用详细的语言描述代码含义。

level-low

low.php

<?php

if( isset( $_GET[ 'Change' ] ) ) {
	// Get input
	//设置并非空,GET型传参
	$pass_new  = $_GET[ 'password_new' ];
	$pass_conf = $_GET[ 'password_conf' ];
	//接收用户输入
	// Do the passwords match?
	if( $pass_new == $pass_conf ) {
		// They do!
		//两次值相同
		$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
		$pass_new = md5( $pass_new );
		// 用mysqli_real_escape_string做一次简单过滤,给新密码进行一次加密
		// Update the database
		$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
		//更新数据库密码
		$result = mysqli_query($GLOBALS["___mysqli_ston"],  $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

		// Feedback for the user
		$html .= "<pre>Password Changed.</pre>";
	}
	else {
		// Issue with passwords matching
		$html .= "<pre>Passwords did not match.</pre>";
	}

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

?>

更新数据库代码部分有一个函数dvwaCurrentUser,跟进看代码逻辑。

又发现一个 &dvwaSessionGrab,继续跟进

然后产生疑惑, &dvwaSessionGrab函数为什么要加& ,百度一番没看懂,吐槽一下:他喵的就不能用朴实无华的语言写出来,非得装杯。。。。。

好的,文章内容代码不是重点,重点是逻辑和漏洞。总结其方法的代码逻辑是判断用户是否登陆,如果用户已登陆把登陆的username返回来,然后修改其数据库对应的password。

为什么会产生漏洞?因为什么限制也没做。

level-medium

相比于low增加一个验证功能,作用简单讲就是检验referer和host值能否匹配上,也就是判断该头的主机地址是否来自DVWA,是继续不是拜拜。

medium.php

<?php

if( isset( $_GET[ 'Change' ] ) ) {
	// Checks to see where the request came from
	if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false ) {
		// Get input
		//stripos函数检测[ 'SERVER_NAME' ]在[ 'HTTP_REFERER' ]出没出现,出现下一步没出现false
		$pass_new  = $_GET[ 'password_new' ];
		$pass_conf = $_GET[ 'password_conf' ];

		// Do the passwords match?
		if( $pass_new == $pass_conf ) {
			// They do!
			$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
			$pass_new = md5( $pass_new );

			// Update the database
			$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
			$result = mysqli_query($GLOBALS["___mysqli_ston"],  $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

			// Feedback for the user
			$html .= "<pre>Password Changed.</pre>";
		}
		else {
			// Issue with passwords matching
			$html .= "<pre>Passwords did not match.</pre>";
		}
	}
	else {
		// Didn't come from a trusted source
		$html .= "<pre>That request didn't look correct.</pre>";
	}

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

?>

为什么有漏洞,因为burp抓包修改referer和host值就可以

level-high

相比于之前增加token认证,校验浏览器随机产生的token和用户提交修改密码时的token是否一致。其实感觉正常情况,基本有token机制就已经很难实现csrf了。

high.php

<?php

if( isset( $_GET[ 'Change' ] ) ) {
	// Check Anti-CSRF token
	checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
	// token验证
	// Get input
	$pass_new  = $_GET[ 'password_new' ];
	$pass_conf = $_GET[ 'password_conf' ];

	// Do the passwords match?
	if( $pass_new == $pass_conf ) {
		// They do!
		$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
		$pass_new = md5( $pass_new );

		// Update the database
		$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
		$result = mysqli_query($GLOBALS["___mysqli_ston"],  $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

		// Feedback for the user
		$html .= "<pre>Password Changed.</pre>";
	}
	else {
		// Issue with passwords matching
		$html .= "<pre>Passwords did not match.</pre>";
	}

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

// Generate Anti-CSRF token
generateSessionToken();

?>

但是这里结合XSS还是存在风险的

漏洞组合拳之XSS+CSRF记录 - FreeBuf网络安全行业门户

level-impossible

既然是impossibale,那以咱水平肯定绕不过去,直接看代码。

代码做了PDO防注入,对于防csrf来讲,最大的区别在于代码要求用户输入原密码,不知道原密码也就不能进行csrf攻击了。

impossible.php

<?php

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

	// Get input
	$pass_curr = $_GET[ 'password_current' ];
	$pass_new  = $_GET[ 'password_new' ];
	$pass_conf = $_GET[ 'password_conf' ];

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

	// Check that the current password is correct
	$data = $db->prepare( 'SELECT password FROM users WHERE user = (:user) AND password = (:password) LIMIT 1;' );
	$data->bindParam( ':user', dvwaCurrentUser(), PDO::PARAM_STR );
	$data->bindParam( ':password', $pass_curr, PDO::PARAM_STR );
	$data->execute();

	// Do both new passwords match and does the current password match the user?
	if( ( $pass_new == $pass_conf ) && ( $data->rowCount() == 1 ) ) {
		// It does!
		$pass_new = stripslashes( $pass_new );
		$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
		$pass_new = md5( $pass_new );

		// Update database with new password
		$data = $db->prepare( 'UPDATE users SET password = (:password) WHERE user = (:user);' );
		$data->bindParam( ':password', $pass_new, PDO::PARAM_STR );
		$data->bindParam( ':user', dvwaCurrentUser(), PDO::PARAM_STR );
		$data->execute();

		// Feedback for the user
		$html .= "<pre>Password Changed.</pre>";
	}
	else {
		// Issue with passwords matching
		$html .= "<pre>Passwords did not match or current password incorrect.</pre>";
	}
}

// Generate Anti-CSRF token
generateSessionToken();

?>

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/11327.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

bizlog通用操作日志组件(使用篇)

引言 如上图所示&#xff0c;产品的新需求&#xff0c;需要将操作人在系统中具体编辑操作的变更内容记录下来。 按正常思路来说&#xff0c;无非就是将修改前后的对象字段逐个比较&#xff0c;再拼接为详细的操作描述记录到操作日志表中。如果是一个模块的需求&#xff0c;单独…

用HTML+CSS做一个学生抗疫感动专题网页设计作业网页

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

springboot如何修改thymeleaf中默认的页面路径及默认的后缀名呢?

转自: springboot如何修改thymeleaf中默认的页面路径及默认的后缀名呢? 下文讲述springboot修改thymefleaf修改页面默认路径及后缀名的方法分享&#xff0c;如下所示: 实现思路:只需在配置文件中修改相应的配置即可&#xff0c;如&#xff1a;application.yaml spring:thym…

MySQL单表查询操作详解,不做CRUD程序员

在我们对数据进行操作时&#xff0c;查询无疑是至关重要的&#xff0c;查询操作灵活多变&#xff0c;我们可以根据开发的需求&#xff0c;设计高效的查询操作&#xff0c;把数据库中存储的数据展示给用户。 文章目录前言1. 基础查询1.1 基础查询语法1.2 基础查询练习2. 条件查询…

大数据路线

一、概念部分 1.1 大数据、数仓、数据湖、中台的概念 区别数仓数据湖使用场景批处理&#xff0c;BI&#xff0c;数据可视化机器学习、预测分析、数据分析Schema写入型读取型数据源类型OLTP为主的结构化数据loT&#xff0c;日志&#xff0c;各个端等结构非结构均可性价比需要快…

牛客刷题总结——Python入门08:面向对象、正则表达式

&#x1f935;‍♂️ 个人主页: 北极的三哈 个人主页 &#x1f468;‍&#x1f4bb; 作者简介&#xff1a;Python领域优质创作者。 &#x1f4d2; 系列专栏&#xff1a;《牛客题库-Python篇》 &#x1f310;推荐《牛客网》——找工作神器|笔试题库|面试经验|实习经验内推&am…

Design A Youtube

title: Notes of System Design No.05 — Design a Youtube description: ‘Design a Youtube’ date: 2022-05-14 13:45:37 tags: 系统设计 categories: 系统设计 01. Funtional Requirements 02. Non Functional Requirements 03.Assumption 04 API 05 High Level Design 上…

05 MSYS2中安装树莓派32位和64位ARM交叉编译工具

作者将狼才鲸创建日期2022-11-14 Gitee源码和工程地址&#xff1a;才鲸嵌入式 / 开源安防摄像机&#xff08;嵌入式软件&#xff09;CSDN文章地址&#xff1a;项目介绍&#xff1a;开源安防摄像机&#xff08;嵌入式软件&#xff09; 4.3 MSYS2中安装32位和64位ARM交叉编译工具…

1524_AURIX TC275存储分布_下

全部学习汇总&#xff1a; GreyZhang/g_TC275: happy hacking for TC275! (github.com) 继续前面的学习&#xff0c;这一次把这个小章节的剩余信息看完。 这一部分是外设相关的寄存器地址区间描述&#xff0c;看起来一个模块的地址空间占用基本都是256个字节。具体包括什么暂时…

Unity技术手册-UGUI零基础详细教程-Graphic Raycaster 射线检测和Canvas Group

往期文章分享点击跳转>《导航贴》- Unity手册&#xff0c;系统实战学习点击跳转>《导航贴》- Android手册&#xff0c;重温移动开发 本文约3千字&#xff0c;新手阅读需要6分钟&#xff0c;复习需要2分钟 【收藏随时查阅不再迷路】 &#x1f449;关于作者 众所周知&#…

outsystems合集系列(三)

outsystemsModeling DataDatabase Entities的介绍如何创建Database Entities如何用excel快速导入真实数据到entity?如何用excel快速创建entity并导入真实数据?Static Entities的介绍Modeling Data 这一节我将介绍在outsystems中建模数据(model data)的一些思路。注意在这里我…

shellcode 中 null byte 的成因和避免方式总结

背景 shellcode 中要避免 null byte&#xff08;\x00&#xff09;这个是个通用的概念&#xff08;windows&#xff0c;linux 都是一样&#xff09;&#xff0c;因为栈溢出的数据作为字符串写入到栈上&#xff0c;\x00 会作为字符串终止符&#xff0c;毁掉整个 shellcode。 这…

HTML+CSS个人静态网页设计

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

【AGC】安全规则resource.data获取不到字段

问题背景 在表结构里有但resource.data获取不到uid字段 解决该问题 request变量是指请求&#xff0c;request.resource.data是请求数据的所有字段和值的映射&#xff1b;resource变量是指所请求的数据在数据库中保存的状态&#xff0c;resource.data是数据库中保存数据的所有…

教师工作量管理系统思路(链表应用)

教师工作量管理系统思路&#xff08;链表应用&#xff09; 文章目录教师工作量管理系统思路&#xff08;链表应用&#xff09;题目描述&#xff1a;初始信息菜单部分数据结构功能实现查询历史信息从键盘录入信息信息删除和修改工作量计算如何存储到工作量信息链表中&#xff1f…

Bootstrap响应式轮播效果网页(1+X Web前端开发中级 例题)

文章目录 &#x1f4c4;题目要求 &#x1f9e9;说明 &#x1f9e9;效果图 &#x1f4bb;HTML代码 &#x1f3af;实现效果 &#x1f4f0;完整答案 &#x1f4c4;题目要求 阅读下列说明、效果图和HTML代码&#xff0c;进行静态网页开发&#xff0c;填写&#xff08;1&…

springboot12总结篇(9 10 11)

1.视图解析 以重定向为例 如果返回字符串 则会调用视图解析器thymeleafResolver判断返回值为普通字符串&#xff0c;返回thymeleafView调用其render方法&#xff0c;拼接直接访问 2.异常处理 404 ControllerAdvie 处理异常类 ExceptionHandler ControllerAdvie 处理异常类…

适配器模式

思考适配器模式 适配器模式通过转换已有的接口&#xff0c;达成目标需要的接口 适配器模式还可以将多种差异化接口适配成同一接口做统一输出 1.适配器模式的本质 适配器模式的本质是:转换匹配,复用功能。 适配器通过转换调用已有的实现&#xff0c;从而能把已有的实现匹配成需要…

【Spring】——4、使用@Scope注解设置组件的作用域

&#x1f4eb;作者简介&#xff1a;zhz小白 公众号&#xff1a;小白的Java进阶之路 专业技能&#xff1a; 1、Java基础&#xff0c;并精通多线程的开发&#xff0c;熟悉JVM原理 2、熟悉Java基础&#xff0c;并精通多线程的开发&#xff0c;熟悉JVM原理&#xff0c;具备⼀定的线…

VCED:学习Jina的简单操作

文章目录VCED:学习Jina的简单操作在pycharm里连接docker环境几个简单的jina demoimagetextvideoVCED:学习Jina的简单操作 在pycharm里连接docker环境 在pycharm里找到docker环境 New一个环境 在docker里进入terminal&#xff0c;找到python 位置 成功得到decker环境 运行jina…