花指令

查壳发现是 UPX 我们直接去脱壳 由于是ELF文件 所以可以实用kali自带的upx软件来脱壳 也是upx -d (其实是我win版的upx 怎么试都没脱下来)

image

main函数

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int pipedes[2]; // [esp+18h] [ebp-38h] BYREF
  __pid_t v5; // [esp+20h] [ebp-30h]
  int v6; // [esp+24h] [ebp-2Ch] BYREF
  _BYTE buf[30]; // [esp+2Eh] [ebp-22h] BYREF
  unsigned int v8; // [esp+4Ch] [ebp-4h]

  v8 = __readgsdword(0x14u);
  pipe(pipedes);
  v5 = fork();
  if ( !v5 )
  {
    puts("\nOMG!!!! I forgot kid's id");
    write(pipedes[1], "69800876143568214356928753", 0x1Du);
    puts("Ready to exit     ");
    exit(0);
  }
  read(pipedes[0], buf, 0x1Du);
  __isoc99_scanf("%d", &v6);
  if ( v6 == v5 )
  {
    if ( loc_80485F7 == 204 )
    {
      puts(":D");
      exit(1);
    }
    printf("\nYou got the key\n ");
    lol(buf);
  }
  wait(nullptr);
  return 0;
}

能看到一个进程判断 一个软断点判断

执行流程如下

  1. pipe(pipedes) 创建管道
pipedes[0]  // 读取端
pipedes[1]  // 写入端
  1. fork() 创建子进程
v5 = fork();

fork() 的返回值在两个进程中不同

  • 子进程中 v5 == 0
  • 父进程中 v5 == 子进程的 PID
  1. 子进程执行这里
if (!v5)
{
    puts("\nOMG!!!! I forgot kid's id");
    write(pipedes[1], "69800876143568214356928753", 0x1Du);
    puts("Ready to exit");
    exit(0);
}

子进程往管道写入一串数字后退出

然后管道两两边进行比较 比较完成后 进入断点检测 然后到lol函数 进入 发现很少

int lol()
{
  return printf("flag_is_not_here");
}

但是看流程图发现 有很多 但是只显示了一个flag_is_not_here 我们看看

image

发现是 有一个恒跳转 那我们nop一下 就好了

mov     [ebp+var_D], al
mov     [ebp+var_C], 0
cmp     [ebp+var_C], 1
jmp     short loc_80486D3

mov [ebp+var_C], 0 nop完成后

int __cdecl lol(_BYTE *a1)
{
  char v2[7]; // [esp+15h] [ebp-13h] BYREF
  int v3; // [esp+1Ch] [ebp-Ch]

  v2[0] = 2 * a1[1];
  v2[1] = a1[4] + a1[5];
  v2[2] = a1[8] + a1[9];
  v2[3] = 2 * a1[12];
  v2[4] = a1[18] + a1[17];
  v2[5] = a1[10] + a1[21];
  v2[6] = a1[9] + a1[25];
  if ( v3 == 1 )
    return printf("%s", v2);
  else
    return printf("flag_is_not_here");
}

exp

pipedes = '69800876143568214356928753'
flag= ''
flag += chr(2*ord(pipedes[1]))
flag += chr(ord(pipedes[5])+ ord(pipedes[4]))
flag += chr(ord(pipedes[8])+ ord(pipedes[9]))
flag += chr(2*ord(pipedes[12]))
flag += chr(ord(pipedes[18])+ ord(pipedes[17]))
flag += chr(ord(pipedes[10])+ ord(pipedes[21]))
flag += chr(ord(pipedes[9])+ ord(pipedes[25]))

print('RCTF{'+flag+"}")

flag

RCTF{rhelheg}