当前位置: 首页 > article >正文

bad_python

攻防世界 (xctf.org.cn)

前戏

下载文件,解压完成后是这个

一个pyc文件

这里要用到python的反编译

要用到的工具有两个

1.python自带的uncompyle6

2.pycdc文件——比uncompyle6强大一点

我们一个一个来尝试一下

uncompyle6:

我是直接在pycharm里面终端用的

把文件放在这个目录下

你需要先安装

然后输入这个命令(在cmd里面也行)

一般来说就OK了

但是这道题考点是进一步的

这是运行了,但是运行出错

最后得到的这个py文件是0kb的,什么都没有

至于后续,我先讲另一种方法,比较常用的

pycdc:

首先你要去下载一个pycdc文件(52上面有)

这样输入,你就会得到一个py文件,名字叫做1.py

但是是0kb

修改文件头

这个MAGIC是指pyc的文件头是坏的

pyc的文件头,我用010editor给大家打开看一下

蓝色标记这部分就是pyc文件的文件头

它包含的信息包括:

前四个字节——版本信息,比如python的3.6,3.8等

中间8个字节——不用管,修改时间而已,对我们来说没有

后面四个字节——包含大小信息和校验码(我也不确定,反正有用)

一般这种错误就是因为这个文件的文件头信息被修改了,我们需要去修复,也就是将文件头修复正确中间我们最重要的一步就是找到他是什么版本的pyc文件,不同版本的文件头不同

我们先给出答案,这道题的版本是3.6,我们可以从两个地方看出来

一:文件名字

还记得最开始文件名那么长的字符吗,你是不是就下意识忽略了,我们在回过头看一下(当时我也没看出来)

3.6版本

二:文件头

这个33 0D 就是3.6版本的文件名开头,他只是修改了后面的部分

然后下面就是我们找到正确的3.6版本的文件头是怎样的了

我是直接百度的,当然厉害的就是自己用3.6版本的python写一个pyc文件,放在010里面去看

橘黄色的就是改的

现在跑出来的py文件就有3KB了

后面就算正常的IDA静态分析了

IDA分析

因为这是个py文件,我们可以直接放入python中去看,他也只有3KB,代码不是很多,就不麻烦IDA了,你要放在IDA里面去看也行

# Source Generated with Decompyle++
# File: 1.pyc (Python 3.6)

from ctypes import *
from Crypto.Util.number import bytes_to_long
from Crypto.Util.number import long_to_bytes

def encrypt(v, k):
    v0 = c_uint32(v[0])
    v1 = c_uint32(v[1])
    sum1 = c_uint32(0)
    delta = 195935983
    for i in range(32):
        v0.value += (v1.value << 4 ^ v1.value >> 7) + v1.value ^ sum1.value + k[sum1.value & 3]
        sum1.value += delta
        v1.value += (v0.value << 4 ^ v0.value >> 7) + v0.value ^ sum1.value + k[sum1.value >> 9 & 3]
    
    return (v0.value, v1.value)

if __name__ == '__main__':
    flag = input('please input your flag:')
    k = [
        255,
        187,
        51,
        68]
    if len(flag) != 32:
        print('wrong!')
        exit(-1)
    a = []
    for i in range(0, 32, 8):
        v1 = bytes_to_long(bytes(flag[i:i + 4], 'ascii'))
        v2 = bytes_to_long(bytes(flag[i + 4:i + 8], 'ascii'))
        a += encrypt([
            v1,
            v2], k)
    
    enc = [
        0xEEC7D402L,
        0x99E9363FL,
        0x853BDE61L,
        558171287,
        0x908F94B0L,
        1715140098,
        986348143,
        1948615354]
    for i in range(8):
        if enc[i] != a[i]:
            print('wrong!')
            exit(-1)
    print('flag is flag{%s}' % flag)

就是这么个事

直接开干吧

这段代码可能新手比较懵逼

这个<<4,就是在二进制表示下,把整个数往左边移动4位,就也是变大了2的四次方大

这个>>7就是右移7次,就是表现2的七次方小,向下取整

然后这个&3就是在二进制层面按位与

3是11,8是11000

1000

0011

相同位置如果都是1,那么得到1,不同为0

得到的结果就是

0000

对应这段代码我很懵逼

然后我去实验了下

825307441

然后把1111又换成了aaaa,也是一串数字

得到了这个数字,然后感觉就是把4个字符串转换成为了一个数字,感觉和base64作用差不多

就是把每个字符的ASCII码提出来,然后通过一些算法组合在一起

这里我采用的就是暴力的方法的,硬跑

加上这个直接全部遍历一遍

(抄一个吧,不想写了)

我是废物

enc = [63912563639333235,63912563820295007,63912563319981409,63912564160552784,63912564260890672,63912564074962770,63912563086615890,63912564159242032]
flag = bytearray(32)
for i in range(8):
    flag[4 * i] = (enc[i] >> 24) & 0xFFFFFFFF & 0xFF
    flag[4 * i + 1] = (enc[i] >> 16) & 0xFFFFFFFF & 0xFF
    flag[4 * i + 2] = (enc[i] >> 8) & 0xFFFFFFFF & 0xFF
    flag[4 * i + 3] = (enc[i] & 0xFFFFFFFF & 0xFF)

print(flag)
#bytearray(b'Th1s_1s_A_Easy_Pyth0n__R3veRse_0')

看不懂为啥这样就OK了,我是废物!~

但是废物也要下班拉~


http://www.kler.cn/news/157072.html

相关文章:

  • Vue3实现一个拾色器功能
  • TimeGPT:时间序列预测模型实例
  • TDA4开发环境Docker化
  • 《系统架构设计师教程(第2版)》第2章-计算机系统基础知识-01-计算机硬件
  • Spring中通知是什么
  • Redis7--基础篇4(Redis事务)
  • CocosCreator 面试题(二十) Cocos creator 如何实现一个置灰Shader?
  • [Ubuntu 20.04] 使用Netplan配置网络静态IP
  • RH850P1X芯片学习笔记-Pin Functions
  • 智能优化算法应用:基于松鼠算法无线传感器网络(WSN)覆盖优化 - 附代码
  • 什么是Overlay网络?Overlay网络与Underlay网络有什么区别?
  • 搭建CIG容器重量级监控平台
  • C\C++ 获取最值
  • 无人机覆盖路径规划综述
  • 学习率设置(写给自己看)
  • Redis队列stream,Redis多线程详解
  • Python3+selenium自动化测试框架详解
  • LoadBalancer将服务暴露到外部实现负载均衡Openelb-layer2模式配置介绍
  • 新数字化时代广告的多变式玩法:广告电商
  • 基于Java SSM产品销售管理系统
  • 快速安装Axure RP Extension for Chrome插件
  • Web漏洞分析-SQL注入XXE注入(上)
  • 贝叶斯网络 (人工智能期末复习)
  • 编译原理:正规表达式转换为NFA(原理+完整代码实现)
  • 零基础学Python的第五天||字符串(2)
  • 在python中自己定义一个方法,但是没有写return XXX会有什么影响
  • Liunx系统使用超详细(三)
  • py 启动默认浏览器
  • 工程师业余生活之制作蔬菜盆景
  • 二维码智慧门牌管理系统升级:高效管控门牌贴牌过程