BOF redhat 원정대 golem -> darkknight
darkknight, darkknight.c
코드를 보면 메인함수에서 argv[1]의 주소를 인자로 problem_child함수를 호출한다.
problem_child함수에서는 arv[1]에서 41바이트 만큼을 버퍼로 덮는다. problem_child함수에서 지역변수로 버퍼를 40바이트 잡아 주었기 때문에 41바이트를 복사하면 SFP의 1바이트를 덮을 수 있다.
SFP는 이전에 ebp를 백업해 두는 곳이다 SFP를 조작함으로 우리는 콜러인 메인함수의 스택의 위치를 조작 할 수 있다.
main과 problem_child의 어셈블리어다.
main, problem_child 모두 코드의 상단과 하단에 push ebp, mov ebp, esp, leave, ret를 찾아 볼 수 있다.
이는 함수가 스택을 독립적으로 사용하도록 느끼게 해주는 코드이다.
push ebp, mov ebp, esp는 함수의 코드 시작전에 스택을 초기화 해주는 코드이고 leave, ret은 콜러의 스택으로 복귀할 수 있도록 해주는 함수이다.
*함수의 호출과 복귀시 메모리의 상태에 대한 포스팅 : prologue, leave, ret
이번 공격에서는 SFP를 조작하여 eip의 흐름에 있는 leave와 ret에 대한 스택을 이용하여 공격을 할 것이다.
strncpy 함수의 실행 전,후의 메모리를 보고 페이로드를 작성해 보자.
(r `python -c 'print "A"*41'`)
메모리를 보면 버퍼에 A가 40개 들어가 있고 SFP의 한바이트가 A로 덮어진것을 볼 수 있다.
problem_child함수의 leave가 수행될 때 ebp는 한바이트가 A로 덮여진 SFP다. leave가 실행되면 ebp가 0xbffffa41을 가리키게되고 RET가 실행되면 eip가 0x0804849e(call problem_child의 다음 코드)를 가리킨다.
다음에 실행될 코드는 메인함수의 leave, ret이다. leave를 실행하고 나면 A로 덮여진 SFP의 주소에서 4바이트를 내려간 곳이 RET가 된다. 나는 SFP의 한 바이트를 조작하여 ebp가 0xbffffac4를 가리키게 하고 8바이트 뒤에 A가 들어있는 곳에 쉘코드를 넣고 RET를 쉘코드가 들어 있는 주소로 이동시켜 공격을 할 것이다. 이렇게 되면 메인함수의 RET가 실행되면서 eip를 쉘코드가 있는 곳으로 보낼 수 있다.
페이로드의 구성은
[ 버퍼 ][PC_SFP(4)][PC_RET(4)]......[MAIN_SFP][MAIN_RET]
[[dummy(4)][RET(4)][쉘코드(24)][dummy(8)][0xc4(1)]]
0xc4에 의해서 problem_child의 SFP가 변조되서 dummy부분에 esp, ebp가 오게된다.
이 상태에서 메인함수의 leave, ret이 실행되면 dummy다음에 RET의 주소로 eip가 튀어 쉘코드가 실행된다.
*의미없는 ebp, esp의 이동을 설명하지 않았다.
공격을 해보면
쉘을 얻을 수 있다.
쉘코드 :
./darkknight `python -c 'print "AAAA" + "\xcc\xfa\xff\xbf" + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80" +"AAAAAAAA"+ "\xc4"'`
Categories
- programming (17)
- security (46)
- study (22)
- system (35)
Recent 7 Days Popular Posts
-
프로그램은 실행하면서 많은 함수를 호출한다. 함수가 호출되고 호출받은 함수가 실행되려면 레지스터와 스택을 사용해야 한다. 버퍼오버플로우 공격을 공부하면서 호출된 함수가 어떻게 esp (스택을 관리하는 레지스터)를 백업하는지 어떻게 스택을 독립적으로 ...
-
$(HOME)/.gdbinit을 생성하면 gdb가 실행될 때 .gdbinit을 불러옴으로 스크립트를 적용시킬 수 있다. ARM 어셈을 처음다루어 라인바이라인으로 분석해 보기위해 몇 가지 스크립트를 작성하였다. .gdbinit ...
-
UBUNUT SSH 서버에 접속 시도를 하면 로그인이 성공하기 전에 뜨는 배너와 로그인이 성공한 후에 뜨는 메세지가 있다. id, pw를 입력하기 전에 뜨는 배너는 디폴트 값으로 /etc/issue.net 을 읽어온다. issue.net 안...
-
라이브러리 로딩 - ld.so.conf 라이브러리란 무엇인가? 프로그램에서 공통으로 사용할 수 있는 기능을 포함하고 있는 오브젝트 파일이다. 동적 라이브러리란 무엇인가? 프로그램을 컴파일하여 생성되는 바이너리에 포함하지 않고 바이너리가...
-
Calling Convection 함수호출규약 은 함수(subroutine, callee)가 어떻게 인자를 전달받고 결과값을 반환하는지에 대한 로우레벨에서의 규칙이다. 다양하게 구현된 함수호출규약들은 파라미터의 위치, 리턴 값이나 리턴 ...
0 개의 댓글:
댓글 쓰기