본문 바로가기

시스템

[시스템] 쉘코드를 작성해보자. [2]

저번시간에 이어서 setreuid를 이용해 root권한 획득과 exit(0)를 이용해 프로그램이 정상적인 종료가 되도록 만들어 보자.

 

먼저 root권한 획득에 대해 알아보자.

 

sh03실행파일의 소유자와 실행권한이 각각 hd, 755인 것을 확인할 수 있다.

chown명령어를 이용해 소유자를 root로 변경하고 chmod명령어를 이용해 파일에 대한 권한을 4755로 변경한다.

4755은 setuid bit를 설정하는 것을 의미한다. 원래의 8진수 퍼미션 설정에 4를 붙여 설정할 수 있으며, 4755로 변경시 실행권한이 -rwsr-xr-x로 변경된다. 이를 통해 실행시킨 사용자의 권한이 아닌 소유자의 권한으로 파일을 실행할 수 있게 된다.

 

설정을 마쳤다면 쉘코드를 통해 root권한 획득이 되는지 확인해보자.

setuid를 붙였음에도 불구하고 여전히 root권한을 획득하지 못한 것을 확인할 수 있다. 이는 root 소유의 프로그램의 권한을 그대로 상속받지 못했기 때문이다. 이는 root권한에서 setuid명령어를 사용해 RUID, EUID를 변경하더라도 파일을 실행할 때의 권한(RUID)이 일반 사용자이기 때문에 프로그램의 권한을 그대로 상속받지 못하는 것이라고 생각한다.

 

따라서 우리는 쉘코드 수정을 통해 사용자의 권한을 그대로 내려받을 수 있도록 만들어주어야 한다.

기존에 작성한 쉘 실행 프로그램에 setreuid()을 추가해 프로그램 소유자의 권한을 얻어올 수 있다.

 

쉘코드를 수정한 후 마찬가지로 소유자와 실행권한을 변경해준다.

uid가 root로 바뀐 것을 확인할 수 있다.

 

그다음 쉘코드를 얻기위해 Static Link Library형태로 다시 컴파일한 후 NULL을 제거하고 그에 대응하는 기계어코드를 얻어야 한다. 그에 대한 방법은 이전 포스팅을 참고하길 바란다.

추가적으로 setreuid의 system call number는 70번이며 cat /usr/include/asm/unistd_32.h명령어를 통해 확인할 수 있다.

 

따라서 setreuid(0,0);에 해당하는 기계어코드는 다음과 같다.

"\x31\xc0"

"\x31\xdb"

"\xb0\x46"

"\xcd\x80"

 

기계어 코드를 전 포스팅에서 만든 쉘코드의 앞부분에 추가해주기만 하면 된다. 추가한 쉘코드는 다음과 같다.

"\x31\xc0\x31\xdb\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"

 

프로그램이 정상적으로 종료되지 않아 에러메세지가 로그파일에 남거나 관리자에게 전달될 수도 있기때문에 overflow 공격 수행 후 프로그램의 정상적인 종료를 위해 exit(0)도 추가해주자.

exit(0);에 해당하는 기계어코드는 다음과 같다.

"\x31\xc0\xb0\x01\xcd\x80"

 

"\x31\xc0\x31\xdb\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\xb0\x01\xcd\x80"

이로써 최종적인 쉘코드가 완성되었다.

 

완성된 쉘코드가 정상적으로 작동하는지 테스트해보자.

 

쉘코드에 setreuid()와 exit(0)에 대응하는 쉘코드를 추가하여 기존의 쉘코드를 수정한다.

 

정상적으로 실행되는 것을 확인할 수 있다.

반응형