2017. 5. 23. 14:04ㆍSystemHacking/FTZ
5번문제는 레이스 컨디션에 대한 문제입니다 5번문제에 앞서 알아두어야할 개념입니다 ! *중요
[1] 레이스 컨디션이란 무엇인가 ?
Race Condition, 경쟁 상태 입니다. 무엇을 경쟁하는가 ?
다수의 프로세스가 동시에 실행하는 과정사이에서 어떤 프로세스가 먼저 실행되는지 경쟁한다
여러가지의 경쟁상태가 존재하는데 이번 문제에서는 파일의 소유를 경쟁하는 상황이다
[2] 심볼릭링크를이용한해킹
- 원리 : 심볼릭링크를 수정하면 원본파일도 수정된다
- root가 /etc/passwd 파일의 심볼릭링크(/tmp/pass)를만든다 ( /tmp/pass -> /etc/passwd )
- /tmp/pass를 수정하면 /etc/passwd 가 수정된다. ( 허가권의제한이통과된다면 )
setUID가 걸린 " rc "라는 프로그램이 있다고 하자
이 프로그램은 실행될 때 /tmp/hi 라는 임시파일을 만든다면, 이때 심볼릭링크를 이용한 해킹이 가능하다
rc 실행 => /tmp/hi 임시파일 생성
rc 에는 setUID가 걸려잇으므로 실행되는 동안에는 root권한을 가진다
/tmp/hi 파일을 삭제하고 /etc/passwd 의 심볼릭링크파일로 /tmp/hi 를 생성하고 rc 를 다시 실행시킨다
rc 실행중에는 root권한을 가지므로 /tmp/hi 파일을 수정함으로써 /etc/passwd 를 수정할 수 있다
[3] Race Condition
A프로그램 진행과정
[1] 파일을 생성한다
[2] 파일이 생성됫으면 생성된 파일에 내용을 입력한다
[3] 쓴 내용을 읽어들여 사용한다
[4] 해당 파일을 삭제한다
여기에 B프로그램을 추가해서 서로 경쟁시키는 것이다. 방법은 다음과 같다
(1) A-[2]번에서 파일이 생성되기 전에 B가 A-[2]과정에서 생성되는 임시파일과 동일한 이름의 임시파일을 생성
그 파일의 심볼릭링크파일을 생성하고 임시파일은 삭제한다 그러면 심볼릭링크파일만 남게된다
(2) A-[2]가 실행되서 파일을 생성하면 링크는 다시 연결되고 내용을 입력하면 심볼릭링크파일에 똑같은 내용이 남음
(3) 해당파일을 삭제해도 심볼릭링크파일 내의 내용은 남아있다 => 공격 성공
* 하지만 A프로세스의 과정은 찰나에 이뤄지므로 [1]~[2] 사이의 순간을 포착하기 어렵다
* 따라서 반복문을 활용해서 프로세스를 실행함으로써 경쟁상태를 만들어 공격을 시도한다
이제 level5 문제풀이를 시작하겠습니다. 먼저 힌트파일을 열어 봅시다 !
< 그림 5.1 >
" /usr/bin/level5 프로그램이 level5.tmp 라는 임시파일을 생성한다 " 즉, level5.tmp 파일을 생성하고 다시 삭제한다라는 뜻
결론적으로 level5.tmp파일에 심볼릭링크를 만드는 공격을 시도하면 되는것이다
"/tmp" 디렉토리에서 직접 코드를 짜서 공격을 수행해야합니다
< 그림 5.2 >
[level5 @ftz level5]$ vi runlv5.c
=> /usr/bin/level5 프로그램을 반복 실행하는 코드입니다 - 그림 5.3
[level5 @ftz level5]$ vi lnlv5.c
=> 심볼릭링크파일을 생성하는 코드입니다 - 그림5.4
< 그림 5.3 >
runlv5.c 파일 소스코드 입니다
" & " 해당 옵션을 프로그램을 백그라운드로 실행시키는 옵션입니다
백그라운드에서 /usr/bin/level5 프로그램을 반복적으로 실행시키는 동안에 심볼릭 링크 생성프로그램을 실행시킨다
< 그림 5.4 >
lnlv5.c 파일 소스코드입니다
[1] /tmp/level5 임시파일에 링크를 걸어둘 원본파일을 생성합니다
system("touch /tmp/link.txt");
[2] 심볼릭링크 파일을 생성하는 반복코드
system("ln -s /tmp/link.txt /tmp/level5.tmp"); => link.txt 파일을 원본으로 하는 level5.tmp 임시파일생성한다
*** 두 소스코드에서 반복문을 사용하는 이유 ! ***
" /usr/bin/level5 " 프로그램의 실행과정중 임시파일을 생성하고 문자열을 입력하고 임시파일을 다시 삭제하는 과정은
매우 짧은 순간에 이루어지기떄문에 사용자가 직접 그 시간에 침투할 수 없습니다
따라서 두 프로그램을 반복적으로 실행시켜 해당 순간에 공격프로그램이 침투하게 경쟁을 벌이도록 한 것입니다
두 소스파일들을 컴파일 시킨 후 실행시켜보겠습니다
< 그림 5.5 >
한번 프로그램을 실행해도 공격에 성공못할 수가 있습니다
그럴때는 반복문을 수정해서 반복횟수를 늘려주던가, 프로그램을 여러번 실행시켜주면 됩니다
< 그림 5.6 >
ln: '/tmp/level5.tmp' : File exists 경고창이 출력되고 있습니다
" lnlv5 " 프로그램에서 심볼릭링크 파일 "/tmp/level5.tmp"를 생성하려고 하는데 이미 "usr/bin/level5"프로그램에서 생성해놓았기 때문에 심볼릭링크파일이 생성되지 않고 경고창이 출력되는 현상입니다
하지만 반복 실행시키면 "lnlv5"프로그램이 먼저 실행되어서 심볼릭링크파일을 먼저 생성하게 되는 순간이 올것입니다
level5.tmp 임시파일에 /tmp/link.txt 링크가 형성되었습니다 !
< 그림 5.7 >
두 프로그램들이 반복실행 되면서 " /usr/bin/level5 " 프로그램이 " /tmp/level5.tmp " 임시파일을 생성하는 과정 실행 전
" /tmp/lnlv5 " 프로그램이 먼저 심볼릭 링크파일 " /tmp/level5.tmp " 생성했기 때문에 임시파일에 입력한 문자열이
링크 파일에 그대로 남아 있음을 알 수 있습니다
위 과정들은 대략적으로 설명한 것이고 gdb로 직접 소스를 디버깅하면서 자세히 살펴보겠습니다
( gdb분석은 level6권한이므로 level6 쉘코드에서 실행합니다 ! )
< 그림 5.8 >
[1] Procedure Prelude
지역변수에 $0x08 만큼의 공간 할당
[2] <main+29>: call <creat>
fd = creat( "파일명" , "권한"); // 파일생성에 성공하면 파일디스크립터 반환 , 실패시 -1 반환
fd = creat( "/tmp/level5.tmp" , $x180(384) ); => 해당파일의 권한은 384로써 /tmp/level5.tmp 파일을 생성
[3] <main+40>: cmpl // 파일이 생성되었는지의 여부
<main+44>: jns <main+88> 해당 조건에 걸리지 않는다면 Jump !
해당 조건에 걸린다면 그대로 코드를 진행한다
// 아래 코드의 흐름상 이미 파일이 존재하여서 파일이 생성되지 않은 경우임을 알 수 있다 ( fd < 0 )
[4] <main+54>: call <printf>
printf( "Can not create temporary file" );
[5] <main+65>: call <remove>
remove("/tmp/level5.tmp");
< 그림 5.9 >
<main+40> 에서 Jump해서 넘어왔다 => main+88 // 파일이 생성된 경우 ( fd > 0 )
[6] <main+91> ~ <main+101>
write( fd , "next password : what the hell\n" , $0x1f );
해당 파일디스크립터에 해당문자열을 $0x1f(31)byte크기만큼 전송 ( fd = /tmp/level5.tmp )
[7] <main+115>: call <close>
close(fd) or close("/tmp/level5.tmp");
[8] <main+131>: call <remove>
remove("/tmp/level5.tmp"); // 임시파일 삭제
gdb분석 결과를 바탕으로 소스코드를 복원하면 다음과 같습니다
이해가 어려울테니 복원된 소스코드를 보고 자세히 설명하겠습니다
< /usr/bin.level5 소스코드 >
#include<stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<fcntl.h>
int main(){
int fd;
char *pass = "next password : what the hell\n";
char *file = "/tmp/level5.tmp";
fd = creat( file , 0x180 ); // 임시파일 생성 ( 파일생성에 실패하면 fd = -1반환 )
if ( fd < 0 ){ // 파일생성에 실패했을 때 ( why? 이미 파일이 존재 )
printf( " Can not creat a temporary file.\n");
remove( file ); // 이미 존재하고 있는 /tmp/level5.tmp 삭제한다
exit(0); // 함수를 종료시킨다
}else{ // 임시파일 생성에 성공 !!
write( fd , pass , strlen(pass) ); // 임시파일에 문자열 입력
close(fd); // 파일디스크립터 닫아준다
remove(file); // 임시파일은 삭제시킨다
}
return 0;
}
" /usr/bin/level5 "실행파일 동작과정은 다음과 같습니다
[1] 임시파일이 존재하는지 아닌지 확인한다
[2] 존재하지 않다면 생성하고, 존재한다면 파일을 삭제한 후 프로그램 종료
[3] 파일이 생성됫으면 문자열을 입력하고 다시 삭제한 후 프로그램 종료
" /lnlink "실행파일 동작과정은 다음과 같습니다
[1] 원본파일 "/tmp/link.txt"을 생성합니다
[2] 해당 파일에 심볼릭링크를 걸어줍니다 ( /tmp/level5.tmp -> /tmp/link.txt )
[3] 임시파일 /tmp/level5.tmp 를 삭제합니다
## 실제로 실행시킨 동작 과정 ##
두 프로그램을 반복 실행 시켜서 "lnlink" 프로그램이 취약점을 공격했습니다 그 취약점은 무엇인가?
"/usr/bin/level5" 프로그램이 파일을 생성하기 전에 임시파일과 같은 이름이 심볼릭링크파일을 생성하고 다시 삭제한다
그 이후 아무일 없다는 듯이 "/usr/bin/level5" 프로그램은 임시파일이 존재 하지 않으므로 임시파일을 생성할 것이고
해당 파일에 문자열을 입력하고 임시파일을 삭제함으로써 프로그램을 종료할 것입니다
하지만! 임시파일이 생성될때 끈어져있던 원본파일 "/tmp/link.txt" 과의 심볼릭링크가 다시 생성되었습니다
입력된 문자열은 "/tmp/link.txt" 파일에 그대로 적혀있습니다
이상 Race Condition 에서 심볼릭링크를 이용한 해킹법이였습니다
추가로 ! 심볼릭 링크 공격법에 조건이 4가지 있습니다
1. 해당 프로그램에 대한 해킹할 사용자의 권한으로 setUID가 걸려있어야 한다 ( 지금 문제에서는 필요없다 )
2. 프로그램 실행과정에서 어떤 임시파일을 생성해야 한다
3. 생성되는 임시파일의 이름과 위치를 알아야한다 ( 심볼릭링크를 걸어주기 위해서 )
4. 심볼릭링크파일이 생성되는 디렉토리에 쓰기 권한을 가지고 있어야 한다 ( 링크파일을 생성시켜야 하므로 )
문제풀이에서는 "lnlv5" 프로그램에서 임시파일을 삭제하는 소스가 없습니다
링크 연결 상태를 보기위해서 삭제하는 소스를 작성하지 않았습니다
삭제하는 소스를 추가하면 완벽한 해킹이 됩니다
부족한 점이나 이상한 부분이 있다면 댓글써주세요
'SystemHacking > FTZ' 카테고리의 다른 글
FTZ level7 암호화 (0) | 2017.05.23 |
---|---|
FTZ level6 시스템 인터럽트 ( System Interupt ) (0) | 2017.05.23 |
FTZ level4 xinetd백도어 (0) | 2017.05.23 |
FTZ level3 system함수의 위험성 (0) | 2017.05.23 |
FTZ level2 VI편집기의 고급기능 (0) | 2017.05.23 |