【BUUCTF】[GXYCTF2019]BabysqliV3.01

进入题目页面如下

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

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

弱口令密码

用户名:admin

密码:password

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

难道是文件上传?

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

应该换个思路

发现URL里有传参?file=upload

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

构造伪协议

1、home.php

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

2、upload.php

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 复制代码
<?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 伪协议

这里 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 复制代码
<?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源码

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如下

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

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

相关推荐
pt10436 分钟前
BGP分解实验·15——路由阻尼(抑制/衰减)实验
网络·智能路由器
Danileaf_Guo20 分钟前
用BGP的路由聚合功能聚合大陆路由,效果显著不?
运维·网络·智能路由器
程序猿000001号23 分钟前
网络安全技术简介
网络·安全·web安全
Jackilina_Stone2 小时前
【huawei】云计算的备份和容灾
安全·云计算·学习笔记·huawei·灾备
学问小小谢2 小时前
第23节课:前端调试技巧—掌握浏览器开发者工具与性能优化
前端·学习·安全·性能优化·交互·html5
咬光空气3 小时前
Qt 5.14.2 学习记录 —— 이십일 Qt网络和音频
网络·qt·学习
HMS工业网络4 小时前
Anybus网关EtherNet/IP扫描器:快速、可靠、易配置的新一代网关
网络·物联网·安全
垚垚 Securify 前沿站4 小时前
Linux Samba 低版本漏洞(远程控制)复现与剖析
linux·运维·网络·安全·web安全·网络安全·系统安全
张小小大智慧4 小时前
计算机网络部分知识点(王道考研笔记)
运维·网络·智能路由器