phpMyAdmin 4.8.1 - Local File Inclusion to Remote Code Execution - 2018

Silinen üye 7909

21.06.2018 tarihinde phpmyadmin 4.8.2 sürümü yayınlandı, sürüm notlarında bir " LFI " açığını ve xss açıklarının kapatıldığını söylediler bu konumuzda LFI açığı nasıl oluştu bu...

21.06.2018 tarihinde phpmyadmin 4.8.2 sürümü yayınlandı, sürüm notlarında bir " LFI " açığını ve xss açıklarının kapatıldığını söylediler bu konumuzda LFI açığı nasıl oluştu bu aşamalara bakacağız.
View hidden content is available for registered users!

PHP:
--index.php [50-63]
$target_blacklist = array (
'import.php', 'export.php'
);

// If we have a valid target, let's load that script instead
if (! empty($_REQUEST['target'])
&& is_string($_REQUEST['target'])
&& ! preg_match('/^index/', $_REQUEST['target'])
&& ! in_array($_REQUEST['target'], $target_blacklist)
&& Core::checkPageValidity($_REQUEST['target'])
) {
include $_REQUEST['target'];
exit;
}

satır 56,57,58'den kaçarak satır 59 geldiğimizde bir doğrulama fonksiyonuna gidiyoruz bu fonksiyona gittiğimizde ;

PHP:
libraries/classes/core.php [443-476]
public static function checkPageValidity(&$page, array $whitelist = [])
{
if (empty($whitelist)) {
$whitelist = self::$goto_whitelist;
}
if (! isset($page) || !is_string($page)) {
return false;
}

if (in_array($page, $whitelist)) {
return true;
}

$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}

$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}

return false;
}

fonksiyonuna geldiğinde aldığı parametrelerde $whitelistboş geldiği için içerisindeki
PHP:
libraries/classes/core.php [31-80]
public static $goto_whitelist = array(
'db_datadict.php',
'db_sql.php',
'db_events.php',
'db_export.php',
'db_importdocsql.php',
'db_multi_table_query.php',
'db_structure.php',
'db_import.php',
'db_operations.php',
'db_search.php',
'db_routines.php',
'export.php',
'import.php',
'index.php',
'pdf_pages.php',
'pdf_schema.php',
'server_binlog.php',
'server_collations.php',
'server_databases.php',
'server_engines.php',
'server_export.php',
'server_import.php',
'server_privileges.php',
'server_sql.php',
'server_status.php',
'server_status_advisor.php',
'server_status_monitor.php',
'server_status_queries.php',
'server_status_variables.php',
'server_variables.php',
'sql.php',
'tbl_addfield.php',
'tbl_change.php',
'tbl_create.php',
'tbl_import.php',
'tbl_indexes.php',
'tbl_sql.php',
'tbl_export.php',
'tbl_operations.php',
'tbl_structure.php',
'tbl_relation.php',
'tbl_replace.php',
'tbl_row_action.php',
'tbl_select.php',
'tbl_zoom_select.php',
'transformation_overview.php',
'transformation_wrapper.php',
'user_password.php',
);
bütün bunlara baktıktan sonra tekrardan index.php'nin satır 60 geldiğimizde Core::checkPageValidity($_REQUEST['target']) burayı true olarak döndürmemiz gerek böylelikle gönderdiğimiz url yapısını buna göre ayarlamamız gerek böylece include yerine ulaştığımızda istediğimiz ifadeyi include'ye göndermiş olacağız

onun öncesinde bir konuya daha değinmek istiyorum.

1.txt ve 2.txt aynı dizinde
include yaparken bir dosyayı ' 1.txt%3f./../2.txt ' böyle bir şekilde yapı gönderirseniz 2.txt''yi görecektir.
bunuda öğrendiğimize göre yapmamız gereken şey " guvenli.php%3f./istedigimiz-bir-dosya "

buraya kadar geldik şimdi yapmamız gereken tek şey o fonksiyonu true olarak atlatmak.
satır 445'ten 454'te kadar olan kısımları atlattık 453'teki true'yi alamayız çünkü güvenli listesine bizim göndereceğimiz dosya dahil edilmiyor bu durumda hemen gözümüze satır 463 çarpıyor, orada true olarak döndermek mümkün olduğunu biliyoruz ama döndermek için göndereceğimiz url yapısı bu şekilde olur " db_sql.php%3f./../../index/index.txt " iyi güzel bunu istiyorduk biz ama böyle gönderince tarayıcı bunu decode ettiği için include'ye düşen link yapısı bu olur ;

include(db_sql.php?./../../index/index.txt) ama biz bunu istemiyoruz amacımız include içine tamamen db_sql.php%3f sonu 3f ile bitecek şekilde yapı göndermek istiyoruz normal şartlarda bu olamaz olması için bizim bunu geriye %3f kalacak şekilde göndermemizdir

peki ama nasıl nasıl aşağıya ineceğiz diye diye düşünürken satır 466'da urldecode var hmm bu işimizi görür mü diye düşünelim
o sırada aklımıza hemen şey geliyor

urldecode ederken eğer biz geriye " % " asci tablosundaki değeri %25 olan bu karakter işimizi görecek

göndereceğimiz url yapısı böyle olacak ;
db_sql.php%253f./../../index/index.txt böylelikle urldecode edilince geriye oluşan link yapısında şunu dönderecek
db_sql.php%3f./../../index/index.txt kalın olarak işaretlediğim yer %25'in urldecodesinden geriye kalan yer
bu bize biraz şeyi çağrıştırdı bir xss filterlemesinde script ve src'leri siliyorlar str_replace ile ama böyle bi değer gidince ssrccripsrct içindeki src'ler silinince geriye script kalıyor bunun gibi bir şey oluyor neyse devam edelim biz.
artık kodumuz tamamlanmıştır göndermemiz gereken url'nin db_sql.php%253f ile başlaması gerektiğini çözdük satır 470'de yine ?'den öncesini alıp güvenli listede var mı yok mu doğrulamasında geçmiş oluyor ve geriye true dönderiyor

yani artık index.php olan alanda true aldık include yerine girdik ve include edeceğimiz değerimizin içinde %3f geçiyor

satırlı kodlar olarak görmek isterseniz ;

index.php
indexphp-jpg.7



Core.php

corephp-jpg.8




Açık fix için ;
https://github.com/phpmyadmin/phpmyadmin/commit/7662d02939fb3cf6f0d9ec32ac664401dcfe7490
 
131,843Konular
3,271,947Mesajlar
316,373Kullanıcılar
barisimSon Üye
Üst Alt