猿人学 - app 比赛第一题 python 还原

admin 2025年2月15日22:58:31评论3 views字数 3680阅读12分16秒阅读模式

前言

猿人学 2020 app 逆向 比赛,第一题

为啥写第一题,因为最简单,懒 ~

java 层分析

祭出群友传的神器 jadx-gui 反编译分析一把梭 ...... 中间省略 n 个字,最终定位到 sign 参数的加密逻辑

简单分析下,看到 abcd 四个常量,第一反应是 md5 算法,然后祭出逆向之友,结果不一样,初步怀疑是魔改算法,继续分析代码

没有发现 T 表,此时就开始怀疑这是 md5 吗 ?,了解 md5 算法的小伙伴都知道,每一轮分别会执行四个函数 f g h i 个函数调用 16

但是这个样本只有三个函数 f g h 每个函数也只循环调用了 4 次,很明显有猫腻,但是为了比赛的速度,决定放弃 python 还原,直接复制 java 第一题算是过了

python 还原

比赛结束后,题目的原创大佬 Q佬 为我们解答了,是 md4 算法,此时才明白,Q佬 不愧是 Q老

java 跑起来之后再使用 python 就简单了许多,对照着改 就完事了

0x1

复制 abcd 四个常量

0x2

class Md4Hash(object):
    def __init__(self):
        self.A = 0x67452301
        self.B = 0xefcdab89
        self.C = 0x98badcfe
        self.D = 0x10325476

    def padding(self):
        self.msg_bit_len = len(self.msg) * 8
        self.msg_len = self.msg_bit_len % (2 ** 64)

        self.msg += b'x80'
        pad_leg = ((448 - (self.msg_len + 8) % 512) % 512) // 8

        self.msg = self.msg + b'x00' * pad_leg + self.msg_len.to_bytes(8, byteorder='little')
        self.msg_bit_len = len(self.msg) * 8

    def main(self, msg):
        self.msg = msg.encode()

        self.padding()

padding 函数

0x3

def transform(self):
    iterations = self.msg_bit_len // 512

    for i in range(0, iterations):
        a = self.A
        b = self.B
        c = self.C
        d = self.D

        block = self.msg[i * 64:(i + 1) * 64]
        M = self.__block_divide(block, 16)

        i1_arr = [04812]
        for i1 in range(4):
            i11 = i1_arr[i1]

            a = self.__FF(a, b, c, d, M[i11], 3)
            ff = self.__FF(d, a, b, c, M[i11 + 1], 7)
            c = self.__FF(c, ff, a, b, M[i11 + 2], 11)
            b = self.__FF(b, c, ff, a, M[i11 + 3], 19)
            d = ff

        i2_arr = [0123]
        for i2 in range(4):
            i22 = i2_arr[i2]

            a = self.__GG(a, b, c, d, M[i22], 3)
            d = self.__GG(d, a, b, c, M[i22 + 4], 5)
            c = self.__GG(c, d, a, b, M[i22 + 8], 9)
            b = self.__GG(b, c, d, a, M[i22 + 12], 13)

        i3_arr = [0213]
        for i3 in range(4):
            i33 = i3_arr[i3]

            hh = self.__HH(a, b, c, d, M[i33], 3)
            d = self.__HH(d, hh, b, c, M[i33 + 8], 9)
            c = self.__HH(c, d, hh, b, M[i33 + 4], 11)
            b = self.__HH(b, c, d, hh, M[i33 + 12], 15)
            a = hh

        self.A = (self.A + a) % (2 ** 32)
        self.B = (self.B + b) % (2 ** 32)
        self.C = (self.C + c) % (2 ** 32)
        self.D = (self.D + d) % (2 ** 32)

    return self.__fmt8(self.A) + self.__fmt8(self.B) + self.__fmt8(self.C) + self.__fmt8(self.D)

transform 函数

0x4

@staticmethod
def __F(i, i2, i3):
    return ((~i) & i3) | (i2 & i)

@staticmethod
def __G(i, i2, i3):
    return (i & i3) | (i & i2) | (i2 & i3)

@staticmethod
def __H(i, i2, i3):
    return (i ^ i2) ^ i3

def __FF(self, a, b, c, d, m, s):
    result = self.left_circular_left((a + self.__F(b, c, d) + m), s)
    return result

def __GG(self, a, b, c, d, m, s):
    result = self.left_circular_left((a + self.__G(b, c, d) + m + 1518565785), s)
    return result

def __HH(self, a, b, c, d, m, s):
    result = self.left_circular_left((a + self.__H(b, c, d) + m + 1859775393), s)
    return result

f g h 三个函数

0x5

@staticmethod
def __fmt8(num):
    big_hex = '{0:08x}'.format(num)
    bin_ver = binascii.unhexlify(big_hex)
    result = '{0:08x}'.format(int.from_bytes(bin_ver, byteorder='big'))
    return result

@staticmethod
def __block_divide(block, chunks):
    result = []
    size = len(block) // chunks
    for i in range(0, chunks):
        result.append(int.from_bytes(block[i * size:(i + 1) * size], byteorder="little"))
    return result

@staticmethod
def left_circular_left(k, bits):
    bits = bits % (2 ** 32)
    k = k % (2 ** 32)
    return (k >> (32 - bits) | (k << bits)) % (2 ** 32)

循环左移函数(这里踩了点坑,调试了挺久,具体啥坑忘记了),还有一些工具函数

最后

差不多就这些,代码是参考 md5 源码写的,最终结果一样了

原文始发于微信公众号(二进制科学):猿人学 - app 比赛第一题 python 还原

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月15日22:58:31
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   猿人学 - app 比赛第一题 python 还原https://cn-sec.com/archives/1886664.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息