level 11
지금까지 제일 많이 헤매기도 했고 다소 난해하다고 느꼈습니다.
스택 영역이 모두 막혔으니 스택 다음인 공유 라이브러리를 이용해야한다는 것을 유추하는데에는 시간이 별로 안걸렸습니다.
하지만 공유 라이브러리를 어떻게 사용해야 쉘이 떨어지는지 알아내는데에 많은 구글링이 필요했습니다.
결론은 LD_PRELOAD 환경변수를 이용하면 됩니다.
LD_PRELOAD란 프로그램이 실행하기 위해 공유 라이브러리에서 실행에 필요한 함수를 가지고있는 라이브러리를 메모리에 할당하게 되는데, 이 할당되는 라이브러리보다 먼저 할당되는 것이 LD_PRELOAD의 값입니다.
이 값으로는 주로 직접 작성한 라이브러리가 저장되며, 실제 프로그램에서 쓰이는 함수들을 오버라이딩 할 수 있습니다.
후킹 용도로 사용되며, 후킹이란 함수 호출, 메세지, 이벤트 등을 중간에서 가로채 자신이 원하는 방향으로 흘러가게 재수정해 프로그램을 실행하는 것을 뜻합니다.
또한, User - Kernel - Net Card 과정을 거치지 않고 바로 User buffer에서 전송될 수 있어 zero copy에 들어가는 기술 중 하나가 후킹이라고 하네요.
여러모로 유용한 환경변수라고 합니다.
메모리에는 이름만 올라가기에 LD_PRELOAD 값으로 쉘코드를 집어넣을 겁니다.
먼저 아무런 내용없는 파일 a.c를 만듭니다.
이제 컴파일을 할건데 여기서 중요한 점은 공유 라이브러리 파일로 컴파일을 하기 위해서는 -fPIC 옵션과 -shared 옵션을 줘야합니다.
이렇게 컴파일 해주었습니다.
파일 이름은 다음과 같습니다.
"\x90"*50 + "\x31\xc0\x50\xb8\x2e\x2e\x73\x68\x04\x01\x80\xc4\x01\x50\x31\xc0\xb8\x2e\x62\x69\x6e\x83\xc0\x01\x50\x89\xe3\x31\xc0\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"
이제 LD_PRELOAD 값으로 위 파일 이름을 넣겠습니다.
여기서 중요한 점은 위 파일의 절대 경로를 앞에 붙여 같이 넣어야한다는 점입니다.
별문제없이 id 명령어가 잘 처리되네요.
id 명령어 또한 프로그램이기에 LD_PRELOAD를 먼저 메모리상에 올리게됩니다.
하지만 지금 만든 LD_PRELOAD 값의 공유 라이브러리는 아무런 기능도 하지 않으므로 티가 나지않는 것입니다.
이제 LD_PRELOAD의 위치를 찾아봅시다.
golem 파일을 gl이라는 이름으로 복사했습니다.
이제 디버깅을 통해 LD_PRELOAD의 위치를 찾아보겠습니다.
찾았네요.
위치는 0xbffff60f부터입니다.
저는 쉽게 0xbffff610을 선택하겠습니다.
payload를 작성하겠습니다.
"A"*44 + "\x10\xf6\xff\xbf"
성공!