XCTF-handcrafted

分析文件类型

看题目以为会是一个pyc文件让反编译,结果是一个不能识别的后缀名,直接丢进WinHex看标识,ascll为python语法所以是一个python文件,修改后缀名为.py

算法分析

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import marshal, zlib, base64

exec(marshal.loads(zlib.decompress(base64.b64decode('eJyNVktv00AQXm/eL0igiaFA01IO4cIVCUGFBBJwqRAckLhEIQmtRfPwI0QIeio/hRO/hJ/CiStH2M/prj07diGRP43Hs9+MZ2fWMxbnP6mux+oK9xVMHPFViLdCTB0xkeKDFEFfTIU4E8KZq8dCvB4UlN3hGEsdddXU9QTLv1eFiGKGM4cKUgsFCNLFH7dFrS9poayFYmIZm1b0gyqxMOwJaU3r6xs9sW1ooakXuRv+un7Q0sIlLVzOCZq/XtsK2oTSYaZlStogXi1HV0iazoN2CV2HZeXqRQ54TlJRb7FUlKyUatISsdzo+P7UU1Gb1POdMruckepGwk9tIXQTftz2yBaT5JQovWvpSa6poJPuqgao+b9l5Aj/R+mLQIP4f6Q8Vb3g/5TB/TJxWGdZr9EQrmn99fwKtTvAZGU7wzS7GNpZpDm2JgCrr8wrmPoo54UqGampFIeS9ojXjc4E2yI06bq/4DRoUAc0nVnng4k6p7Ks0+j/S8z9V+NZ5dhmrJUM/y7JTJeRtnJ2TSYJvsFq3CQt/vnfqmQXt5KlpuRcIvDAmhnn2E0t9BJ3SvB/SfLWhuOWNiNVZ+h28g4wlwUp00w95si43rZ3r6+fUIEdgOZbQAsyFRRvBR6dla8KCzRdslar7WS+a5HFb39peIAmG7uZTHVm17Czxju4m6bayz8e7J40DzqM0jr0bmv9PmPvk6y5z57HU8wdTDHeiUJvBMAM4+0CpoAZ4BPgJeAYEAHmgAUgAHiAj4AVAGORtwd4AVgC3gEmgBBwCPgMWANOAQ8AbwBHgHuAp4D3gLuARwoGmNUizF/j4yDC5BWM1kNvvlxFA8xikRrBxHIUhutFMBlgQoshhPphGAXe/OggKqqb2cibxwuEXjUcQjccxi5eFRL1fDSbKrUhy2CMb2aLyepkegDWsBwPlrVC0/kLHmeCBQ=='))))

导入了三个模块,将base64字符串解密后执行

  • marshal:提供了一种将 Python 对象序列化和反序列化的方式,序列化是将对象转换为字节流以便存储或传输的过程,而反序列化是从字节流创建对象的反向过程。dumps为序列化,loads为反序列化
  • zlib:Python 内置的压缩库,提供了压缩和解压缩数据的功能。它基于 DEFLATE 压缩算法,可以在压缩数据的同时保持数据的完整性。compress为压缩,decompress为解压缩
  • base64: Python 内置的编码和解码二进制数据的库。b64encode为加密函数,b64decode为解密函数
  • exec:既可以执行python语句,又可以执行编译后的字节串
    loads加载的数据若不是同一版本的python解释器产生的会报错,我这里就这种情况
构建pyc文件

看其他师傅wp说exec中的字节串为python虚拟机的可执行二进制码,所以可以直接将其作为pyc文件,然后用工具还原源代码,chatgpt按理应该可以直接将二进制码还原的,不过我没弄出来,还是走pyc文件的路吧
在此之前我们要清楚pyc文件结构:(python3)

  • 文件头:占十六字节
  • 机器码:文件头之后区域
  • python2:只有八个字节的文件头,为魔数和时间
    在这里插入图片描述
    用以下代码将解压缩字节串写入新建文件
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import marshal, zlib, base64

