SECCON Beginners CTF 2021 解けなかった問題を勉強した記録3

reversing 03 please_not_trace_me は gdb の勉強
reversing 04 be_angry は人生初 angr



# reversing 03 please_not_trace_me

Ghidraで処理の流れを確認

```c:main
void main(undefined4 param_1,undefined8 param_2,undefined8 param_3)

{
  int local_54;
  int local_50;
  void *local_48;
  long local_40;
  long local_38;
  undefined8 local_30;
  
  megaInit();
  local_30 = 9;
  _global_argv = param_2;
  _global_argc = param_1;
  _global_envp = param_3;
  do {
    switch(local_30) {
    case 0:
      local_50 = 2;
      local_30 = 0xb;
      break;
    case 2:
      local_30 = _1_main_flag_func_0(local_38,0xffffffffffffffff,0x10,5);
      break;
    case 5:
      if (local_50 == 6) {
        local_30 = 0x12;
      }
      else {
        local_30 = 8;
      }
      break;
    case 6:
      if (local_40 == 0) {
        local_30 = 0;
      }
      else {
        local_30 = 0xb;
      }
      break;
    case 8:
      fwrite("prease not trace me... ",1,0x17,stderr);
                    /* WARNING: Subroutine does not return */
      exit(1);
    case 9:
      local_54 = 0;
      local_30 = 10;
      break;
    case 10:
      switch(local_54) {
      case 0:
        local_30 = 0x16;
        break;
      case 1:
        local_30 = 0xf;
        break;
      case 2:
        local_30 = 0x13;
        break;
      case 3:
        local_30 = 0x14;
        break;
      case 4:
        local_30 = 0x11;
        break;
      case 5:
        local_30 = 0x15;
        break;
      default:
        local_30 = 0x12;
      }
      break;
    case 0xb:
      local_38 = ptrace(PTRACE_TRACEME,0,1,0);
      local_30 = 2;
      break;
    case 0xf:
      local_48 = malloc(0x10);
      local_30 = 0x12;
      break;
    case 0x10:
      local_50 = local_50 * 3;
      local_30 = 5;
      break;
    case 0x11:
      puts("flag decrypted. bye.");
      local_30 = 0x12;
      break;
    case 0x12:
      local_54 = local_54 + 1;
      local_30 = 10;
      break;
    case 0x13:
      generate_key(local_48);
      local_30 = 0x12;
      break;
    case 0x14:
      rc4(e,local_48);
      local_30 = 0x12;
      break;
    case 0x15:
                    /* WARNING: Subroutine does not return */
      exit(0);
    case 0x16:
      local_50 = 0;
      local_40 = ptrace(PTRACE_TRACEME,0,1,0);
      local_30 = 6;
    }
  } while( true );
}
```

local_30 で処理が分岐する
0x09 が local_30 の初期値
各分岐では，次の分岐の為に local_30 に分岐先番号を再セットしている

この再セットを gdb で細工して
0x0f  malloc()       # keyを格納するヒープを確保
0x13  generate_key() # keyをヒープに設定
0x14  rc4()          # 復号
と処理を流せば関数名rc4（中身はrc4ではない）で復号される。
※encrypted flagは，switchに入る前のmegaInit()で設定済み。

逆アセ

