1 분 소요


문제

image-20211227182232312

  • RELRO - Partial RELRO
    • GOT Overwrite 가능
  • NX - Enable : 활성화
    • 쉘 코드 삽입 불가



소스코드

image-20211229015624369

  • initialize : 30초 시간제한 초과시 TIME OUT 메시지 출력하고 종료
  • get_shell : system 명령어로 /bin/sh 주소 출력
  • main
    • heap_buf에 0x80(128byte)만큼 메모리 공간을 만들어 heap_buf 포인터에 할당
    • stack_buf에 0x90(144byte)만큼 할당
    • initialize 실행
    • read 명령어로 heap_buf에 0x80(128byte)만큼 입력
    • sprintf 명령어로 heap_buf의 내용을 stack_buf에 출력
      • sprintf에 서식문자의 생략으로 인해 FSB 발생 가능
      • 또한, snprintf와 같이 사이즈를 지정하지 않았기 때문에 bof 또한 발생 가능
        • 예를들어 heap_buf에 저장된 값이 %255c라면 heap_buf에는 6개의 문자열인 “%255c”로 인식되겠지만 stack_buf에는 255byte로 인식되므로 이를 이용하자.
      • 즉, BOF 접근법과 FSB 접근법으로 해결할 수 있다.
    • printf로 stack_buf의 값을 “ECHO : “로 출력
  • FSB 접근법
    • printf_got 주소를 이용해 printf_got 주소에 get_shell 주소를 Overwrite
  • BOF 접근법
    • stack_buf의 주소값을 크기를 구해서 BUF와 SFP에 특정값을 채워넣고 RET 주소에 get_shell 주소를 덮어씌우자
    • 스택의 구조 : BUF + SFP(4byte) + RET(4byte)



KALI

FSB와 BOF 접근법을 모두 충족하기 위해

printf_got 주소와 get_shell 주소, stack_buf의 주소를 구해보자

image-20211229195137762

  • printf_got : 0x804a010


image-20211229195252190

  • get_shell : 0x8048669


image-20211229195428107

  • sprintf : 0x8048f0
  • stack_buf 의 크기 : ebp - 0x98
    • EBP 레지스터 : 하나의 스택프레임의 시작주소가 저장
  • 즉, stack_buf의 크기는 0x98(152byte)
  • BOF 접근법으로 적용해서 BUF와 SFP(4byte)를 더한 값인 156byte를 입력하여 stack_buf에 156byte로 인식되게 하고
  • RET(4byte) 주소에 get_shell 주소를 덮어씌우면 된다.



PAYLOAD

BOF

image-20211229201447791

  • pwn 모듈을 사용하기 위해 import
  • 문제의 서버로 원격접속 위해 remote 명령어 실행
  • get_shell 주소 선언
  • payload 값 적재
    • stack_buf에서 156byte로 인식되기 위해 %156c로 값을 입력해주고 나머지 4byte(RET)에
    • p32(리틀엔디안)식으로 get_shell 주소 입력


FSB

image-20211229203020553

  • pwn 모듈 사용 위해 import 해주고
  • 문제의 서버 원격접속 위해 remote 명령어 사용
  • printf_got에 get_shell 주소를 입력하기 위해 printf_got주소를 printf에 선언
  • payload 작성
    • 구조 : (printf_got) + (printf_got + 1) + (0x69 - 0x8) + (0x86 - 0x69)
    • 문제 002와 비교해서 got 주소의 위치가 바뀌었는데 (printf_got) + (printf_got +1)으로 바뀐 이유
      • get_shell 주소 0x8048669의 첫번째 1byte 0x69 에서 두번째 1byte 0x86을 뺼셈을 하기 위해 위치를 바꿔 줬다.
    • 첫 번째 인자 printf_got에 먼저 입력된 printf_got 주소 0x8 제외해야하기 때문에
      • 0x69 - 0x8 = 0x61(97byte)를 넣어주고 1byte(hhn)으로 구성해준다.
      • 1byte가 아닌 2byte로 구성해주게 되면 30,000byte가 넘는 값을 입력받게 되는데 소스코드의 sprintf를 거치면 stack_buf에는 0x90만 받아주기 때문에 segmentation fault가 발생되기 때문이다.
    • 두 번째 인자 printf_got + 1 에는 나머지 값인 0x86에서 0x69를 감산해준다.
      • 0x86 - 0x69 = 0x1D(29byte)를 넣어주고 마찬가지로 1byte(hhn)으로 구성해주면 된다.



결과

image-20211229204221872

  • DH{4e6e355c62249b2da3b566f0d575007e}

업데이트: