in this post we going to checkout the WarmWelcome challenge in S4CTF(Peykar).

Category:Reverse

Solution

for first step, i opened the program in r2 and carefully examined the main function.


[0x0000139f]> pdgo
    0x0000139f    |undefined8
    0x0000139f    |main(undefined8 param_1, undefined8 param_2, undefined8 param_3, undefined8 param_4, undefined8 param_5,
                  |    undefined8 param_6, undefined8 param_7, undefined8 param_8)
                  |{
                  |    undefined4 uVar1;
                  |    int32_t iVar2;
                  |    double placeholder_1;
                  |    char var_8bh [2];
                  |    char *s;
                  |    char *buf;
                  |    char var_78h;
                  |    int32_t iStack127;
                  |    int32_t iStack123;
                  |    int64_t var_6fh;
                  |    int32_t iStack100;
                  |    char var_58h;
                  |    char var_57h;
                  |    int64_t var_56h;
                  |    char var_4eh;
                  |    int64_t var_4dh;
                  |    undefined8 req;
                  |    int64_t var_38h;
                  |    undefined8 var_28h;
                  |    undefined8 var_20h;
                  |    undefined8 var_18h;
                  |    int64_t ptr;
                  |    undefined8 size;
                  |    
    0x000013aa    |    req = 0;
    0x000013b2    |    var_38h = 25000000;
    0x000013ba    |    size = 200;
    0x000013c7    |    sym.ncurses_init();
    0x000013d1    |    uVar1 = sym.imp.time(0);
    0x000013d8    |    sym.imp.srand(uVar1);
    0x000013e9    |    ptr = sym.imp.calloc(0x20, size);
    0x000013fe    |    var_18h = sym.imp.calloc(0x20, size);
    0x00001413    |    var_20h = sym.imp.calloc(0x20, size);
    0x00001428    |    var_28h = sym.imp.calloc(0x20, size);
    0x0000143f    |    sym.particle_init(ptr, size);
    0x00001452    |    sym.particle_init(var_18h, size);
    0x00001465    |    sym.particle_init(var_20h, size);
    0x00001478    |    sym.particle_init(var_28h, size);
    0x00001681    |    while (iVar2 = sym.imp.wgetch(_reloc.stdscr), iVar2 != 0x71) {
    0x0000148b    |        placeholder_1 = (double)*(float *)(ptr + 0x18);
    0x000014b2    |        if ((*(double *)0x20a8 <= placeholder_1) || ((double)*(float *)(ptr + 0x18) <= *(double *)0x20b0)) {
    0x000014d5    |            placeholder_1 = (double)*(float *)(ptr + 0x18);
    0x000014fc    |            if ((*(double *)0x20b8 <= placeholder_1) || ((double)*(float *)(ptr + 0x18) <= *(double *)0x20c0)) {
    0x0000151c    |                placeholder_1 = (double)*(float *)(ptr + 0x18);
    0x00001543    |                if ((*(double *)0x20c8 <= placeholder_1) || ((double)*(float *)(ptr + 0x18) <= *(double *)0x20d0)) {
    0x00001563    |                    placeholder_1 = (double)*(float *)(ptr + 0x18);
    0x00001573    |                    if (placeholder_1 < *(double *)0x20d8) {
    0x00001583    |                        sym.particle_init(ptr, size);
                  |                    }
                  |                } else {
    0x00001553    |                    sym.particle_init(var_28h, size);
                  |                }
                  |            } else {
    0x0000150c    |                sym.particle_init(var_20h, size);
                  |            }
                  |        } else {
    0x000014c2    |            sym.particle_init(var_18h, size);
                  |        }
    0x00001592    |        sym.imp.werase(_reloc.stdscr);
    0x000015a2    |        sym.particle_update((uint64_t)*(uint32_t *)0x20e0, placeholder_1, param_3, param_4, param_5, param_6, param_7, 
    0x000015ad    |                            param_8, ptr, size);
    0x000015bd    |        sym.particle_update((uint64_t)*(uint32_t *)0x20e0, placeholder_1, param_3, param_4, param_5, param_6, param_7, 
    0x000015c8    |                            param_8, var_18h, size);
    0x000015d8    |        sym.particle_update((uint64_t)*(uint32_t *)0x20e0, placeholder_1, param_3, param_4, param_5, param_6, param_7, 
    0x000015e3    |                            param_8, var_20h, size);
    0x000015f3    |        sym.particle_update((uint64_t)*(uint32_t *)0x20e0, placeholder_1, param_3, param_4, param_5, param_6, param_7, 
    0x000015fe    |                            param_8, var_28h, size);
    0x00001611    |        sym.particle_draw(ptr, size);
    0x00001624    |        sym.particle_draw(var_18h, size);
    0x00001637    |        sym.particle_draw(var_20h, size);
    0x0000164a    |        sym.particle_draw(var_28h, size);
    0x00001659    |        sym.imp.wrefresh(_reloc.stdscr);
    0x0000165e    |        sym.imp.nanosleep(&req, 0);
                  |    }
    0x0000168e    |    sym.imp.free(ptr);
    0x00001693    |    ptr = 0;
    0x000016a2    |    sym.imp.free(var_18h);
    0x000016a7    |    var_18h = 0;
    0x000016b6    |    sym.imp.free(var_20h);
    0x000016bb    |    var_20h = 0;
    0x000016ca    |    sym.imp.free(var_28h);
    0x000016cf    |    var_28h = 0;
    0x000016d7    |    sym.imp.endwin();
    0x000016e3    |    sym.imp.puts("Hope you enjoy the firework we prepared for you! Now give me a flag :))\n");
    0x000016f9    |    sym.imp.read(0, &buf, 0x34);
    0x000016fe    |    sym.imp.sprintf(&s, 0x2051, 4);
    0x00001739    |    sym.imp.sprintf(var_8bh, 0x2051, 0);
    0x0000173e    |    s._2_1_ = 0x54;
    0x00001745    |    s._3_1_ = 0x68;
    0x0000174c    |    s._4_1_ = 0x33;
    0x00001753    |    s._5_1_ = 0x5f;
    0x0000175a    |    s._6_1_ = 0x46;
    0x00001761    |    s._7_1_ = 0x31;
    0x0000189e    |    if (((((((((char)buf == 'S') && (buf._1_1_ == '4')) && (buf._2_1_ == 'C')) &&
    0x00001790    |           ((buf._3_1_ == 'T' && (buf._4_1_ == 'F')))) && (buf._5_1_ == '{')) &&
    0x000017b4    |         ((((char)var_4dh == '}' &&
    0x000017d3    |           (iVar2 = sym.imp.strncmp((int64_t)&var_6fh + 1, "We1c0m3_fr0m_S4LAB", 0x12), iVar2 == 0)) &&
    0x000017e4    |          ((buf._6_1_ == 'A' && (((buf._7_1_ == '_' && (var_78h == 'v')) && (iStack123 == 0x6d726157)))))))) &&
    0x00001833    |        ((iVar2 = sym.imp.strncmp((int64_t)&var_56h + 1, (int64_t)&s + 2, 6, (int64_t)&s + 2), iVar2 == 0 &&
    0x00001846    |         (iStack100 == 0x6a6e655f)))) &&
    0x00001857    |       ((iStack127 == 0x5f797233 &&
    0x00001866    |        ((((char)var_6fh == (char)var_56h && ((char)var_6fh == '_')) &&
    0x00001876    |         ((var_4eh == 'g' && (((var_57h == 'y' && (var_56h._7_1_ == (char)s)) && (var_58h == var_8bh[0])))))))))) {
    0x000018a7    |        sym.imp.puts("\rOh Wow you are ready for fun!! :)\n");
    0x000018c5    |        return 0;
                  |    }
    0x000018ba    |    sym.imp.puts("Try harder to have fun!!\n");
    0x000018c5    |    return 0;
                  |}