f =open('my.pyc','wb')
pyc =zlib.decompress(base64.b64decode('eJyNVktv00AQXm/eL0igiaFA01IO4cIVCUGFBBJwqRAckLhEIQmtRfPwI0QIeio/hRO/hJ/CiStH2M/prj07diGRP43Hs9+MZ2fWMxbnP6mux+oK9xVMHPFViLdCTB0xkeKDFEFfTIU4E8KZq8dCvB4UlN3hGEsdddXU9QTLv1eFiGKGM4cKUgsFCNLFH7dFrS9poayFYmIZm1b0gyqxMOwJaU3r6xs9sW1ooakXuRv+un7Q0sIlLVzOCZq/XtsK2oTSYaZlStogXi1HV0iazoN2CV2HZeXqRQ54TlJRb7FUlKyUatISsdzo+P7UU1Gb1POdMruckepGwk9tIXQTftz2yBaT5JQovWvpSa6poJPuqgao+b9l5Aj/R+mLQIP4f6Q8Vb3g/5TB/TJxWGdZr9EQrmn99fwKtTvAZGU7wzS7GNpZpDm2JgCrr8wrmPoo54UqGampFIeS9ojXjc4E2yI06bq/4DRoUAc0nVnng4k6p7Ks0+j/S8z9V+NZ5dhmrJUM/y7JTJeRtnJ2TSYJvsFq3CQt/vnfqmQXt5KlpuRcIvDAmhnn2E0t9BJ3SvB/SfLWhuOWNiNVZ+h28g4wlwUp00w95si43rZ3r6+fUIEdgOZbQAsyFRRvBR6dla8KCzRdslar7WS+a5HFb39peIAmG7uZTHVm17Czxju4m6bayz8e7J40DzqM0jr0bmv9PmPvk6y5z57HU8wdTDHeiUJvBMAM4+0CpoAZ4BPgJeAYEAHmgAUgAHiAj4AVAGORtwd4AVgC3gEmgBBwCPgMWANOAQ8AbwBHgHuAp4D3gLuARwoGmNUizF/j4yDC5BWM1kNvvlxFA8xikRrBxHIUhutFMBlgQoshhPphGAXe/OggKqqb2cibxwuEXjUcQjccxi5eFRL1fDSbKrUhy2CMb2aLyepkegDWsBwPlrVC0/kLHmeCBQ=='))
print(pyc)
f.write(pyc)

给文件添加文件头,由于不知道原机器码版本,所以python2,python3文件头都可以试试
winhex->edit->paste zero bytes:新添加字节会被设为0

pyc反汇编

可能是魔数不对,不能直接被还原出源码,但可以用pycdas进行反汇编,一千行有点难顶 两千行!,没法直接输入给chatgpt了(噩梦的开始,这道题越到后面带给我的问题越多)
在这里插入图片描述
狂补字节码知识:

  • https://www.yuque.com/zhao.ming.tai.zi/ksmo0g/trma9l/edit
    师傅们的意思是模拟VM的运行,让字节码跑完,将途中遇到的所有字符串保留下来且输出,由于是逐行运行的所以不会跳过不符合的情况
    沐师傅的wp,VM果然对我来说还是有点难😑
def BINARY_ADD(list1):	# 模拟BINARY_ADD相加操作
	top1=list1.pop()
	top2=list1.pop()
	list1.append(top2+top1)


def ROT_TWO(list1):		# 模拟ROT_TWO交换操作
	top1=list1.pop()
	top2=list1.pop()
	list1.append(top1)
	list1.append(top2)

with open('3.py','r') as fd:	# 将代码中的内容读取进来
	lines=fd.readlines()

list1=[]

for line in lines:				# 遍历每一行
	if "LOAD_CONST" in line:	# 包含LOAD_CONST
		line = line.split()[-1]	# 在每行中根据空格划分子字符串,总是赋值最后一个元素
		if line.isdigit():			# 如果是数字的话直接添加该字符
			list1.append(chr(int(line)))		
		else:
			list1.append(0)		# 如果不是数字的话,栈中添0。代码333行中出现了None,即添加空字符常量
	else:
		if "BINARY_ADD" in line:	 # 如果包含BINARY_ADD,就执行相加操作
			BINARY_ADD(list1)
		elif "ROT_TWO" in line:	 # 如果包含ROT_TWO,就执行交换操作
			ROT_TWO(list1)
print(list1)

hitcon{Now you can compile and run Python bytecode in your brain!}
参考链接:
https://blog.csdn.net/xiao__1bai/article/details/120568154
https://blog.csdn.net/m88997766/article/details/129829565

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值