91 lines
1.6 KiB
Plaintext
91 lines
1.6 KiB
Plaintext
format ELF64 executable
|
|
include "arch/x86_64-linux.fasm"
|
|
|
|
PR_CAP_AMBIENT = 47
|
|
PR_CAP_AMBIENT_RAISE = 2
|
|
|
|
upstream:
|
|
db '/home/kaction/.nix-profile/bin/ls', 0
|
|
|
|
|
|
hdrp:
|
|
.version:
|
|
dd 0x20080522
|
|
.pid:
|
|
dd 0x0
|
|
|
|
datap:
|
|
.effective0:
|
|
rd 1
|
|
.permitted0:
|
|
rd 1
|
|
.inheritable0:
|
|
rd 1
|
|
.effective1:
|
|
rd 1
|
|
.permitted1:
|
|
rd 1
|
|
.inheritable1:
|
|
rd 1
|
|
|
|
do_prctl:
|
|
.repeat:
|
|
bsf edx, ebx ;; edx <- index of first set bit in ebx
|
|
jz .done ;; break if ebx is 0
|
|
btr ebx, edx ;; clear that bit in ebx
|
|
add rdx, r12
|
|
|
|
;; prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, edx)
|
|
;; %edx is third argument to syscall and it already
|
|
;; has value needed.
|
|
mov rax, SYS_prctl
|
|
mov rdi, PR_CAP_AMBIENT
|
|
mov rsi, PR_CAP_AMBIENT_RAISE
|
|
syscall
|
|
jmp .repeat
|
|
.done:
|
|
ret
|
|
|
|
|
|
entry $
|
|
mov rdi, hdrp
|
|
mov rsi, datap
|
|
mov rax, SYS_capget
|
|
syscall
|
|
|
|
mov eax, [datap.permitted0]
|
|
mov [datap.inheritable0], eax
|
|
mov [datap.effective0], eax
|
|
|
|
mov eax, [datap.permitted1]
|
|
mov [datap.inheritable1], eax
|
|
mov [datap.effective1], eax
|
|
|
|
mov rdi, hdrp
|
|
mov rsi, datap
|
|
mov rax, SYS_capset
|
|
syscall
|
|
|
|
xor r12, r12
|
|
mov ebx, [datap.inheritable0]
|
|
call do_prctl
|
|
|
|
mov r12, 32
|
|
mov ebx, [datap.inheritable1]
|
|
call do_prctl
|
|
|
|
mov r10, [rsp] ;; r10 := argc
|
|
mov qword rdi, upstream ;; rdi := upstream
|
|
lea rsi, [rsp + 8] ;; rsi := argv
|
|
mov qword [rsi], upstream ;; argv[0] := upstream. Makes busybox happy
|
|
lea rdx, [16 + 8 * r10 + rsp] ;; rdx := envp
|
|
mov rax, SYS_execve
|
|
syscall
|
|
|
|
;; This should not happen, but segfaulting if execve(2) failed is not
|
|
;; nice.
|
|
neg rax
|
|
mov rdi, rax
|
|
mov rax, SYS_exit
|
|
syscall
|