```
gdb-peda$ pdisass main
Dump of assembler code for function main:
   0x00005555555551ff <+0>:	push   rbp
   0x0000555555555200 <+1>:	mov    rbp,rsp
=> 0x0000555555555203 <+4>:	sub    rsp,0x70
   0x0000555555555207 <+8>:	mov    DWORD PTR [rbp-0x54],edi
   0x000055555555520a <+11>:	mov    QWORD PTR [rbp-0x60],rsi
   0x000055555555520e <+15>:	mov    QWORD PTR [rbp-0x68],rdx
   0x0000555555555212 <+19>:	call   0x55555555585e <megaInit>
   0x0000555555555217 <+24>:	mov    eax,DWORD PTR [rbp-0x54]
   0x000055555555521a <+27>:	mov    DWORD PTR [rip+0x2e18],eax        # 0x555555558038 <_global_argc>
   0x0000555555555220 <+33>:	mov    rax,QWORD PTR [rbp-0x60]
   0x0000555555555224 <+37>:	mov    QWORD PTR [rip+0x2e05],rax        # 0x555555558030 <_global_argv>
   0x000055555555522b <+44>:	mov    rax,QWORD PTR [rbp-0x68]
   0x000055555555522f <+48>:	mov    QWORD PTR [rip+0x2e0a],rax        # 0x555555558040 <_global_envp>
   0x0000555555555236 <+55>:	mov    DWORD PTR [rbp-0x44],0x1
   0x000055555555523d <+62>:	mov    QWORD PTR [rbp-0x28],0x9   <--- 初期値
   0x0000555555555245 <+70>:	cmp    QWORD PTR [rbp-0x28],0x16
   0x000055555555524a <+75>:	ja     0x555555555245 <main+70>
   0x000055555555524c <+77>:	mov    rax,QWORD PTR [rbp-0x28]
   0x0000555555555250 <+81>:	lea    rdx,[rax*4+0x0]
   0x0000555555555258 <+89>:	lea    rax,[rip+0xdd5]        # 0x555555556034
   0x000055555555525f <+96>:	mov    eax,DWORD PTR [rdx+rax*1]
   0x0000555555555262 <+99>:	cdqe   
   0x0000555555555264 <+101>:	lea    rdx,[rip+0xdc9]        # 0x555555556034
   0x000055555555526b <+108>:	add    rax,rdx
   0x000055555555526e <+111>:	jmp    rax
   0x0000555555555270 <+113>:	mov    rax,QWORD PTR [rbp-0x40]
   0x0000555555555274 <+117>:	mov    rdi,rax
   0x0000555555555277 <+120>:	call   0x5555555551a9 <generate_key>
   0x000055555555527c <+125>:	mov    QWORD PTR [rbp-0x28],0x12
   0x0000555555555284 <+133>:	jmp    0x5555555554b3 <main+692>
   0x0000555555555289 <+138>:	mov    rax,QWORD PTR [rbp-0x40]
   0x000055555555528d <+142>:	mov    rsi,rax
   0x0000555555555290 <+145>:	lea    rdi,[rip+0x2db9]        # 0x555555558050 <e>
   0x0000555555555297 <+152>:	call   0x5555555555f8 <rc4>
   0x000055555555529c <+157>:	mov    QWORD PTR [rbp-0x28],0x12
   0x00005555555552a4 <+165>:	jmp    0x5555555554b3 <main+692>
   0x00005555555552a9 <+170>:	mov    edx,DWORD PTR [rbp-0x48]
   0x00005555555552ac <+173>:	mov    eax,edx
   0x00005555555552ae <+175>:	add    eax,eax
   0x00005555555552b0 <+177>:	add    eax,edx
   0x00005555555552b2 <+179>:	mov    DWORD PTR [rbp-0x48],eax
   0x00005555555552b5 <+182>:	mov    QWORD PTR [rbp-0x28],0x5
   0x00005555555552bd <+190>:	jmp    0x5555555554b3 <main+692>
   0x00005555555552c2 <+195>:	add    DWORD PTR [rbp-0x4c],0x1
   0x00005555555552c6 <+199>:	mov    QWORD PTR [rbp-0x28],0xa
   0x00005555555552ce <+207>:	jmp    0x5555555554b3 <main+692>
   0x00005555555552d3 <+212>:	mov    DWORD PTR [rbp-0x48],0x0
   0x00005555555552da <+219>:	mov    ecx,0x0
   0x00005555555552df <+224>:	mov    edx,0x1
   0x00005555555552e4 <+229>:	mov    esi,0x0
   0x00005555555552e9 <+234>:	mov    edi,0x0
   0x00005555555552ee <+239>:	mov    eax,0x0
   0x00005555555552f3 <+244>:	call   0x555555555080 <ptrace@plt>
   0x00005555555552f8 <+249>:	mov    QWORD PTR [rbp-0x38],rax
   0x00005555555552fc <+253>:	mov    QWORD PTR [rbp-0x28],0x6
   0x0000555555555304 <+261>:	jmp    0x5555555554b3 <main+692>
   0x0000555555555309 <+266>:	cmp    DWORD PTR [rbp-0x48],0x6
   0x000055555555530d <+270>:	je     0x55555555531c <main+285>
   0x000055555555530f <+272>:	mov    QWORD PTR [rbp-0x28],0x8
   0x0000555555555317 <+280>:	jmp    0x5555555554b3 <main+692>
   0x000055555555531c <+285>:	mov    QWORD PTR [rbp-0x28],0x12
   0x0000555555555324 <+293>:	jmp    0x5555555554b3 <main+692>
   0x0000555555555329 <+298>:	lea    rdi,[rip+0xcd4]        # 0x555555556004
   0x0000555555555330 <+305>:	call   0x555555555040 <puts@plt>
   0x0000555555555335 <+310>:	mov    QWORD PTR [rbp-0x28],0x12
   0x000055555555533d <+318>:	jmp    0x5555555554b3 <main+692>
   0x0000555555555342 <+323>:	mov    DWORD PTR [rbp-0x48],0x2
   0x0000555555555349 <+330>:	mov    QWORD PTR [rbp-0x28],0xb
   0x0000555555555351 <+338>:	jmp    0x5555555554b3 <main+692>
   0x0000555555555356 <+343>:	cmp    QWORD PTR [rbp-0x38],0x0
   0x000055555555535b <+348>:	jne    0x55555555536a <main+363>
   0x000055555555535d <+350>:	mov    QWORD PTR [rbp-0x28],0x0
   0x0000555555555365 <+358>:	jmp    0x5555555554b3 <main+692>
   0x000055555555536a <+363>:	mov    QWORD PTR [rbp-0x28],0xb
   0x0000555555555372 <+371>:	jmp    0x5555555554b3 <main+692>
   0x0000555555555377 <+376>:	cmp    DWORD PTR [rbp-0x4c],0x5
   0x000055555555537b <+380>:	ja     0x5555555553dc <main+477>
   0x000055555555537d <+382>:	mov    eax,DWORD PTR [rbp-0x4c]
   0x0000555555555380 <+385>:	lea    rdx,[rax*4+0x0]
   0x0000555555555388 <+393>:	lea    rax,[rip+0xd01]        # 0x555555556090
   0x000055555555538f <+400>:	mov    eax,DWORD PTR [rdx+rax*1]
   0x0000555555555392 <+403>:	cdqe   
   0x0000555555555394 <+405>:	lea    rdx,[rip+0xcf5]        # 0x555555556090
   0x000055555555539b <+412>:	add    rax,rdx
   0x000055555555539e <+415>:	jmp    rax
   0x00005555555553a0 <+417>:	mov    QWORD PTR [rbp-0x28],0x16
   0x00005555555553a8 <+425>:	jmp    0x5555555553e5 <main+486>
   0x00005555555553aa <+427>:	mov    QWORD PTR [rbp-0x28],0xf
   0x00005555555553b2 <+435>:	jmp    0x5555555553e5 <main+486>
   0x00005555555553b4 <+437>:	mov    QWORD PTR [rbp-0x28],0x13
   0x00005555555553bc <+445>:	jmp    0x5555555553e5 <main+486>
   0x00005555555553be <+447>:	mov    QWORD PTR [rbp-0x28],0x14
   0x00005555555553c6 <+455>:	jmp    0x5555555553e5 <main+486>
   0x00005555555553c8 <+457>:	mov    QWORD PTR [rbp-0x28],0x11
   0x00005555555553d0 <+465>:	jmp    0x5555555553e5 <main+486>
   0x00005555555553d2 <+467>:	mov    QWORD PTR [rbp-0x28],0x15
   0x00005555555553da <+475>:	jmp    0x5555555553e5 <main+486>
   0x00005555555553dc <+477>:	mov    QWORD PTR [rbp-0x28],0x12
   0x00005555555553e4 <+485>:	nop
   0x00005555555553e5 <+486>:	jmp    0x5555555554b3 <main+692>
   0x00005555555553ea <+491>:	mov    rax,QWORD PTR [rip+0x2c2f]        # 0x555555558020 <stderr@@GLIBC_2.2.5>
   0x00005555555553f1 <+498>:	mov    rcx,rax
   0x00005555555553f4 <+501>:	mov    edx,0x17
   0x00005555555553f9 <+506>:	mov    esi,0x1
   0x00005555555553fe <+511>:	lea    rdi,[rip+0xc14]        # 0x555555556019
   0x0000555555555405 <+518>:	call   0x5555555550a0 <fwrite@plt>
   0x000055555555540a <+523>:	mov    edi,0x1
   0x000055555555540f <+528>:	call   0x555555555090 <exit@plt>
   0x0000555555555414 <+533>:	mov    edi,0x0
   0x0000555555555419 <+538>:	call   0x555555555090 <exit@plt>
   0x000055555555541e <+543>:	mov    QWORD PTR [rbp-0x18],0x10
   0x0000555555555426 <+551>:	mov    QWORD PTR [rbp-0x10],0x5
   0x000055555555542e <+559>:	mov    rcx,QWORD PTR [rbp-0x10]
   0x0000555555555432 <+563>:	mov    rdx,QWORD PTR [rbp-0x18]
   0x0000555555555436 <+567>:	mov    rax,QWORD PTR [rbp-0x30]
   0x000055555555543a <+571>:	mov    rsi,0xffffffffffffffff
   0x0000555555555441 <+578>:	mov    rdi,rax
   0x0000555555555444 <+581>:	call   0x555555555933 <_1_main_flag_func_0>
   0x0000555555555449 <+586>:	mov    QWORD PTR [rbp-0x8],rax
   0x000055555555544d <+590>:	mov    rax,QWORD PTR [rbp-0x8]
   0x0000555555555451 <+594>:	mov    QWORD PTR [rbp-0x28],rax
   0x0000555555555455 <+598>:	jmp    0x5555555554b3 <main+692>
   0x0000555555555457 <+600>:	mov    DWORD PTR [rbp-0x4c],0x0
   0x000055555555545e <+607>:	mov    QWORD PTR [rbp-0x28],0xa
   0x0000555555555466 <+615>:	jmp    0x5555555554b3 <main+692>
   0x0000555555555468 <+617>:	mov    ecx,0x0
   0x000055555555546d <+622>:	mov    edx,0x1
   0x0000555555555472 <+627>:	mov    esi,0x0
   0x0000555555555477 <+632>:	mov    edi,0x0
   0x000055555555547c <+637>:	mov    eax,0x0
   0x0000555555555481 <+642>:	call   0x555555555080 <ptrace@plt>
   0x0000555555555486 <+647>:	mov    QWORD PTR [rbp-0x30],rax
   0x000055555555548a <+651>:	mov    QWORD PTR [rbp-0x28],0x2
   0x0000555555555492 <+659>:	jmp    0x5555555554b3 <main+692>
   0x0000555555555494 <+661>:	mov    edi,0x10
   0x0000555555555499 <+666>:	call   0x555555555070 <malloc@plt>
   0x000055555555549e <+671>:	mov    QWORD PTR [rbp-0x20],rax
   0x00005555555554a2 <+675>:	mov    rax,QWORD PTR [rbp-0x20]
   0x00005555555554a6 <+679>:	mov    QWORD PTR [rbp-0x40],rax
   0x00005555555554aa <+683>:	mov    QWORD PTR [rbp-0x28],0x12
   0x00005555555554b2 <+691>:	nop
   0x00005555555554b3 <+692>:	jmp    0x555555555245 <main+70>
End of assembler dump.
```

