Gloem의 소스를 먼저 보겠습니다.

코드에 변경점이 좀 있네요.

Egghunter가 사라졌으니 환경변수를 입력 가능합니다.

그리고 프로그램 종료 전에 buffer부터 0xbffffffff까지 ret주소가 들어있는부분을 제외하고는 전부다 0으로 초기화 하네요.

즉 매개변수, 버퍼, 환경변수 다 사용 불가능하다는 얘기 같습니다.

 

그럼 저희가 쉘코드를 넣을수 있는 위치는 buffer 아랫부분에 있는 메모리 영역입니다.

Code, data, bss영역은 코드 컴파일시에 결정이 나고, heap영역은 동적할당으로 잡히는 영역이니 프로그램 실행시에 저희가 임의로 값을 넣어줄 수는 없습니다.

 

그럼 할수 있는 방법이 무엇이 있을 까요?

 

여기서 잠시 생각해 봐야 하는 것은 프로그램이 동작할때 메모리에 실행한 프로그램만 로드하는 것이 아니라는 것입니다. 프로그램 내부에서 사용하는 함수들도 실행을 해야하니 전부 메모리에 로드를 해야곘죠.

 

일반적으로 내부 함수들은 외부 라이브러리에 존재하기때문에 다른 메모리 영역에 존재합니다.

프로그램에서 사용하고 있는 memset이나 strcpy등 다른 함수들은 다 메모리 중 저 위치에 로드가 되어 있는 것입니다.

그래서 실행시에 저기서 가져오게 되는 것이죠.

 

그럼 여기에 등록이 되어 있지 않은 다른 임의 함수를 추가해서 사용할 때는 어떻게 될까요?

메모리 상에 로드를 해야 실행을 할 수 있을테니 프로그램 동작시에 사전에 메모리에 로드하게 될것입니다.

이러기 위한 환경변수가 리눅스에 존재 합니다.

바로 LD_PRELOAD이죠. LD_PRELOAD 환경변수에 파일을 등록 하면 프로그램이 메모리에 로드 되기 전에 환경변수에 등록한 파일을 먼저 메모리에 로드하게 됩니다.

 

그리고 이전 문제에서의 기억을 되짚어 보면 프로그램의 해당 메모리 영역의 끝부분에는 해당 프로그램의 이름이 올라가 있습니다.

 

, 만약 LD_PRELOAD 환경변수에 AA라는 이름의 파일을 등록하고 프로그램을 실행하면 프로그램의 스택 아래쪽에는 AA라는 이름의 파일의 코드가 등록이 되고 그 파일의 이름 또한 스택에 존재하겠죠.

 

코드상에서 0으로 초기화 하는것은 buffer부터 0xbfffffff까지 이므로 LD_PRELOAD로 메모리에 로드한 영역은 초기화 되지 않습니다.

 

이 방법을 이용해 이번 문제를 풀면 됩니다.

 

우선 아무런 동작을 하지 않는 파일을 하나 만들어 쉘코드 이름으로 컴파일 해주도록 하곘습니다.

shared object를 컴파일 하기 위한 명령어는 gcc –fPIC –shared입니다.

 

이제 환경변수 LD_PRELOAD에 이 파일을 등록해 주면 됩니다.

정상적으로 쉘코드를 이름으로 하고 있는 파일이 LD_PRELOAD에 등록이 되었네요.

 

이제 gdb를 통해 이 이름의 위치를 확인하도록 하겠습니다.

golem의 메모리 영역보다 아래쪽에 있을테니 esp-3000부터 확인하도록 하겠습니다.



NOP 슬라이드와 쉘코드가 메모리에 적재되어 있는것이 보이네요. Ret 주소에 대략 0xbffff5a0쯤 넣어주면 될것 같습니다.

 

쉘이 떳네요.

 

이제 원본 파일을 대상으로 공격하도록 하겠습니다.

golem의 쉘을 획득 하였네요.

golem의 패스워드는 cup of coffee라고 합니다.

+ Recent posts