hws_winter2022-re

一.Babyre

程序入口处调用了一个check函数,但这个是假的检验

跟进去发现做了一些简单操作,尝试了几次但逆不出来,就到别的文件里看了看,结果发现还有一段解密

 

读取了enc文件,并且进行解密,替换class.dex

 

 将enc文件从apk中解压出来,然后解密

package software;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

public class Activity {
	public static void main(String[] args)throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
		try {
            InputStream open = new FileInputStream("C:\\Users\\Lenovo\\Desktop\\enc");
            byte[] bArr = new byte[open.available()];
            open.read(bArr);
            for (int i = 0; i < bArr.length; i++) {
                bArr[i] = (byte) (bArr[i] ^ 52);
            }
            File dir = new File("C:\\Users\\Lenovo\\Desktop");
            File file = new File(dir.getAbsolutePath() + File.separator + "classes.dex");
            if (!file.exists()) {
                file.createNewFile();
            }
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(bArr);
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

	}
}

解密完发现是AES+base64加密,直接使用在线网站解密

 

 二.Easyre

ida进入main函数,发现把输入分成了四部分,每部分进行相同的处理

跟进fun函数,发现是改的xtea,修改了delta和sum的运算

找到key和data解密即可

#include <stdio.h>  
#include <stdint.h>  
    
void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {  
    unsigned int i; 
    uint32_t v0=v[0], v1=v[1], delta=0x61C88647, sum=0;   
    for(i = 0;i < 32;i++)
    {
        sum -= 0x61C88647;
    }
    
    for (i=0; i < num_rounds; i++) {  
        v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);  
        sum += delta;  
        v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);  
    }  
    v[0]=v0; v[1]=v1;  
}  
  
int main()  
{  //0x34,0x9b,0xb2,0xc0,0x6a,0xaf,0x30,0xef, 
   //0x38,0xb2,0xcc,0x98,0x95,0xf1,0xb6,0x85,
   //0x85,0x6,0x48,0xa2,0x59,0x9b,0x3d,0xa6,
   //0x1e,0xc7,0x91,0xf1,0x7b,0x76,0x90,0x67
    uint32_t v[2]={0xc0b29b34,0xef30af6a};
    uint32_t v1[2]={0x98ccb238,0x85b6f195};
    uint32_t v2[2]={0xa2480685,0xa63d9b59};
    uint32_t v3[2]={0xf191c71e,0x6790767b};
    
      
    uint32_t const k[4]={0x29,0x4823,0x18be,0x6784};  
    unsigned int r=32;//num_rounds建议取值为32  
    // v为要加密的数据是两个32位无符号整数  
    // k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位  
    printf("解密前的数据:%x %x\n",v[0],v[1]);  
    decipher(r, v, k);  
    printf("解密后的数据:%x %x\n",v[0],v[1]);  
    printf("解密前的数据:%x %x\n",v1[0],v1[1]);  
    decipher(r, v1, k);  
    printf("解密后的数据:%x %x\n",v1[0],v1[1]);
    printf("解密前的数据:%x %x\n",v2[0],v2[1]);  
    decipher(r, v2, k);  
    printf("解密后的数据:%x %x\n",v2[0],v2[1]);
    printf("解密前的数据:%x %x\n",v3[0],v3[1]);  
    decipher(r, v3, k);  
    printf("解密后的数据:%x %x\n",v3[0],v3[1]);

    uint32_t flag[32] = {0x39,0x63,0x33,0x32,0x30,0x36,0x61,0x33,0x39,0x34,0x32,0x65,0x30,0x38,0x33,0x35,0x64,0x61,0x62,0x61,0x61,0x31,0x38,0x32,0x31,0x32,0x38,0x64,0x36,0x30,0x62,0x63};
    for(int i = 0;i < 32;i++)
    {
        printf("%c",flag[i]);
    }
    return 0;  
}  

 三.repy

主流程分为三部分,第一部分是解密一个10位数字,第二部分是解密一个字符串,第三部分解密py文件,前两部分都加了ollvm混淆,第三部分解密的秘钥要用到第二部分解的结果,尝试用平坦化程序,但是失败了,后来又试了D810和OPBP,但是因为环境问题都失败了,所以前两部分是硬调的,花了很多时间

 

 

 第一部分的校验,对十位数每一位的个数和这个十位数进行比较,爆破不出来,最后是猜出来的,也可以用从第二部分逆推

s = [0]*10
s1 = [0]*10
def check(i):
    tmp = i
    for j in range(0,10):
        x = (tmp+10) % 10
        s[x] += 1
        s1[9 - j] = x
        tmp = int(tmp/10)
    print(s)
    print(s1)
    x = 0
    for k in range(0,10):
        if (s[k] == s1[k]):
            x += 1
        else:
            x = 0
    if (x == 10):
        print(i)
print(check(6210001000))

第二部分的校验,其实直接找到最后一处md5校验即可,这个md5值在有些网站可以直接解出来,正常做尝试用z3解出来,但是也没解出来

