码迷,mamicode.com
首页 > 其他好文 > 详细

2018/11/28-LCTF-easyre

时间:2018-11-29 10:53:47      阅读:305      评论:0      收藏:0      [点我收藏+]

标签:比较   and   nump   循环   decode   port   tps   range   调用   

 题目链接:https://pan.baidu.com/s/1whGqn75JvrO82XpIc2TyMg 

提取码:q3nl

首先程序对输入的数据构建二叉树,节点的结构体:

技术分享图片

程序使用递归的方式构建二叉树,比节点大的数据作为右孩子,比节点小的数据作为左孩子,构建完成后如果中序遍历二叉树,升序排列。

技术分享图片

技术分享图片

接着sub_4017DD函数对二叉树进行先序遍历。

技术分享图片

 

技术分享图片

接着将遍历节点值存放的数组传进sub_401D6E函数中。

技术分享图片

接着分析sub_401D6E函数。

技术分享图片

sub_4018F0是DES加密,密钥可以找到是"fa1conn",DES加密过程:明文64位->初始置换IP->轮加密变换->逆初始变换IP-1->密文。可以根据初始置换IP,初始逆置换IP-1,选择置换PC-1,选择置换PC-2四个常量表,以及16加密变换的for循环来识别是DES加密。

sub_40195A里面是一个三重循环,是将DES加密后的前36个数据与dword_408020数组存的36个数据当矩阵相乘得到一个6*6的矩阵。

sub_401A24是将得到的矩阵数据与dword_40B6D0数组中的数据比较,比较完矩阵的36位数据后,再比较DES加密后的最后四位的值。

这样我们就可以用python写出脚本进行矩阵逆运算,再进行DES解密,运行即可得到先序遍历的结果"LC-+)=1234@AFETRS{the^VYXZfislrvxyz}"。

from numpy import *
from Crypto.Cipher import DES

A = [[0x17, 0x41, 0x18, 0x4E, 0x2B, 0x38], [0x3B, 0x43, 0x15, 0x2B, 0x2D, 0x4C], [0x17, 0x36, 0x4C, 0x0C, 0x41, 0x2B],
     [0x59, 0x28, 0x20, 0x43, 0x49, 0x39], [0x17, 0x2D, 0x1F, 0x36, 0x1F, 0x34], [0x0D, 0x18, 0x36, 0x41, 0x22, 0x18]]
mA = matrix(A)
B = [[0x0AA92, 0x0C006, 0x0A815, 0x0C920, 0x0D095, 0x0CAD1], [0x7004, 0x9B3C, 0x68A1, 0x0A2C1, 0x8B5B, 0x9EB5],
     [0x7E37, 0x7AA2, 0x4F95, 0x0A344, 0x82AC, 0x8C00], [0x432B, 0x71F7, 0x732D, 0x6E76, 0x70A1, 0x6F34],
     [0x0B465, 0x0E401, 0x0AF37, 0x0DAD2, 0x0DF89, 0x0ECFA], [0x657D, 0x6838, 0x5FCE, 0x977C, 0x71F4, 0x759E]]
mB = matrix(B)
mX = mB * mA.I
X = matrix.tolist(mX)

cipher = ‘‘
for i in range(6):
    for j in range(6):
        X[i][j] = int(round(X[i][j]))
        cipher += hex(X[i][j])[2:].zfill(2)
cipher += 733CF57C

cipher = cipher.decode(hex)
key = fa1conn\x00
des = DES.new(key, DES.MODE_ECB)
plain = des.decrypt(cipher)
print(plain)

接着sub_401ACC确认flag前十八位的值,恢复后得到flag前十八位为”LCTF{this-RevlrSE=“

str = "LC-+)=1234@AFETRS{the^VYXZfislrvxyz}"
arr = [0,1,14,12,17,18,19,27,28,2,15,20,31,29,30,16,13,5]
for i in arr:
    print(str[i],end="")

 

接着又对二叉树进行后序遍历,然后调用sub_4021DE函数。

技术分享图片

分析sub_4021DE函数。

技术分享图片

sub_401D90函数中将flag中每个字符的ascii值的和作为srand()的种子,然后将401E79地址开始的值与rand()异或。

但是不能直接对程序的401E79处的值写脚本进行解密。

因为需要注意的是这只是第二段smc,在开始的时候是存在反调试的,并且反调试和第一段smc有关。也就是说两段smc正确处理后,才能得到正确的自解密函数。

技术分享图片

我们选择patch掉程序中进程名,然后运行程序让第一段smc正确解密,我们当前程序从dump下来得到正确的第一段smc数据,然后写IDApython解密smc函数。

#rand()值
arr = [0x9B,0xBC,0x70,0x3A,0x99,0xF4,0x68,0xB0,0x5F,0x6F,0xDB,0xF1,0xD,0x53,0xA0,0x8C,0xC5,0xCE,0x83,0x25,0x6D,0xC0,0x33,0xC7,0xB0,0xB4,0x5C,0x7C,0x46,0x15,0x10,0x1B,0x76,0x9F,0x6B,0x62,0xD9,0x13,0x77,0x44,0x60,0x2F,0x4D,0x84,0x98,0xDD,0x7D,0x83,0x2D,0xAB,0xB0,0x57,0xAE,0x7B,0x8C,0x1C,0x8F,0x7B,0xD8,0x8F,0x74,0x58,0xE1,0xD9,0xAD,0xAF,0x1C,0xA8,0xFC,0xC5,0xC,0x84,0x9F,0x77,0x66,0x61,0x8A,0x74,0x74,0x70,0xF5,0xA9,0xB7,0x3B,0x16,0xFD,0xD0,0xF1,0x30,0x3F,0xA1,0xFE,0xCC,0x5C,0xAF,0xDF,0x46,0xD6,0xCA,0x35,0x8C,0x71,0xF1,0x18,0x23,0x30,0x70,0xAD,0x6B,0x7F,0x4B,0xFB,0x23,0xB2,0xDF,0xFA,0x2F,0xAE,0xC7]
address = 0x401E79
i =0
while(i <= 118):
    a = Byte(address + i) ^ arr[i]
    PatchByte(address + i,a)
    i = i + 1

接着处理一下即可对自解密函数进行反编译。

技术分享图片

我们写出脚本可以得到flag后序遍历为”)+4321A@=-EFCSRXZYV^ferlsihzyxvt}{TL“。

arr = [0x7c,0x81,0x61,0x99,0x67,0x9b,0x14,0xea,0x68,0x87,0x10,0xec,0x16,0xf9,0x7,0xf2,0xf,0xf3,0x3,0xf4,0x33,0xcf,0x27,0xc6,0x26,0xc3,0x3d,0xd0,0x2c,0xd2,0x23,0xde,0x28,0xd1,0x1,0xe6]
for i in range(36):
    for j in range(0,7,2):
        arr[i] ^= 1 << (j + i % 2)
print(‘‘.join(map(chr,arr)))

函数 sub_401F3C()即确认flag后18位的顺序,我们进行恢复可以得到后十八位为”=^V1@Y+)fAxyzXZ234}“

然后flag即为”LCTF{this-RevlrSE=^V1@Y+)fAxyzXZ234}“。

 

2018/11/28-LCTF-easyre

标签:比较   and   nump   循环   decode   port   tps   range   调用   

原文地址:https://www.cnblogs.com/Fingerprint/p/10036094.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!