;================================================================================= ; sys_socketcall (SYS_SOCKET & SYS_SENDTO) demonstration. ; ; This is an example of sending data encapsulated within ICMP (echo_request) ; packets. ; To send a file: $ ./icmp [filename] [ip] ; To receive a file: $ ./icmp -s [filename] [ip] ; ; e.g. ; $ ./icmp -s out.file 127.0.0.1 & ; $ ./icmp in.file 127.0.0.1 ; ; ; The LSCR Project. ;================================================================================= format ELF include '../macros.inc' include '../../include/symbols.inc' include '../../include/structs.inc' extrn error_chk extrn dd2ascii_hex section '.text' executable public _start _start: pop eax cmp eax, 3 jb exit pop eax pop ebx cmp [ebx], word "-s" ; client or server ? je server_mode ;-------------------------------------------------------; CLIENT mode push ebx ; if it's not "-s" we are in client mode and it's a filename mov eax, SYS_WRITE mov ebx, STDOUT mov ecx, sending_s mov edx, sending_s_sz int 0x80 mov eax, SYS_OPEN ; open the file in read only mode pop ebx mov ecx, O_RDONLY int 0x80 mov [fd], eax ccall error_chk, <"SYS_OPEN has failed: ">, exit mov eax, SYS_FSTAT ; get file information (we are interested in file size) mov ebx, [fd] mov ecx, fstat int 0x80 ccall error_chk, <"SYS_FSTAT has failed: ">, close mov eax, SYS_BRK ; make space for the file data on the .bss xor ebx, ebx int 0x80 mov [bss_original], eax ccall error_chk, <"SYS_BRK has failed: ">, close mov ebx, [fstat.st_size] ; expand the .bss segment add ebx, eax mov eax, SYS_BRK int 0x80 ccall error_chk, <"SYS_BRK has failed: ">, close mov eax, SYS_READ ; read the file data mov ebx, [fd] mov ecx, [bss_original] mov edx, [fstat.st_size] int 0x80 mov [bytes_count], eax ccall error_chk, <"SYS_READ has failed: ">, close pop esi ; convert the IP address mov ecx, -1 next_digit: xor ebx, ebx @@: lodsb sub al, 0x30 jb @f imul ebx, 10 add bl, al jmp @b @@: inc ecx mov byte [_sockaddr_in.sin_addr+ecx], bl cmp ecx, 3 jng next_digit push 1 ; ICMP ; creat RAW socket push SOCK_RAW push PF_INET mov eax, SYS_SOCKETCALL mov ebx, SYS_SOCKET mov ecx, esp int 0x80 add esp, 12 ccall error_chk, <"SYS_SOCKETCALL has failed: ">, close mov ebp, eax mov [_sockaddr_in.sin_family], AF_INET ; finish filling the sockaddr_in structure mov [_sockaddr_in.sin_port], 0 mov esi, [bss_original] mov edi, esi add edi, [bytes_count] next_dword: ; encapsulate 4 bytes from the file and send lodsd mov [c_dat], eax cmp esi, edi jng send mov [c_dat], dword 10213243h ; mark the end in case we reached it send: xor eax, eax ; calculate checksum of ICMP packet mov ax, 0x0FFF7 sub ax, word [c_dat] sub ax, word [c_dat+2] mov [csum], ax push sizeof.sockaddr_in ; send the packet push _sockaddr_in push 0 push 8 push icmp_packet push ebp mov eax, SYS_SOCKETCALL mov ebx, SYS_SENDTO mov ecx, esp int 0x80 add esp, 24 ccall error_chk, <"SYS_SOCKETCALL has failed: ">, close @@: mov eax, SYS_NANOSLEEP ; pause so we wont make a flood mov ebx, delay xor ecx, ecx int 0x80 cmp eax, -EINTR je @b cmp esi, edi jng next_dword mov eax, SYS_WRITE mov ebx, STDOUT mov ecx, done_s mov edx, done_s_sz int 0x80 close: mov eax, SYS_CLOSE mov ebx, [fd] int 80h mov eax, SYS_CLOSE mov ebx, ebp int 80h exit: mov eax, SYS_EXIT xor ebx, ebx int 80h server_mode:;-------------------------------------------; SERVER mode pop dword [recv_fname] ; file name mov eax, SYS_WRITE mov ebx, STDOUT mov ecx, waiting_s mov edx, waiting_s_sz int 0x80 pop esi ; convert the IP address mov ecx, -1 next_digit2: xor ebx, ebx @@: lodsb sub al, 0x30 jb @f imul ebx, 10 add bl, al jmp @b @@: inc ecx mov byte [ip_cmp+ecx], bl cmp ecx, 3 jng next_digit2 mov esi, dword [ip_cmp] push 1 ; ICMP ; creat RAW socket push SOCK_RAW push PF_INET mov eax, SYS_SOCKETCALL mov ebx, SYS_SOCKET mov ecx, esp int 0x80 add esp, 12 mov ebp, eax mov eax, SYS_OPEN ; write the data to file and exit mov ebx, [recv_fname] lea ebx, [ebx] mov ecx, O_WRONLY or O_CREAT mov edx, S_IRUSR int 0x80 mov [fd], eax packet_read: ; wait for packets and save to buffer on arrival mov eax, SYS_READ mov ebx, ebp mov ecx, buffer mov edx, 28 int 80h cmp word [buffer+20], 0008h ; so we wont write the echo_reply when testing on loopback jne packet_read cmp [buffer+12], esi ; verify the source ip, so we won't log any 'external' ping`s jne packet_read cmp [buffer+24], 10213243h ; check whether we have reached the end jne @f mov eax, SYS_WRITE mov ebx, STDOUT mov ecx, done_s mov edx, done_s_sz int 80h jmp close @@: mov eax, SYS_WRITE mov ebx, [fd] mov ecx, buffer+24 mov edx, 4 int 80h jmp packet_read section '.data' writeable waiting_s db " Receiving the file...", 0xa waiting_s_sz = $-waiting_s sending_s db " Sending the file...", 0xa sending_s_sz = $-sending_s done_s db " Done.", 0xa done_s_sz = $-done_s delay dd 1, 0 ; wait for one second icmp_packet db 8, 0 csum dw 0 ; checksum c_dat dd 0 ; covert data bss_original rd 1 fd rd 1 recv_fname rd 1 bytes_count rd 1 ip_cmp rd 1 fstat stat _sockaddr_in sockaddr_in buffer rd 28/4