James Hoi's Blog

近期做过的一些题目

Word count: 928Reading time: 4 min
2022/01/11 Share

近期做过的一些题目

学业&机器人挺忙的,逆向做一题就很耗时间,实在是不太有时间认真做题,准备直接找一堆wp复现一遍

湖湘杯 Hideit Hideit

进程序大致能找到这个函数

image-20220111010145631

能看出是向进程内存注入了一个函数,然后根据内存地址调用该函数,断点进入函数,一直跟进去,会发现TestEv1l.dll已注入,具体注入流程尚未分析。

image-20220111012146523

找到加密函数,开头有个修改注册表函数,隐藏了key

image-20220111012911648

image-20220111013550525

进一步分析发现先做了一次xxtea,需要令v12这个输入值正确,成功进入if后再进行一次加密,然后最后再判断是否一致

image-20220111013704574

xtea解密,解密得到第一个密匙为dotitsit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <stdio.h>

void decrypt(unsigned int* v, int* k) {
unsigned int v0 = v[0], v1 = v[1], i; /* set up */
unsigned int sum = 0xC6EF3720;
unsigned int delta = 0x61C88647; /* a key schedule constant */
int index = 0;
for (i = 0; i < 32; i++) { /* basic cycle start */
index = (sum >> 2) & 3;
v1 -= ((sum ^ v0) + (v0 ^ k[index ^ 1])) ^ (((v0 << 4) ^ (v0 >> 3)) + ((v0 >> 5) ^ (v0 << 2)));
v0 -= ((sum ^ v1) + (v1 ^ k[index])) ^ (((v1 << 4) ^ (v1 >> 3)) + ((v1 >> 5) ^ (v1 << 2)));
sum += delta;
} /* end cycle */
v[0] = v0; v[1] = v1;
}

int main()
{
int key[4] = { 114, 514, 19, 19 };
unsigned int v[2] = { 288407067,1668576323 };
decrypt((unsigned int*)v, key);
char* ptr = (char*)v; int i = 0;
for(int i=0;i<8;i++)printf("%c", *(ptr+i));
}

用findcrypt插件提示为salsa20加密,一直尝试无果,最后发现了是chacha20,编写脚本即可

image-20220111015157822

最后的解密脚本:(怎么看出nonce就是dotitist我忘了,大致是动调的结果)

1
2
3
4
5
6
7
8
from Crypto.Cipher import ChaCha20
secret = "0N3@aYI_M3l0dy_KurOm1_W_Suk1dqy0".encode()
ciphertext = bytes([0xEB, 0x8E, 0x5C, 0xA5, 0x62, 0xB4, 0x1C, 0x84, 0x5C, 0x59,0xFC, 0x0D, 0x43, 0x3C, 0xAB, 0x20, 0xD8, 0x93, 0x33, 0x13,0xA1, 0x9E, 0x39, 0x00, 0x76, 0x14, 0xB5, 0x04, 0x58, 0x9D,0x06, 0xB8])
nonce = "dotitsit".encode()
cipher = ChaCha20.new(key=secret, nonce=nonce)
plaintext = cipher.decrypt(ciphertext)

print(plaintext)

得到flag{F1NDM3_4f73r_7H3_5h3LLC0D3}

强网拟态 babyre babyre

其实题目挺简单,我硬是没看出这只是个查表法的aes解密,其余啥都没做。

扔进ida能大致发现应该是个upx,脱壳后进行分析。

强网拟态 babytms babytms

已经搭建好动调环境,有空学习一波arm指令然后复现一次。

MBCrackme MBCrackme

crazyman大佬发的题目,一个exe里就有三题,废物我只做了第一题,主要是思路挺有意思的。.net题目

image-20220111020726584

按下第一个检查密码按钮进入button1_click函数,可见输入的密码作为密匙解密resources文件,然后将所得到的字节保存并执行。

image-20220111020750665

解密过程为将resource图片的像素点的颜色值提取出来,然后循环取每位密码的字节作异或

image-20220111021339163

先将异或前的值提取出来,然后由于最后生成的程序需要执行,不妨假设最后解密后的数据开头是pe的文件头,所以用pe头做密匙异或即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#上文b的值
arr = None
with open("b","rb+") as f:
arr = f.read()

pe_head = [
0x4D,0x5A,0x90,0x00,0x03,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,
0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
]

for j in range(len(pe_head)):
print(chr(arr[j]^pe_head[j]),end="")
#得到easy_level_one_almost_done_xor_pe_and_keep_going!easy_level_
#因为解密为循环去每位密码字节,所以会有重复部分,删除即可

pwd = "easy_level_one_almost_done_xor_pe_and_keep_going!"

with open("level2.exe","wb+") as f:
for i in range(len(arr)):
f.write((ord(pwd[i%len(pwd)])^arr[i]).to_bytes(length=1,byteorder="big",signed=False))

最后得到level2.exe

CATALOG
  1. 1. 近期做过的一些题目
    1. 1.1. 湖湘杯 Hideit Hideit
    2. 1.2. 强网拟态 babyre babyre
    3. 1.3. 强网拟态 babytms babytms
    4. 1.4. MBCrackme MBCrackme