好几周前的存稿了….因为懒,所以咕咕咕了…
国外的题目还是很有质量的,考的都是我没遇到过的题
Kernel Reverse
唔,Linux内核逆向…又是一个盲点
ssh连上,发现目录下就一个ioctl.ko
teamx@cyb-driver:~$ file ioctl.ko ioctl.ko: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), BuildID[sha1]=df785cb97d70de2ae5493fa26595d8bd0d1e50a6, with debug_info, not stripped
scp
拿出来分析
在sub_65
发现了疑似flag
字段
满足这两个条件即可,且能够在/dev
目录下找到ioctl
#include <stdio.h> #include <string.h> #include <sys/time.h> #include <sys/ioctl.h> #include <fcntl.h> #include <stdlib.h> int main() { struct timeval t; int a2 = 0x5702; int fs = open("/dev/ioctl", O_RDWR); if (fs == -1) { printf("open driver error.\n"); exit(-1); } printf("open driver success.\n"); gettimeofday(&t, NULL); char flag[128]; int second = t.tv_sec; int a3 = 0x13373389 ^ second; memcpy(flag, &a3, 4); ioctl(fs, a2, flag); printf("%s\n", flag); return 0; }
Listin
SSE……复现,有一些指令没看见过,Google一下
PSHUFB — Packed Shuffle Bytes (felixcloutier.com)
MOVDQA/VMOVDQA32/VMOVDQA64 — Move Aligned Packed Integer Values (felixcloutier.com)
PXOR — Logical Exclusive OR (felixcloutier.com)
分析一遍流程
BITS 64 global check section .text check: mov rbp, rsp sub rsp, 0x100 VMOVDQA ymm0, [rdi] and rsp, 0xffffffffffffff00 mov rax, 0xfeca50051345b0b0 push rax push rax push rax push rax VMOVDQA ymm1, [rsp] VPXOR ymm2, ymm1, ymm0 ; ymm2 = ymm1 ^ ymm0 mov rax, 0x0100030205040706 push rax mov rax, 0x09080b0a0c0d0f0e push rax mov rax, 0x1110131215141716 push rax mov rax, 0x19181b1a1c1d1f1e push rax VMOVDQA ymm3, [rsp] VPSHUFB ymm4, ymm2, ymm3 ; ymm2 根据ymm3的内容打乱ymm2中的字节 mov rax, 0xd1d3762335619aab push rax mov rax, 0xd5d52327356583f8 push rax mov rax, 0xc9d36127336c85b9 push rax mov rax,0xd5d622713161cbf8 push rax VMOVDQA ymm0, [rsp] VPCMPEQQ ymm1, ymm4, ymm0 ; ymm4 == ymm0 VMOVDQA [rsp], ymm1 pop rax cmp rax, 0xffffffffffffffff jnz fail pop rax cmp rax, 0xffffffffffffffff jnz fail pop rax cmp rax, 0xffffffffffffffff jnz fail pop rax cmp rax, 0xffffffffffffffff jnz fail mov rax, 1 jmp fin fail: xor rax, rax fin: mov rsp, rbp ret
需要注意的是VPSHUFB
指令,国内几乎没有具体讲解的文章。于是只能自己看伪代码理解了
没有详细的注释,仔细看几遍就能大致理解流程了
然后就是根据流程写脚本
import struct def parseBytes(ymm: list): arr = [] for j in ymm: arr.extend(struct.pack("<Q", j)) return arr ymm1 = [0xfeca50051345b0b0, 0xfeca50051345b0b0, 0xfeca50051345b0b0, 0xfeca50051345b0b0] # XorKeys ymm3 = [0x19181b1a1c1d1f1e, 0x1110131215141716, 0x09080b0a0c0d0f0e, 0x0100030205040706] # Tables ymm0 = [0xd5d622713161cbf8, 0xc9d36127336c85b9, 0xd5d52327356583f8, 0xd1d3762335619aab] # EncData # https://www.felixcloutier.com/x86/pshufb#fig-4-15 (KL, VL) = (32, 256) jmask = (KL - 1) & ~0XF TbArrs = parseBytes(ymm3) for i in range(len(TbArrs)): TbArrs[i] = (TbArrs[i] & 0xF) + (i & jmask) print("VPSHUFB Tables:", TbArrs) xorDataArr = [0] * len(TbArrs) shuffleArr = parseBytes(ymm0) for i, v in enumerate(TbArrs): xorDataArr[v] = shuffleArr[i] ymm4 = [] xorKey = parseBytes(ymm1) for i in range(len(xorDataArr)): ymm4.append(xorKey[i] ^ xorDataArr[i]) flag = "".join([chr(i) for i in ymm4]) print(flag)
发表回复