switchで分岐させている local_30 は，`QWORD PTR [rbp-0x28]` に格納される

初期値 0x9 が入っている状況

```
gdb-peda$ x/x $rbp-0x28
0x7fffffffe218:	0x0000000000000009
```

スタックのアドレスは 0x7fffffffe218

0x7fffffffe218の値をタイミングよく，0x09  -->  0x0f  -->  0x13  -->  0x14 と書き換えながら n (next) で進める


case 0x9 の分岐で，次の値を 0x0f に書き換えて n (next)

```
gdb-peda$ set {int}0x7fffffffe218=0x0f
```

case 0x0f の分岐で，mallocを通過後， 0x13 に書き換えて n (next)

```
=> 0x555555555499 <main+666>:	call   0x555555555070 <malloc@plt>

gdb-peda$ set {int}0x7fffffffe218=0x13
```

case 0x13 の分岐で，generate_keyを通過後， 0x14 に書き換えて n (next)

```
=> 0x555555555277 <main+120>:	call   0x5555555551a9 <generate_key>

gdb-peda$ set {int}0x7fffffffe218=0x14
```

復号処理に入ってくる

```
=> 0x555555555297 <main+152>:	call   0x5555555555f8 <rc4>
```

rc4を抜けたところで， RAX (ret) を確認 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/c7c270ef-1431-3279-d701-e95a6bcd1980.png)

