Dreamhack(pwnable) - sint
oolongeya
·2021. 9. 1. 18:45
sint.c
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
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);
}
void get_shell()
{
system("/bin/sh");
}
int main()
{
char buf[256];
int size;
initialize();
signal(SIGSEGV, get_shell);
printf("Size: ");
scanf("%d", &size);
if (size > 256 || size < 0)
{
printf("Buffer Overflow!\n");
exit(0);
}
printf("Data: ");
read(0, buf, size - 1);
return 0;
}
|
cs |
파일은 32비트 ELF 파일이다.
get_shell() 함수를 실행하는 것이 목적이다. get_shell() 함수는 system("/bin/sh"); 코드가 있는데, 쉘을 실행하는 것이다. 따라서 get_shell() 함수를 실행할 수 있다면 플래그를 얻을 수 있다.
char buf[256], size 순서대로 변수가 선언되고, signal(SIGSEGV, get_shell) 코드가 보인다.
Size의 값을 먼저 input으로 받는데, 이때 size의 값이 256보다 크거나 0보다 작으면 Buffer Overflow!\n를 출력한다
exit(0); 문이 있는 것으로 보아 이 조건문이 참이 되면 안되는 것이다.
input값을 다르게 했더니 위와 같이 나왔다.
그렇다면 get_shell의 주소를 확인한 뒤 size에서 ret까지의 거리를 계산해서 페이로드를 작성하면 되는걸까?
하지만 size 변수의 input을 받은 뒤 바로 뒤 조건문 있으니 긴 코드로 ret에 원하는 주소를 넣을 수 없다.
즉 패턴을 만들어서 확인할 수가 없기때문에 직접 메인함수의 assembly 코드를 보자.
0x104 바이트를 sub하는 것을 확인할 수 있다.
ret - sfp(ebp) - buf 순으로 쌓여있을 것이니,
0x104(바이트) + sfp(4바이트) => ret값
0x104는 10진수로 260이다 즉 264바이트 패딩 이후 ret값에 들어가고 여기에 get_shell() 함수의 주소가 들어가면 된다.
하지만! 이 값은 조건문에 걸려버린다. 중간 조건문에 걸리면 프로그램이 종료가 되니 조건문을 무조건 지나야한다.
즉 size에 알맞은 값을 넣어서 조건문을 통과한 뒤 read 함수 부분에서 승부를 봐야 한다.
read(0, buf, size - 1);
위와 같은 read 함수는 무엇을 의미하냐면,
size - 1 만큼의 크기를 파일에서 읽어서 buf에 저장한다고 생각하면된다.
size - 1 부분은 파일에서 얼마를 읽을지 적는 부분이다. 이때 원래 파일의 크기보다 더 크게 적게되면 파일의 내용 전부를 저장할 수 있게된다.
하지만 size의 값은 256보다 크거나 0보다 작아선 안된다.
따라서 size의 값은 0이다.
0은 조건문에 걸리지않지만 0-1의 경우 FFFF FFFF FFFF FFFF 가 되어버린다. 이 정도 크기면 엄청나게 큰 수이고,
read 함수에서 사용하면 파일의 모든 정보를 읽을 수 있을 것이다.
따라서 첫 번째 input에서 0을 입력하고 두 번째 input에서 패딩값 + get_shell() 함수 주소로 페이로드를 구성할 수 있다.
get_shell 함수의 주소를 확인한다.
얻은 정보들과 내용으로 작성한 코드이다.
실행하면
성공적으로 플래그를 얻을 수 있다.
'시스템 해킹 (Pwnable) > Wargame' 카테고리의 다른 글
Protostar - Format 0 (포맷 스트링 버그 + 버퍼 오버플로우) (0) | 2021.09.23 |
---|---|
Protostar - Stack 7 (쉘 코드 + 버퍼 오버플로우 + RTL) (0) | 2021.09.12 |
Protostar - Stack 6 (쉘 코드 + 버퍼 오버플로우 + RTL) (0) | 2021.09.01 |
Protostar - Stack 5 (쉘 코드 + 버퍼 오버플로우 + attach) (0) | 2021.08.28 |
Protostar - Stack 4 (버퍼 오버플로우 공격 + 메모리 참조) (0) | 2021.08.25 |