-
-
Save DGivney/5917914 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
section .text | |
global _start | |
_start: | |
xor eax, eax ; init eax 0 | |
xor ebx, ebx ; init ebx 0 | |
xor esi, esi ; init esi 0 | |
jmp _socket ; jmp to _socket | |
_socket_call: | |
mov al, 0x66 ; invoke SYS_SOCKET (kernel opcode 102) | |
inc byte bl ; increment bl (1=socket, 2=bind, 3=listen, 4=accept) | |
mov ecx, esp ; move address arguments struct into ecx | |
int 0x80 ; call SYS_SOCKET | |
jmp esi ; esi is loaded with a return address each call to _socket_call | |
_socket: | |
push byte 6 ; push 6 onto the stack (IPPROTO_TCP) | |
push byte 1 ; push 1 onto the stack (SOCK_STREAM) | |
push byte 2 ; push 2 onto the stack (PF_INET) | |
mov esi, _bind ; move address of _bind into ESI | |
jmp _socket_call ; jmp to _socket_call | |
_bind: | |
mov edi, eax ; move return value of SYS_SOCKET into edi (file descriptor for new socket, or -1 on error) | |
xor edx, edx ; init edx 0 | |
push dword edx ; end struct on stack (arguments get pushed in reverse order) | |
push word 0x6022 ; move 24610 dec onto stack | |
push word bx ; move 1 dec onto stack AF_FILE | |
mov ecx, esp ; move address of stack pointer into ecx | |
push byte 0x10 ; move 16 dec onto stack | |
push ecx ; push the address of arguments onto stack | |
push edi ; push the file descriptor onto stack | |
mov esi, _listen ; move address of _listen onto stack | |
jmp _socket_call ; jmp to _socket_call | |
_listen: | |
inc bl ; bl = 3 | |
push byte 0x01 ; move 1 onto stack (max queue length argument) | |
push edi ; push the file descriptor onto stack | |
mov esi, _accept ; move address of _accept onto stack | |
jmp _socket_call ; jmp to socket call | |
_accept: | |
push edx ; push 0 dec onto stack (address length argument) | |
push edx ; push 0 dec onto stack (address argument) | |
push edi ; push the file descriptor onto stack | |
mov esi, _fork ; move address of _fork onto stack | |
jmp _socket_call ; jmp to _socket_call | |
_fork: | |
mov esi, eax ; move return value of SYS_SOCKET into esi (file descriptor for accepted socket, or -1 on error) | |
mov al, 0x02 ; invoke SYS_FORK (kernel opcode 2) | |
int 0x80 ; call SYS_FORK | |
test eax, eax ; if return value of SYS_FORK in eax is zero we are in the child process | |
jz _write ; jmp in child process to _write | |
xor eax, eax ; init eax 0 | |
xor ebx, ebx ; init ebx 0 | |
mov bl, 0x02 ; move 2 dec in ebx lower bits | |
jmp _listen ; jmp in parent process to _listen | |
_write: | |
mov ebx, esi ; move file descriptor into ebx (accepted socket id) | |
push edx ; push 0 dec onto stack then push a bunch of ascii (http headers & reponse body) | |
push dword 0x0a0d3e31 ; [\n][\r]>1 | |
push dword 0x682f3c21 ; h/<! | |
push dword 0x64334e77 ; d3Nw | |
push dword 0x503e3168 ; P>1h | |
push dword 0x3c0a0d0a ; <[\n][\r][\n] | |
push dword 0x0d6c6d74 ; [\r]lmt | |
push dword 0x682f7478 ; h/tx | |
push dword 0x6574203a ; et : | |
push dword 0x65707954 ; epyT | |
push dword 0x2d746e65 ; -tne | |
push dword 0x746e6f43 ; tnoC | |
push dword 0x0a4b4f20 ; \nKO | |
push dword 0x30303220 ; 002 | |
push dword 0x302e312f ; 0.1/ | |
push dword 0x50545448 ; PTTH | |
mov al, 0x04 ; invoke SYS_WRITE (kernel opcode 4) | |
mov ecx, esp ; move address of stack arguments into ecx | |
mov dl, 64 ; move 64 dec into edx lower bits (length in bytes to write) | |
int 0x80 ; call SYS_WRITE | |
_close: | |
mov al, 6 ; invoke SYS_CLOSE (kernel opcode 6) | |
mov ebx, esi ; move esi into ebx (accepted socket file descriptor) | |
int 0x80 ; call SYS_CLOSE | |
mov al, 6 ; invoke SYS_CLOSE (kernel opcode 6) | |
mov ebx, edi ; move edi into ebx (new socket file descriptor) | |
int 0x80 ; call SYS_CLOSE | |
_exit: | |
mov eax, 0x01 ; invoke SYS_EXIT (kernel opcode 1) | |
xor ebx, ebx ; 0 errors | |
int 0x80 ; call SYS_EXIT |
Hi, I get the same bad strace result as @pcordes with invalid syscalls. I use 6.1.0-22-amd64 kernel on debian. I fixed the asm by changing :
- push word bx ; 1 AF_FILE
+ push word 0x02 ; 2 AF_INET
Then I use this Makefile :
.PHONY: all clean
all: httpd
clean:
rm -f httpd
httpd: httpd.o
ld -m elf_i386 -n -o httpd httpd.o
strip httpd
httpd.o: httpd.asm
yasm -f ELF httpd.asm
And I get a working 436 bytes x86 (32 bits) binary :
$ ls -l httpd
-rwxr-xr-x 1 ludolpif ludolpif 436 29 août 14:24 httpd
$ strace ./httpd
execve("./httpd", ["./httpd"], 0x7ffc46bb40f0 /* 48 vars */) = 0
[ Process PID=429633 runs in 32 bit mode. ]
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
bind(3, {sa_family=AF_INET, sin_port=htons(8800), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
listen(3, 1) = 0
accept(3, NULL, NULL) = 4
fork() = 429921
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=429921, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
listen(3, 1) = 0
accept(3, NULL, NULL
[waiting next connection]
On client side :
$ nc -v localhost 8800
localhost [127.0.0.1] 8800 (?) open
HTTP/1.0 200 OK
Content-Type: text/html
<h1>PwN3d!</h1>
^C
Remarks : this code send http reply right after TCP syn/ack, without waiting a http request like "GET /".
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@vinod-somebody You do, my friend. Just have to get the basics.
Read about basic linux system calls, basic calling convention, and basic assembly.