[*] Written in C and compiled it as assembly
[*] Strip away a few bits (e.g. set up for the stack frame)
which are pointless: exec is a no-return.
[*] Workarounds to remove two \x00 bytes that are
dissiminated in the current result.
[ ] Direct syscall to exec instead of jumping to libc
Compilation as by the makefile (also below).
The target is 32-bit linux (matching the CTF system), which needs
some extra packages for the build to work under 64-bit systems.
On OpenSUSE: glibc-32bit + gcc13-32bit
Since I'm acquiring expertise with radare2: dumping it can be an
interesting exercise:
> Assuming that `ret` was added to the code (or else r2 will be
somewhat confused on how to determine the end of the frame):
@@ -27,5 +27,6 @@ foo:
leal -16(%ebp), %eax
pushl %eax
call execl
+ ret
.size foo, .-foo
.section .note.GNU-stack,"",@progbits
> Check disassembly of result:
$ r2 -Aqc 'pdf @ sym.foo' ./shellcode.o
> Dump disassembly to a file:
$ r2 -Aqc 'pdf @ sym.foo' ./shellcode.o |
xxd -p -r - shellcode.bin
> Dump string representation
$ r2 -Aqc 'psx $FS - 1 @ sym.foo'
> Dump/disassemble in radare2
$ r2 -Aqc 'pdf sym.foo' ./shellcode.o
> Execution in radare2 via rarun2:
$ more rarun.rr2
stdio=/dev/pts/5
setenv=EGG=\x83\xec\x18\... # etc
$ r2 -r /tmp/.../rarun.rr2 ./narnia1
> https://lwn.net/Articles/604287/
The standard ABI for how x86_64 user programs invoke a system call is to
the system call number (0 for read) into the RAX register, and the other
parameters into specific registers (RDI, RSI, RDX for the first 3 paramet
then issue the SYSCALL instruction.
> sys_execve -> 59
RDI -> filename
RSI -> argv[]
RDX -> envp[]
> Some useful info gathered about assembly, on ##asm (Libera.chat)
Instructions such as "push %edx" is only available in 32 bit mode (gcc -m
This is because the 0x52 opcode that means "push edx" in 32 bit mode mean
"push rdx" in 64 bit mode.
Regardless of 32-bit or 64-bit mode, it is always possible to push a 16 b
value or register:
opcode 32 bit mode 64 bit mode
50 push eax push rax
6650 push ax push ax
> vDSO
Dynamically linked to executable. Use ldd(1) on the binary to
appreciate it.
The kernel links an ELF file. The name of it depends on the
architecture.
Common names are listed on vdso(7).
HTML Narnia 1 CTF (overthewire.org)
DIR ..
TEXT GNUmakefile 2024-Mar-14 14:29 0.1 KB
TEXT main.c 2024-Jul-11 19:10 0.1 KB
TEXT shellcode.S 2024-Jul-11 19:10 0.7 KB
__________________________________________________________________________
Gophered by Gophernicus/3.0.1 on FreeBSD/amd64 14.3