各位师傅们有没有这样的经历,看着大佬随便爆破就可以进别人网站的后台,嘴上mmp,心里还要mmp,怎么自己的字典就那么呢,没办法,苦求无门,只能自己另寻办法解决。经过学习发现这么个变量覆盖漏洞,可以不用账号密码登录别人的网站后台,一起来学习一下吧。
2变量的概念(有点绕,就是用来赋值的某个东西)
学习任意一门编程语言或者其他,我们都会接触到一个东西,那就是变量。变量是什么,在百度百科中这样定义:变量来源于数学,是计算机语言中能储存计算结果或能表示值的抽象概念。
说实话我觉得很抽象,我们作为渗透测试人员,不需要了解那么深入,能够理解即可。我是这样理解的,变量就是一个盒子,可以赋予它名字,而变量覆盖呢,就是先赋予了一个名字A,后面又再赋予了一个名字B。此时,盒子的名字为B。
从代码来看,可以更直观些:
<?php $a = 1;$a = 2;echo $a;?>
很明显,输出了后面赋值的2。
3变量覆盖漏洞那么这为什么是一个漏洞呢,我们考虑这样一个场景,某程序前面定义了一个变量$app,这个变量的值为该程序定义的app的链接;如果我们可以通过变量覆盖将链接修改,换成我们定义的钓鱼app的链接,那么是不是所有用户都变成访问我这边了呢,当然实际作用远不如此。
4触发变量覆盖的几种情况1、函数extract():将数组中的数据变成变量
<?php $a = "1";$my_array = array("a" =>"Cat","b" => "Dog", "c" =>"Horse");extract($my_array);echo "\$a = $a; \$b = $b; \$c =$c";?>
运行结果:$a = Cat; $b = Dog; $c = Horse
2、函数parse_str():将字符串解析到变量中
<?php parse_str("name=hr_sec&&age=60"); echo$name."
"; //输出hr_sec echo$age; //输出60 ?>
运行结果:输出:hr_sec和60
3、$$:双美元符
<?php $a='b'; $b='a'; echo$$a; //输出a ?>
4、foreach():将数组键值分离
<?php $a = 1;foreach(array('_COOKIE','_POST','_GET') as$_request) {foreach($$_request as $_key=>$_value) { $$_key=addslashes($_value); }}echo $a; //在$_COOKIE、$_POST、$_GET传参a=*即可覆盖原来的$a=1。?>
运行结果:通过GET传参a=5,结果成功输出了传参的值,对$a进行了覆盖。
5实战演示1、首先还是用代码审计工具seay打开源码,全局搜索foreach
2、发现在common.php中有个很熟悉的操作,将REQUEST获取的数据进行键值分离。(那个$$也太熟悉了些)
foreach($$_request as $_k => $_v) ${$_k} = _RunMagicQuotes($_v);
3、右键全局追踪找到函数_RunMagicQuotes(),经分析这里就是执行了一个addslashes()函数,学过SQL注入应该都知道吧,这个就是个魔术引号的,因为我们这里不进行SQL注入,所以这里对我们无影响。
4、那么这里就已经发现了变量覆盖问题了,但是这里无法利用,我们需要看看哪里调用了common.php这个文件
5、这里很明显发现了一个admin/login.php的文件包含了它,点击查看
6、这里发现还包含了一个check.admin.php文件,看字面意思就是检查admin的,在路径:/duomiphp/check.admin.php找到了它,打开查看。
7、这里很明显能够看到这个页面是用来检测SESSION的,就是说我们可以对$_SESSION赋值来获取权限。通过搜索groupid也可以看到值为1时表示系统管理员。
8、现在漏洞点在common.php,admin/login.php包含了这个页面,并且还通过SESSION判断身份,可以覆盖。但是要使SESSION生效需要开启session,那么最后就需要找一个开启了session_start()并且包含了common.php的页面。
9、一个个点,发现在/upload/interface/comment/api/index.php页面有,当然其他也还有,师傅们自己尝试了,这里我就用这个。
10、接下来,搭建网站并尝试访问后台
127.0.0.1/admin/
11、这里看到是需要登录的,我们现在还不知道要覆盖SESSION的什么值,打开check_admin.php,在$_SESSION后面加上如下代码,这里表示输出前面获取的$_SESSION的值之后die()结束代码执行。
die(var_dump($_SESSION));
12、回去输入账号密码登录后台,我这里是默认的admin/admin
13、登录后已经成功获取SESSION了,先记录下来
array(5) { ["duomi_ckstr"]=>string(4) "diuk" ["duomi_ckstr_last"]=> string(0)"" ["duomi_admin_id"]=> string(1) "1" ["duomi_group_id"]=>string(1) "1" ["duomi_admin_name"]=> string(5)"admin" }
14、这里解析一下需要的键值对(即把无用的东西删除)
$_SESSION [duomi_ckstr] => diuk(验证码,经测试也可以不用)$_SESSION [duomi_ckstr_last] => (空,那么这里可以不需要)$_SESSION [duomi_admin_id] => 1$_SESSION [duomi_group_id] => 1$_SESSION [duomi_admin_name] => admin(有人说这样就需要知道用户名才能用了,其实经过测试发现这里随便填什么都行)
15、这里可以构造payload,回忆一下common.php的变量覆盖是$$_REQUEST传参,这里为了方便直接以GET方式构造POC。POC如下:
/interface/comment/api/index.php?_SESSION[duomi_group_id]=1&_SESSION[duomi_admin_id]=1&_SESSION[duomi_admin_name]=hr_sec_ajie
16、首先访问admin.php,需要登录
17、访问一下构造的POC:
http://192.168.43.87/interface/comment/api/index.php?_SESSION[duomi_group_id]=1&_SESSION[duomi_admin_id]=1&_SESSION[duomi_admin_name]=hr_sec_ajie
18、重新访问http://192.168.43.87/admin/,可以看到,成功以管理员身份登录了,用户名就是我输的用户名hr_sec_ajie
·END·
HR_SEC有问题请加我大仁哥/我微信
微信号:empqMTk5ODAyMDM=
大仁哥微信号:jiangdaren000
点分享点收藏点点赞点在看