[0x0000139f]> 

As you can see, at the beginning of the program we have a loop that is most likely related to the fireworks display. To easily debug the program, we can disable it by Rewrite JMP Instruction in 0x0000147d address. In the following program code, the expressions printed by the puts function. also we can see read Syscall , that takes input from the user and store it in stack.

and finally , program have a condition and this is all of the problem :D . so let’s go to set BreakPoint on conditions. The points required to set the BreakPoints are between 0x0000176c and 0x0000189c. now we ready to start debugging. For Start we most have a Specific string.I used all uppercase and lowercase letters to recognize the results. abcdefghijklmnopqrstuvwxjzABCDEFGHIJKLMNOPQRSTUVWXYZ

in debugging process , we check values and replace it with our string letters. For convenience, you can use the following code to store data:


#!/usr/bin/python3
deff =  {}

def  main():
	checker =  ""
	letters =  "abcdefghijklmnopqrstuvwxjzABCDEFGHIJKLMNOPQRSTUVWXYZ"
	for i in letters:
		deff[i]  =  hex(ord(i)).replace("0x","")
	while  True:
		checker =  input("Enter letter to set value :>> ")
		if checker ==  "EXIT":
                    break
		value =  input("Enter Value :>> ")
		deff[checker]  = value
	for i in letters:
            print(deff[i],end="")

  
  

if  __name__  ==  "__main__":
    main()

and finally we got the flag :D » S4CTF{A_v3ry_Warm_We1c0m3_fr0m_S4LAB_enj0y_Th3_F14g}