[*] 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). | |
Narnia 1 CTF (overthewire.org) | |
.. | |
GNUmakefile 2024-Mar-12 23:16 0.1 KB | |
main.c 2024-Apr-01 19:17 0.1 KB | |
shellcode.S 2024-Apr-24 19:41 0.7 KB | |
__________________________________________________________________________ | |
Gophered by Gophernicus/3.0.1 on FreeBSD/amd64 14.0 |