From code above we can see that there is mmap function called at initial of main function. The third argument of mmap function is 7, it means that the we allowed to read, write, and execute memory. We can see that the static values and our input (s) are stored also in v20 and at the end there is a call to v20. So basically v20 contains shellcode that will process our input and static values. To know the instructions executed, we can debug it by stepping instruction on v20 call.
pie b 0x14B6
pie run
Input some random value then send "si" to step instruction.
So rdi is our input and rsi is static values. our input (rdi) will be moved each byte to al and then will be xored with 0x18. After that it will be compared with 1 byte value of rsi (static values). From that information we can get the valid value of input by xoring the static values with 0x18. Below is the script to solve the challenge
a =b"[Z[*(*,c +y~~+.,.!)/ }}*yy{/~.{*}| !/}z*e"flag =b""for i in a: flag +=bytes([i ^0x18])print(flag)
Flag: CBC2024{83aff36469178ee2aac7f6c2ed897eb2}
baby-vm (100 pts)
Description
-
Solution
Given ELF 64 bit, open it using IDA
int __fastcall main(int argc,constchar**argv,constchar**envp){ FILE *stream; // [rsp+8h] [rbp-18h] __int64 size; // [rsp+10h] [rbp-10h]void*ptr; // [rsp+18h] [rbp-8h] stream =fopen("code.bin","rb");if ( !stream ) {puts("Failed to open code.bin");exit(1); }fseek(stream,0LL,2); size =ftell(stream);fseek(stream,0LL,0); ptr =malloc(size);fread(ptr, size,1uLL, stream);fclose(stream);if ( (unsignedint)vm_exec(ptr, (unsignedint)size) )puts("Congrats, you own the flag!");elseputs("Oops, wrong flag!");return0;}
The opcode are stored in code.bin and the function that will execute the opcode in vm_exec, so let's check vm_exec.
We can see that the instruction is not much and the operation available only addition and substraction. So basically at the end our input only will be added or subtracted although there are many operation of substraction or addition. With assumption that our input will be processed individually (each byte and independent) so lets set breakpoint at compare instruction (opcode 7).
pie b 0x1516
pie run
Lets do scripting and use 2 different input to check the values compared.
#!/usr/bin/python3import stringdefwrite_payload(data): f =open("payload.txt", "wb") f.write(bytes(data)) f.close()classSolverEquation(gdb.Command):def__init__ (self):super(SolverEquation, self).__init__ ("solve-equation",gdb.COMMAND_OBSCURE)definvoke (self,arg,from_tty):dict={}for i in string.printable[:2]: list_al = [] list_dl = [] tmp = [ord(i)] *45write_payload(tmp) gdb.execute("pie b 0x1516") gdb.execute("pie run < payload.txt")for _ inrange(45): al =addr2num(gdb.selected_frame().read_register("al")) dl =addr2num(gdb.selected_frame().read_register("dl")) gdb.execute("set $al=$dl") gdb.execute("c") list_al.append(al &0xff) list_dl.append(dl &0xff) dict[i]= list_dlprint(dict)print(list_al) gdb.execute("pie del")defaddr2num(addr):try:returnint(addr)except:returnlong(addr)SolverEquation()
Given luac file, it should be compiled lua. At first i tried to clone the repo but it takes long time so i try to find online decompiler and found https://luadec.metaworm.site/. Upload the .luac file and we got decompiled version of it.