• BUUCTF web之WarmUp 源代码详解


    目录

    前言

    PHP代码分析

    关于../


    前言

    访问除了一张滑稽图,就没其他的了

    查看源码,有一个注释了的 source.php,可以尝试直接访问一下。同时进行目录扫描

    访问source.php,里面包含php代码,题目说了是php代码审计,那就先从这里进行分析

    提取其中的php代码

    1. highlight_file(__FILE__);
    2. class emmm
    3. {
    4. public static function checkFile(&$page)
    5. {
    6. //定义了一个白名单:source.php和hint.php,判断$page是否为空、是否为字符串
    7. $whitelist = ["source"=>"source.php","hint"=>"hint.php"];
    8. if (! isset($page) || !is_string($page)) {
    9. echo "you can't see it";
    10. return false;
    11. }
    12. //判断&page是否在白名单中
    13. if (in_array($page, $whitelist)) {
    14. return true;
    15. }
    16. //取出$page问号前的东西,然后再判断$_page是否在白名单里,若存在则返回true;
    17. $_page = mb_substr(
    18. $page,
    19. 0,
    20. mb_strpos($page . '?', '?') //获取?号的位置索引
    21. );
    22. if (in_array($_page, $whitelist)) {
    23. return true;
    24. }
    25. //如果上一步判断失败,则又考虑了url编码的问题,因为url在传入以后服务器会自动进行一次解码。因此传入二次编码后的内容,就可以使checkfile返回true。
    26. $_page = urldecode($page);
    27. $_page = mb_substr(
    28. $_page,
    29. 0,
    30. mb_strpos($_page . '?', '?')
    31. );
    32. if (in_array($_page, $whitelist)) {
    33. return true;
    34. }
    35. echo "you can't see it";
    36. return false;
    37. }
    38. }
    39. if (! empty($_REQUEST['file'])
    40. && is_string($_REQUEST['file'])
    41. && emmm::checkFile($_REQUEST['file'])
    42. ) {
    43. include $_REQUEST['file'];
    44. exit;
    45. } else {
    46. echo "
      "
      ;
    47. }
    48. ?>

    PHP代码分析

    1.  代码整体结构分析

    首先定义了一个emmn的类,并且在类emm中定义了一个checkFile()函数,接着判断函数下面的if语句,即if (true && true && true)才能执行include函数,所以需要满足如下3个要求:

    • $_REQUEST['file']不为空,!empty($_REQUEST['file'] 才会返回true;
    • $_REQUEST['file']是字符串,is_string($_REQUEST['file']才会返回true;
    • checkFile($_REQUEST['file']返回true,emmm::checkFile($_REQUEST['file']才会返回true

    前面两个条件很好满足,只需要 source.php?file=字符串 ,即可。所以重点需要让checkeFile函数返回true,则会进行文件包含

    2. chechkFile()函数分析

    首先函数里的语句碰到return就会终止函数的执行,不管下面还有没有语句。函数中共有4个if,只需要让一个if返回true即可

    • 第一个if不能执行括号中的内容,否则return false,函数终止执行。只需满足$page存在且为字符串
    • 第2个语句可以执行,返回true。in_array函数是检查数组中是否存在某个值(找到true;找不false),特别注意这是在数组的键值中找,不包括键。即只要让$page值为source.php或者为hint.php就可以返回true

    所以根据第二个if,尝试访问 /source.php?file=hint.php,没有出现滑稽图,而出现了一个flag提示“flag not here, and flag in ffffllllaaaagggg”,提示flag存在于“ffffllllaaaagggg”这个文件中

    关于../

    ../即回退到上级目录,在url中使用../的时候 ../最前面随便写什么都行,只返回../最后面的文件数据。

    1.txt的内容如下

    “ ?filename=1.txt../../../../../../../../../../Windows/System32/drivers/etc/hosts“,在这里../最前面的1.txt不会返回,只会返回后面的hosts

    1.txt可以换成任何的字符都不会影响返回hosts

    所以根据题目提示我们可以尝试构造如下进行获取flag(../的个数可以随便尝试)

    1. //这里其实包含的就是ffffllllaaaagggg,而不包含hint.php
    2. source.php?file=hint.php../../../../../ffffllllaaaagggg

    此时函数实参 $page的值为 “hint.php../../../../../ffffllllaaaagggg”,但其并不在$whitelist白名单列表中,函数不会返回true。所以出现如下的画面

    我们再回到checkFile函数中,第二个if是不能返回true了。观察第三个if代码,红色框中的意思为取出$page问号?前的字符再赋值给$page,最后再判断$_page是否在白名单里,若存在则返回true;

    仔细分析后发现这段代码是有问题的。那如果构造poc如下,在hint.php后加上?。则经过mb_substr()的截取,返回的$page的值为 hint.php,刚好在白名单中通过校验。函数返回true。相当于访问?file=ffffllllaaaagggg,成功包含ffffllllaaaagggg文件

    source.php?file=hint.php?../../../../../ffffllllaaaagggg

    访问,获取flag{1eee2ed7-7ba6-498e-b1ae-ab2c59863701}

  • 相关阅读:
    MATLAB程序设计与应用 2.5 MATLAB运算
    21 搜索二维矩阵 II
    ROS中预览pcl点云数据,提示fatal error: pcl/point_cloud.h: 没有那个文件或目录
    ARM/Linux嵌入式面经(六):华为【共四面】
    http/https服务器实现
    当Synchronized遇到这玩意儿,有个大坑,要注意
    Socks5代理、IP代理与网络安全:保护你的爬虫和隐私
    JavaScript数组常用方法解析和深层次js数组扁平化
    YOLOv5、v7改进之三十五:引入S2-MLPv2注意力机制
    网页前端设计-作业四(HTML5)
  • 原文地址:https://blog.csdn.net/qq_44159028/article/details/127924757