level 8에서 얻은 패스워드를 사용해 level 9 계정으로 로그인해보면 hint 파일만 존재하는 것을 볼 수 있다. cat 명령어로 hint 파일을 읽어보면 /usr/bin/bof 프로그램의 소스 코드가 출력되고 이를 이용해 level10의 권한을 얻으라는 문구가 출력된다.
/usr/bin/bof 파일을 ls -al 명령어로 확인해보면 level10 권한으로 setuid가 걸려있는 것을 볼 수 있다. 이 프로그램의 취약점을 찾아 level10 권한으로 쉘을 얻는다면 level10 계정의 패스워드를 얻을 수 있을 것이다.
먼저 소스코드를 살펴보겠다.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
main(){
char buf2[10];
char buf[10];
printf("It can be overflow : ");
fgets(buf,40,stdin);
if ( strncmp(buf2, "go", 2) == 0 )
{
printf("Good Skill!\n");
setreuid( 3010, 3010 );
system("/bin/bash");
}
}
10byte의 char형 배열 buf2와 buf를 선언한 후 fgets를 통해 buf에 40byte만큼 입력을 받는다.(buf의 크기는 10인데 40byte만큼 입력 받으므로 bof 발생)
그 후 strncmp를 통해 buf2와 "go"를 2byte만큼 비교한 후 같다면 쉘을 얻게 해준다.
fgets함수에서 buf를 통한 buffer overflow 취약점이 발생하니, 이를 이용해 buf2의 값을 "go"로 바꿔준다면 쉘을 얻을 수 있을 것이다.
일단 buf와 buf2 주소간의 차이를 알아야하므로 gdb를 통해 확인해봐야한다. /usr/bin/bof 파일의 경우 권한이 안 맞아 디버깅이 불가능하므로 hint 파일에 나와있었던 소스 코드를 그대로 복사해와서 tmp 폴더 내에서 gcc를 이용해 문제 파일 사본을 하나 만들었다.
buf, buf2의 주소는 각각 fgets, strncmp 함수를 호출하는 부분에 bp를 걸고 스택을 확인해서 얻었다.(변수의 주소가 인자로 전달되기 때문에 스택에 존재한다.)
계산기를 통해 두 주소의 차를 구해보면 0x10(16byte)인 것을 알 수 있다. 따라서 16byte만큼 더미 값으로 채워주고 "go"를 넣어주면 된다.
ftz에서는 pwntools를 사용할 수 없으므로 python -c를 이용해서 exploit 하겠다.
# exploit command
(python -c "print 'A'*16+'go'"; cat) | /usr/bin/bof
더미 값으로 "A"를 16byte만큼 입력한 후 "go"를 입력해준다. exploit에 성공한다면 쉘 명령어를 입력해야하므로 ; cat으로 bof 프로그램이 끝나지 않도록 했다. 그 후 |(파이프)를 이용해 python 코드의 결과 값을 /usr/bin/bof 파일을 실행한 후 입력되도록 했다.
'Wargame > FTZ' 카테고리의 다른 글
[FTZ] Level 11 (0) | 2021.05.28 |
---|---|
[FTZ] Level 10 (0) | 2021.05.28 |
[FTZ] Level 6 ~ Level 8 (0) | 2021.03.28 |
[FTZ] Level 1 ~ Level 5 (0) | 2021.03.27 |
FTZ Training (1) | 2021.03.10 |