2024西湖论剑初赛RE_wp
MZ
1、固定基址
2、下断点
3、Idapython脚本遍历所有路径
import idc
import hashlib
map = "0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM_@!~"; # 一开始爆破时候没加 ~ 这个字符,直接浪费了我两个多小时的时间...
flag = ""
cip = "dc0562f86bec0a38508e704aa9faa347101e1fdb"
inp = []
def i2b(m):
if m >= 0:
return m
return 256+m
def dfs(addr):
global flag,inp,cip
if len(flag) > 48:
return
if len(flag) == 48:
print(flag)
rinp = []
for i in inp:
rinp.append(i2b(i))
cipdata = bytes(rinp)
sha = hashlib.sha1(cipdata)
encrypts = sha.hexdigest()
if encrypts == cip:
print("flag: ",end="")
print(flag)
print("---------------------------------------------")
print("+++++++++++++++++++++++++++++++++++++++++++++")
print("----------------------------------------------")
exit(0)
return
data = [idc.get_wide_dword(i) for i in range(addr + 0,addr + 0x200*4,4)]
load_str = ""
load_data = []
load_v5 = []
for ch in map:
v5 = ord(ch)
v4 = data[2*v5]
if v5 - 5 == v4:
load_data.append(~(v5+1))
load_str += ch
load_v5.append(v5)
else:
if v5 + 5 != v4:
continue
load_data.append(~(v5-1))
load_str += ch
load_v5.append(v5)
for i in range(len(load_v5)):
idx = 2*load_v5[i] +1
addr = data[idx]
inp.append(load_data[i])
flag += load_str[i]
dfs(addr)
flag = flag[:-1]
inp = inp[:-1]
addr = 0x0439078
dfs(addr)
4、运行脚本
5、拿到flag
flag即为 Somet1mes_ch0ice_i5_more_import@nt_tHan_effort~!
BabyCPP
1、 魔改xtea加密
在0x000000000407EE0地址的位置
2、 魔改rc4加密?
不确定是不是rc4加密,应该是,不过直接dump异或/相加字节流即可完成解密
下条件断点Dump这两处
条件断点类似这样:
import idaapi
edx = idaapi.get_reg_val("edx")
print(f"edx: {hex(edx)}")
3、 解密脚本
首先是rc4部分:
from struct import pack,unpack
cip = [0x33, 0xB2, 0x49, 0x8C, 0x39, 0xDD, 0x60, 0x5F, 0x5F, 0x77, 0x72, 0xAB, 0x38, 0xD9, 0xED, 0xE7, 0xF3, 0xF0, 0x66, 0x67, 0x16, 0xC8, 0x53, 0x80, 0x71, 0xB2, 0xFA, 0x5E, 0x7C, 0x2B, 0xBB, 0x0B, 0xE5, 0x88, 0x82, 0x0B, 0x06, 0x8C, 0x8D, 0xAD, 0x47, 0xB5, 0x85, 0xBB, 0x06, 0x8D, 0x01, 0x2B]
stream = [0x3b,0x3b,0x3e,0xe8,0x2c,0x72,0x2e,0xc7,0xc7,0xde,0x12,0xd1,0x91,0x34,0x61,0x59,0x1d,0x13,0x81,0xd4,0x87,0x67,0xeb,0x73,0x7c,0x58,0xa4,0x6a,0x98,0x97,0x1f,0x83,0x2d,0xa3,0x90,0x76,0xdb,0xf0,0x18,0x89,0x8d,0xe2,0xa7,0x2e,0x44,0xbc,0x4c,0x6c]
add = [0x56,0x2d,0xf8,0x42,0x7f,0xc2,0x26,0x63,0x83,0x32,0xc4,0x3f,0xb9,0xa8,0x7f,0xc9,0x43,0x22,0xc6,0x89,0x6b,0x5d,0xef,0x2e,0xe8,0x20,0xcd,0xbf,0x84,0xf0,0x7b,0x4d,0xd2,0x3f,0x4f,0xb7,0x95,0xf0,0xcd,0x96,0x57,0x56,0x43,0xf1,0x6b,0x1,0xc6,0x36]
xor = [0xee,0x17,0x80,0xe3,0x17,0xa,0xe5,0x53,0x33,0x9e,0x2e,0x1d,0x5,0x6f,0xb4,0x51,0x9a,0x36,0x5c,0xbd,0x8,0xa2,0x34,0xa3,0x65,0x59,0x62,0xae,0x34,0xd,0xd0,0xbc,0x30,0x81,0xeb,0x8c,0x65,0x36,0xfd,0x7e,0x4a,0x1e,0x10,0x27,0xdd,0x5a,0xa4,0xb]
def _2z(m):
if m >= 0:
return m
return 256+m
cip2 = []
for i in range(len(cip)):
cip2.append(_2z((cip[i] ^ xor[i]) - add[i]) ^ stream[i] )
cip2 = bytes(cip2)
cip3 = []
for i in range(0,len(cip2),4):
md = unpack("<I",cip2[i:i+4])[0]
cip3.append(md)
for i in range(0,len(cip3)):
print(f"v24[{i}]=",end = "")
print(hex(cip3[i]),end = ",")
得到:
v24[0]=0xc5ef43bc,v24[1]=0x6e716783,v24[2]=0xa68a692e,v24[3]=0xb4bb3a15,v24[4]=0x85f5b73b,v24[5]=0x86936a34,v24[6]=0x5b6f9350,v24[7]=0xe9efa15c,v24[8]=0xa68a692e,v24[9]=0xb4bb3a15,v24[10]=0x85f5b73b,v24[11]=0x86936a34,
xtea部分:
#include <stdio.h>
#include <stdint.h>
void conver_to_bytes(uint32_t* v){
uint32_t v0=v[0], v1=v[1];
printf("0x%02x,",v[0] & 0x000000ff);
printf("0x%02x,",(v[0] & 0x0000ff00) >> 8);
printf("0x%02x,",(v[0] & 0x00ff0000) >> 16);
printf("0x%02x,",(v[0] & 0xff000000) >> 24);
printf("0x%02x,",v[1] & 0x000000ff);
printf("0x%02x,",(v[1] & 0x0000ff00) >> 8);
printf("0x%02x,",(v[1] & 0x00ff0000) >> 16);
printf("0x%02x,",(v[1] & 0xff000000) >> 24);
// puts("");
}
void conver_to_ch(uint32_t* v){
uint32_t v0=v[0], v1=v[1];
printf("%c",v[0] & 0x000000ff);
printf("%c",(v[0] & 0x0000ff00) >> 8);
printf("%c",(v[0] & 0x00ff0000) >> 16);
printf("%c",(v[0] & 0xff000000) >> 24);
printf("%c",v[1] & 0x000000ff);
printf("%c",(v[1] & 0x0000ff00) >> 8);
printf("%c",(v[1] & 0x00ff0000) >> 16);
printf("%c",(v[1] & 0xff000000) >> 24);
// puts("");
}
void encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
unsigned int i;
uint32_t v0=v[0], v1=v[1], sum=0, delta=0xDEADBEEF;
for (i=0; i < num_rounds; i++) {
v0 += (((v1 << 2) ^ (v1 >> 7)) + v1) ^ (sum + key[sum & 3]);
v1 += (((v0 << 6) ^ (v0 >> 3)) + v0) ^ (sum + key[(sum>>11) & 3]);
sum += delta;
}
v[0]=v0; v[1]=v1;
}
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=0xDEADBEEF, sum=delta*num_rounds;
for (i=0; i < num_rounds; i++) {
sum -= delta;
v1 -= (((v0 << 6) ^ (v0 >> 3)) + v0) ^ (sum + key[(sum>>11) & 3]);
v0 -= (((v1 << 2) ^ (v1 >> 7)) + v1) ^ (sum + key[sum & 3]);
}
v[0]=v0; v[1]=v1;
}
void xTea()
{
unsigned int r=0x100;
uint32_t v[2] = {0};
uint32_t v24[12] = {0};
v24[0] = 0x64778908;
v24[1] = 0x984eaf15;
v24[2] = 0x7a60a998;
v24[3] = 0xbe8ceda9;
v24[4] = 0xb3e7e3ee;
v24[5] = 0xf3b8af91;
v24[6] = 0x345eea0d;
v24[7] = 0x88a4bce4;
v24[8] = 0x7d122bc8;
v24[9] = 0x24957cdd;
v24[10] = 0x952257ca;
v24[11] = 0x474d3142;
v24[0]=0xc5ef43bc,v24[1]=0x6e716783,v24[2]=0xa68a692e,v24[3]=0xb4bb3a15,v24[4]=0x85f5b73b,v24[5]=0x86936a34,v24[6]=0x5b6f9350,v24[7]=0xe9efa15c,v24[8]=0xa68a692e,v24[9]=0xb4bb3a15,v24[10]=0x85f5b73b,v24[11]=0x86936a34;
for(int i=0;i<12;i+=2){
v[0] = v24[i];
v[1] = v24[i+1];
uint32_t const k[4]={0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476};
decipher(r, v, k);
conver_to_ch(v);
}
}
int main(){
xTea();
}
得到:df8d8ab87c22a396041f9bde6a40c4987c22a396041f9bde
拿到flag