from z3 import *
import hashlib
s = Solver()
input_0,input_1,input_2,input_3,input_4,input_5,input_6,input_7,input_8,input_9,input_10,input_11,input_12,input_13,input_14,input_15 = Ints('input_0 input_1 input_2 input_3 input_4 input_5 input_6 input_7 input_8 input_9 input_10 input_11 input_12 input_13 input_14 input_15')
s.add(Distinct(input_0,input_1,input_2,input_3,input_4,input_5,input_6,input_7,input_8,input_9,input_10,input_11,input_12,input_13,input_14,input_15))
s.add(input_0+input_1+input_2+input_3+input_4+input_5+input_6+input_7+input_8+input_9+input_10+input_11+input_12+input_13+input_14+input_15==120)
s.add((input_0+input_1+input_2+input_3)==(input_4+input_5+input_6+input_7))
s.add((input_4+input_5+input_6+input_7)==(input_8+input_9+input_10+input_11))
s.add((input_8+input_9+input_10+input_11)==(input_12+input_13+input_14+input_15))
s.add(input_0+input_4+input_8+input_12==30)
s.add(input_0+input_5+input_10+input_15==30)
s.add(input_0+input_5+input_10+input_15==input_3+input_6+input_9+input_12)
s.add(input_0>=0)
s.add(input_1>=0)
s.add(input_2>=0)
s.add(input_3>=0)
s.add(input_4>=0)
s.add(input_5>=0)
s.add(input_6>=0)
s.add(input_7>=0)
s.add(input_8>=0)
s.add(input_9>=0)
s.add(input_10>=0)
s.add(input_11>=0)
s.add(input_12>=0)
s.add(input_13>=0)
s.add(input_14>=0)
s.add(input_15>=0)
s.add(input_0+input_3+input_12+input_15==30)
s.add(input_5+input_6+input_9+input_10==30)
s.add(input_1+input_2+input_13+input_14==30)
s.add(input_4+input_8+input_7+input_11==30)
s.add(input_0+input_2+input_8+input_10==30)
s.add(input_5+input_7+input_13+input_15==30)
s.add(input_0+input_1+input_4+input_5==30)
s.add(input_2+input_3+input_6+input_7==30)
s.add(input_8+input_9+input_12+input_13==30)
s.add(input_10+input_11+input_14+input_15==30)

while s.check() == sat:
    arr=[0]*16
    model = s.model()
    #print(model)
    s.add(Or([d() != model[d] for d in model]))
    for d in model:
        #print(str(d),":",model[d],end=',')
        if (str(d) == "input_0"):
            arr[0] = model[d].as_long()
        elif (str(d) == "input_1"):
            arr[1] = model[d].as_long()
        elif (str(d) == "input_2"):
            arr[2] = model[d].as_long()
        elif (str(d) == "input_3"):
            arr[3] = model[d].as_long()
        elif (str(d) == "input_4"):
            arr[4] = model[d].as_long()
        elif (str(d) == "input_5"):
            arr[5] = model[d].as_long()
        elif (str(d) == "input_6"):
            arr[6] = model[d].as_long()
        elif (str(d) == "input_7"):
            arr[7] = model[d].as_long()
        elif (str(d) == "input_8"):
            arr[8] = model[d].as_long()
        elif (str(d) == "input_9"):
            arr[9] = model[d].as_long()
        elif (str(d) == "input_10"):
            arr[10] = model[d].as_long()
        elif (str(d) == "input_11"):
            arr[11] = model[d].as_long()
        elif (str(d) == "input_12"):
            arr[12] = model[d].as_long()
        elif (str(d) == "input_13"):
            arr[13] = model[d].as_long()
        elif (str(d) == "input_14"):
            arr[14] = model[d].as_long()
        elif (str(d) == "input_15"):
            arr[15] = model[d].as_long()
    array_40 = [0x63,0x74,0x55,0x33,0x4f,0x67,0x64,0x6f,0x40,0x34,0x72,0x61,0x30,0x79,0x44,0x6e]
    s1 = ""
    for i in arr:
        s1 += chr(array_40[i])
    s1+=chr(0)
    m = hashlib.md5()
    #yOUar3g0oD@tc4nd
    m.update(s1.encode('utf-8'))
    if (s1 == "yOUar3g0oD@tc4nd"):
        print(s1)
    if (m.hexdigest().upper() == "E324486F7B08234DEAFFAFCD1DFA0371"):
        print(s1)

第三部分,这里直接参考的别的师傅平坦化完的结果,对secret.bin进行了AES解密

 

 然后得到一个不完整的pyc文件,根据题目的提示,得知pyc的版本为3.8,先给pyc文件添加magic number,然后修改花指令6e 24,改为6e 00,最后修改花指令后面的36字节为nop(0x09),之后就可以用python的dis模块进行反汇编,但是卡在这里了,后面也没法做了

 

posted @ 2023-01-10 17:11  写在风中的信  阅读(37)  评论(0编辑  收藏  举报