微擎sql注入到getshell

几年前的一个洞,发现依然存在

if ('download' == $do) {
	$data = base64_decode($post);
	if (base64_encode($data) !== $post) {
		$data = $post;
	}
	$ret = iunserializer($data);
	$gz = function_exists('gzcompress') && function_exists('gzuncompress');
	$file = base64_decode($ret['file']);
	if ($gz) {
		$file = gzuncompress($file);
	}

	$_W['setting']['site']['token'] = authcode(cache_load(cache_system_key('cloud_transtoken')), 'DECODE');
	$string = (md5($file) . $ret['path'] . $_W['setting']['site']['token']);
	if (!empty($_W['setting']['site']['token']) && md5($string) === $ret['sign']) {
						if (0 === strpos($ret['path'], '/web/') || 0 === strpos($ret['path'], '/framework/')) {
			$patch_path = sprintf('%s/data/patch/upgrade/%s', IA_ROOT, date('Ymd'));
		} else {
			$patch_path = IA_ROOT;
		}
		$path = $patch_path . $ret['path'];
		load()->func('file');
		@mkdirs(dirname($path));
		file_put_contents($path, $file);
		$sign = md5(md5_file($path) . $ret['path'] . $_W['setting']['site']['token']);
		if ($ret['sign'] === $sign) {
			exit('success');
		}
	}
	exit('failed');
}

以上是漏洞的核心代码,我简单说明一下,首先依次顺序是:
1.base解密我们post提交的内容
2.反序列化j解密后内容
3.检测是否存在gzuncompress与gzcompress并将返回赋值gz
4.判断gz是否为true当为true则用gzuncompress再解内容
5.获取cloud_transtoken的内容并通过authcode解密
6.将获取到的token与我们md5后的file以及post反序列化后的path进行拼接
7.判断是否获取到token以及进行了常规的sign验证
8.当验证都通过后进行file_put,因为path、file、content均可控所以导致任意文件写入。只需要获取拿到token值即可

cache_load(cache_system_key('cloud_transtoken'))

我们这里的token是从data下的cache中获取到的,我们看看还有没其他方法可以获取到


旧版本这里没有判断token是否为默认的,高版本这里判断了非auth时进行默认检查

5 个赞

新年 0day 啊

那倒不是!!就是一直存着的一个洞而已。。

1 个赞

马上就有活动了,发早了 :thinking:

问题不大!最近也在看东西,到时可以发发另一篇

3 个赞

牛逼!