後の祭りというか，結果論というか，このくらい，gdbでメモリを書き換えたこと一度もなかったにせよ，当日できそうだ。
ふがいない自分に腹が立つ。



# reversing 04 be_angry

今日，初めて angr のインストールに成功したので angr問題に挑戦する。

普通に動かすと

```
# ./be_angry
AAA
Incorrect!!
```


Ghidraのデコンパイル

```c:main

void main(undefined4 param_1,undefined8 param_2,undefined8 param_3)

{
  uint uVar1;
  int iVar2;
  long in_FS_OFFSET;
  uint local_190;
  long local_160;
  char local_38 [2];
  char local_36;
  char local_34;
  char local_32;
  char local_2f;
  char local_2d;
  char local_2b;
  char local_2a;
  char local_28;
  char local_27;
  char local_25;
  char local_22;
  char local_21;
  undefined8 local_10;
  
  local_10 = *(undefined8 *)(in_FS_OFFSET + 0x28);
  megaInit();
  local_160 = 0xe;
  _global_argv = param_2;
  _global_argc = param_1;
  _global_envp = param_3;
  do {
                    /* WARNING: Could not find normalized switch variable to match jumptable */
    switch(local_160) {
    case 0:
      puts("Incorrect!!");
      local_160 = 0x27;
      break;
    case 2:
      puts("Incorrect!!");
      local_160 = 0x27;
      break;
    case 4:
      if ((int)((int)local_22 - (local_190 * 2 + ~local_190) |
               (~local_190 + local_190 * 2) - (int)local_22) < 0) {
        local_160 = 10;
      }
      else {
        local_160 = 0x10;
      }
      break;
    case 6:
      if ((int)((int)local_27 - (local_190 + 4) | (local_190 + 4) - (int)local_27) < 0) {
        local_160 = 5;
      }
      else {
        local_160 = 0xd;
      }
      break;
    case 8:
      iVar2 = -((int)((((int)local_2f - ((local_190 & 0xffffffcc) * 2 + (local_190 ^ 0xffffffcc))) +
                       0x80000000 ^
                      (int)(((int)local_2f -
                            ((local_190 & 0xffffffcc) * 2 + (local_190 ^ 0xffffffcc))) + -0x80000000
                           ) >> 0x1f) -
                     ((int)(((int)local_2f -
                            ((local_190 & 0xffffffcc) * 2 + (local_190 ^ 0xffffffcc))) + -0x80000000
                           ) >> 0x1f)) >> 0x1f);
      uVar1 = (uint)(iVar2 == 0);
      local_160 = ((long)(int)~uVar1 & 0xcU) * (long)(int)uVar1 + (long)iVar2 * 0x21;
      break;
    case 10:
      puts("Incorrect!!");
      local_160 = 0x27;
      break;
    case 0xc:
      puts("Incorrect!!");
      local_160 = 0x27;
      break;
    case 0xe:
      local_190 = 100;
      fgets(local_38,0x19,stdin);
      local_160 = 0x28;
      break;
    case 0x10:
      if ((int)((((int)local_21 - ((local_190 & 0x19) * 2 + (local_190 ^ 0x19))) + 0x80000000 ^
                (int)(((int)local_21 - ((local_190 & 0x19) * 2 + (local_190 ^ 0x19))) + -0x80000000)
                >> 0x1f) -
               ((int)(((int)local_21 - ((local_190 & 0x19) * 2 + (local_190 ^ 0x19))) + -0x80000000)
               >> 0x1f)) < 0) {
        local_160 = 0x20;
      }
      else {
        local_160 = 0x1a;
      }
      break;
    case 0x12:
      local_160 = _1_main_flag_func_6((int)local_2d,local_190 - 0x31,0x19);
      break;
    case 0x14:
      puts("Incorrect!!");
      local_160 = 0x27;
      break;
    case 0x16:
      local_160 = _1_main_flag_func_3((int)local_2b,local_190 - 0x30,0x2a);
      break;
    case 0x18:
      puts("Incorrect!!");
      local_160 = 0x27;
      break;
    case 0x1a:
      puts("Incorrect!!");
      local_160 = 0x27;
      break;
    case 0x1c:
      if ((int)((int)local_32 - ((local_190 * 2 | 0xffffff9e) - (local_190 ^ 0xffffffcf)) |
               ((local_190 * 2 | 0xffffff9e) - (local_190 ^ 0xffffffcf)) - (int)local_32) < 0) {
        local_160 = 9;
      }
      else {
        local_160 = 0x29;
      }
      break;
    case 0x1e:
      local_160 = _1_main_flag_func_2((int)local_36,(local_190 | 2) * 2 - (local_190 ^ 2),0x15);
      break;
    case 0x20:
      puts("Correct!!");
      local_160 = 0x27;
      break;
    case 0x22:
      puts("Incorrect!!");
      local_160 = 0x27;
      break;
    case 0x24:
      puts("Incorrect!!");
      local_160 = 0x27;
      break;
    case 0x26:
      puts("Incorrect!!");
      local_160 = 0x27;
      break;
    case 0x28:
      if ((int)((int)local_38[0] - (local_190 - 1) | (local_190 - 1) - (int)local_38[0]) < 0) {
        local_160 = 0x2f;
      }
      else {
        local_160 = 0xb;
      }
      break;
    case 0x2a:
      if ((int)(((int)local_2a - ((local_190 * 2 | 0x1c) - (local_190 ^ 0xe)) ^
                (int)((int)local_2a - ((local_190 * 2 | 0x1c) - (local_190 ^ 0xe))) >> 0x1f) -
               ((int)((int)local_2a - ((local_190 * 2 | 0x1c) - (local_190 ^ 0xe))) >> 0x1f)) < 1) {
        local_160 = 3;
      }
      else {
        local_160 = 2;
      }
      break;
    case 0x2c:
      puts("Incorrect!!");
      local_160 = 0x27;
      break;
    case 0x2e:
      iVar2 = -((int)((((int)local_34 - (local_190 - 2) ^
                       (int)((int)local_34 - (local_190 - 2)) >> 0x1f) -
                      ((int)((int)local_34 - (local_190 - 2)) >> 0x1f)) + -1) >> 0x1f);
      local_160 = (long)(int)(uint)(iVar2 == 0) * 0x11 + (long)iVar2 * 0x31;
      break;
    case 0x30:
      if ((int)((int)local_28 - ((local_190 | 0x10) * 2 + (local_190 ^ 0xffffffef) + 1) |
               ((local_190 | 0x10) * 2 + (local_190 ^ 0xffffffef) + 1) - (int)local_28) < 0) {
        local_160 = 0x23;
      }
      else {
        local_160 = 6;
      }
      break;
    case 0x32:
      iVar2 = -((int)(((int)((int)local_25 -
                            ((local_190 * 2 & 0xffffff9e) + (local_190 ^ 0xffffffcf))) >> 0x1f ^
                      ((int)local_25 - ((local_190 * 2 & 0xffffff9e) + (local_190 ^ 0xffffffcf))) +
                      ((int)((int)local_25 -
                            ((local_190 * 2 & 0xffffff9e) + (local_190 ^ 0xffffffcf))) >> 0x1f)) - 1
                     ) >> 0x1f);
      local_160 = ((long)(int)(uint)(iVar2 == 0) * 0x1f & (long)iVar2 * 0x17) * 2 +
                  ((long)iVar2 * 0x17 ^ (long)(int)(uint)(iVar2 == 0) * 0x1f);
    }
  } while( true );
}
```

正解の特徴的な文字　"Correct!!"　を使って，angr する。
コードは作問者writeup

https://feneshi.co/ctf4b2021writeup/#be_angry

実行結果

```
# workon angr
(angr) ~# python3 be_angry.py 
WARNING | 2021-05-26 20:07:00,429 | cle.loader | The main binary is a position-independent executable. It is being loaded with a base address of 0x400000.
ctf4b{3nc0d3_4r1thm3t1c}
(angr) ~# deactivate
# 
```

すごいな。 angr