Перейти к содержимому

 Друзья: Всё для вебмастера | [ Реклама на форуме ]


Rutor
Rutor


[ DDos Услуги. DDos атака. Заказать ДДос ]


Socks5 изучение продолжается:BIND


  • Авторизуйтесь для ответа в теме
В этой теме нет ответов

#1
Jinn

Jinn

    Байт

  • Members
  • Pip
  • 77 сообщений
--:[ Название : Socks5 изучение продолжается:BIND  ]:--
--:[ Автор : Jinn, ZaeB.uS, ]]>http://zaeb.us]]>  ]:--

o--:[ 1 | Введение ]:--o

Вот решил написать еще одну статью на тему соксов, некоторые личности скажут:"Вот понаписал статей, мог бы все в одной изложить!", объясню мою точку зрения на данную проблему: я считаю, что если бы весь этот материал(с первой статьи по текущую) содержался в одной статье, то статья бы получилась довольно большой и сложной для понимания! В этот раз рассмотрим метод не connect как в прошлых статьях, а bind. Если вы первый раз читаете про соксы и не знакомы с этим протоколом, то желательно прочитать мои статьи:"Организация работы php скрипта через socks5 сервер","PHP + socks5(авторизация по методу username/password)", либо RFC. Как и в прошлые разы перечислю на чем я все это гонял,ничего не изменилось=):
* Win XP SP2
* Opera 8.52
* Денвер
* 3proxy-0.5.3i(ЗАРАЗА)

o--:[ 2 | Общие принципы ]:--o

Для тех кто не знаком что это такое отправлю в гугл и коротко обьясню=) Bind используется для открытия порта, а по теме этой статьи видно что мы рассматриваем сокс => открывать порт будем на стороне socks5-сервера. А для чего это нужно? Это может использоваться в соединениях, которые требуют открытия порта на стороне клиента(мы ведь прячемся за сокс, т.е для удаленного сервера клиентом является сокс), хорошим примером требующим открытия порта на стороне клиента является ftp. Я думаю многие видели вопросы на форумах типа: "Ftp клиент не работает с http проксей", после долгой дискуссии выяснялось, что хлопчик пытается подключиться к фтп серверу через http проксю в активном режиме. И соответствующий ответ: "Юзай пассивный режим!". А что же это такое активный и пассивный режим? Если кто изучал ftp протокол те знаю, что в нем используется 2 вида соединения: клиент--->сервер по которому идут команды клиента и сервер--->клиент:альтернативный порт, который используется для передачи результата команды клиента(ls,get,put). Но вот проблема: с htpps проксями же такое не пройдет... Мы ведь не можем открыть порт на стороне https прокси, а для передачи данных его открыть нужно. Именно поэтому при использовании прокси сервера и активного режима вы не получите листинг директории,etc. Тогда приходиться юзать пассивный режим, там все открытия порта происходят на стороне ftp-сервера, а клиент из-за прокси просто к ним подключается и получает ответы на команды =) Но в соксах все по другому, тут есть механизм открытия порта на стороне сокс сервера и называется он bind. Т.е при использовании сокса не нужно переходить в пассивный режим(хотя возможно :-), но нужно тоже постараться чтобы открыть порт на соксе, а именно изучить данную небольшую статью =)

o--:[ 3 | Реализуем BIND ]:--o

Для чего это нужно разобрались, перейдем к практике и попробуем написать работающие приложение :-)
По RFC предполагается, что bind будет использован только как вторичное соединение, после первого первичного установленного с помощью метода CONNECT, но мы в наших экспериментах нарушим предписания RFC.
Пакеты для бинда порта мы должны слать такие же как и для коннекта, но метод должен быть не connect(01) а bind(02)=). Снова показывать структуру пакета я не буду, если ты ее не знаешь читай статьи [1],[2]. На connect сокс сервером возвращается один ответ, в котором указан статус(ok/error) подключения, с bind'ом все сложнее, соксом предоставляется 2 ответа: первый приходит сразу же после запроса, в нем так же указан статус успешности открытия порта для входящего соединения,а также ip и порт выделенные соксом для входящего соединения, эта информация, в случае надобности, может быть предоставлена серверу-приложению через первичное соединение как адрес для взаимодействия. Возможно что ip будет отличаться от ip сокс сервера, т.к иногда подобные сервера имеют несколько адресов. Второй пакет приходит после внешнего подключения к забинденому порту, там содержится ip и порт подключившегося хоста и статус подключения(коды те же, 0-ok,etc). Эти данные могут быть использованы для решения о дальнейшем взаимодействии(напрмиер ip подключившегося хоста содержится в черных списках, тогда соединение может быть разорвано....но это все на ваше усмотрение)
В принципе никакой сложности это вызывать не должно, после того как мы забиндим порт и получим первый ответ сокса, перед получением данных от подключившегося клиента мы должны будем получить второй пакет и проверять его статус, далее же, если все в порядке, мы сможем получать, отправлять данные как и прежде методами php(fread,fgets,fwrite,feof).
Теперь собственно обсудим что мы будем кодить. Мы не будем работать с ftp и вот почему: в php существуют ф-ции ftp_connect, ftp_put, etc. Но при подключении сначала к соксу а потом попытке передачи через данный сокет файла данными методами определенными для работы с ftp компилятор php верещит, что сокет не подходит => воспользоваться встроенными ф-циями работы с ftp сервером нам не удастся и придется изучать и писать свой класс для работы по протоколу ftp, а это не так то просто и не входит в мои планы....пока=) Но ведь наша цель просто открыть на соксе порт, и получить оттуда отправленные сервером данные, поэтому мы поступим вот как:
 -- забиндим порт на соксе
 -- получим ответ сокса, со статусом открытия порта, ip и порт выделенный для входящих подключений
   [ Мы за сервер ]
	 -- теперь поработает за сервер и откроем подлючение не используя сокса(хм..хотя никто вам не мешает это сделать) с помощью fsockopen и выделенным адресом для входящего подключения
	 -- отправим туда произвольные данные 
	 -- закроем подключение
   [ сервер накрылся медным тазом ]
 -- теперь мы получим пакет от сокса, в котором указаны ip и порт подключившегося хоста(т.е нашего)
 -- опять получим данные, уже отправленные сервером(опять нами;-)
 -- закроем подлючение к соксу
 -- выведем все это пользователю

Этим примером мы проверим правильность понимания нами протокола, как мне кажется, данный пример полностью показывает все стороны bind'а, как клиентской стороны так и серверной :-)
Обсудим особенности нашего сегодняшнего кода.
Обычно сокс сервер формирует ответ с типом адреса 01, т.е ip адрес, а не так как мы 03 - доменное имя. Для перевода ip в привычный нам строковый вид, т.е с точками мы будем использовать функцию пхп long2ip, специального для этого предназначенную, но перед этим мы должны будем перевести адрес из hex'а в dec. Кстати существует функция ip2long, которая могла бы пригодиться нам в том случае если бы мы передавали соксу IPv4,но это просто на заметку :-)
Код изначально взят из моей статьи [2] и заточен именно для bind'а...
<?
 error_reporting(0);
 $socks_ip	= "127.0.0.1"; // адрес scoks 5 прокси
 $socks_port  =  1080;	   // порт сокса
 $socks_login = "jinn";	  // логин для доступа к соксу
 $socks_pass  = "jinn2";	 // пароль
 
 $bind_host = "127.0.0.1";
 $bind_port = 3232;
 
 $socks_server=fsockopen($socks_ip,$socks_port);   // соединяемся с соксом
 if($socks_server)
 {
   echo'<meta http-equiv="Content-Language" content="ru"><meta http-equiv=Content-Type content="text/html; charset=windows-1251">';
   $h=pack("H*",'05020002'); // привествие =)
   fwrite($socks_server,$h);
   $result=bin2hex(fread($socks_server,4)); // переводим в hex для дальнейшего сравнения
   if($result == '0500') // авторизация отсутствует
   {
	  $auth_ok=1;
   }
   elseif($result == '0502') // метод username/password
   {
	  $len_login = chr(strlen($socks_login)); //получаем спец символ соответсвующий ascii коду
	  $len_pass  = chr(strlen($socks_pass));  // получаем спец символ соответсвующий ascii коду
  
	  $h=pack("H*","01").$len_login.$socks_login.$len_pass.$socks_pass; // формируем пакет с помощью pack()
	  fwrite($socks_server,$h);
	  
	  $result=bin2hex(fread($socks_server,4)); // переводим из бинарного режима в hex
	  // далее сверяем если код ответа 0, то авторизация успешна,выставляем об этом переменую,в ином случа выводим сообщение об ошибке
	   if($result{3}!=0)
		{
		   echo "<center><font color=red>Ошибка:аутентификация не прошла!</font></center>";
		   fclose($socks_server);
		}
		else
		{
		   $auth_ok=1;
		}
   }
   else
   {
	 echo "<center><font color=red>Ошибка:возможно это не socks5 или он не поддерживает данные(00,02) методы аутентификации!</font></center>";
   }
	
   $list="";
   // проверяем если авторизация успешна , то начинаем взаимодействие с соксом
   if($auth_ok==1)
   {
	  $len_h=chr(strlen($bind_host));
	  $h=pack("H*","05020003").$len_h.$bind_host.pack("n",$bind_port); //формируем запрос 
	  fwrite($socks_server,$h);
	  
	  $result = bin2hex(fread($socks_server,1024));
	  $ver	= substr($result,0,2);
	  $status = substr($result,2,2);
	  $in_ip	 = long2ip(hexdec(substr($result,8,8)));
	  $in_port   = hexdec(substr($result,16,4));
	  echo "Адрес для подключения:".$in_ip.":".$in_port."<br>";

	   // проверяем успешность подключения,выводи ошибки
		if($status == '00')
		{
			$head  = "<br><br><center><font color='blue' size=4>HI!coded by ZaeB.uS</font></center>";
			$in_socket=fsockopen($in_ip,$in_port);
			fwrite($in_socket,$head);
			fclose($in_socket);
			
			$result = bin2hex(fread($socks_server,1024));
			$ver	= substr($result,0,2);
			$status = substr($result,2,2); // тут статус входящего подключения
			$con_ip	 = long2ip(hexdec(substr($result,8,8))); // а кто это к нам подключился?ип подключившегося хоста
			$con_port   = hexdec(substr($result,16,4)); // порт негодяя
			
			echo "Подключившийся хост:".$con_ip.":".$con_port."<br>";
			echo "Полученные данные<br><br>";
			// получаем данные
			while(!feof($socks_server))
			{
			  echo fread($socks_server,1024);
			}
		}
		// определяем ошибку! данные коды ответа взяты из RFC
	   elseif ($status == 1) {echo "<center><font color=red>Ошибка: вина SOCKS-сервера</font></center>";}
	   elseif ($status == 2) {echo "<center><font color=red>Ошибка: соединение запрещено набором правил</font></center>";}
	   elseif ($status == 3) {echo "<center><font color=red>Ошибка: сеть недоступна</font></center>";}
	   elseif ($status == 4) {echo "<center><font color=red>Ошибка: хост недоступен</font></center>";}
	   elseif ($status == 5) {echo "<center><font color=red>Ошибка: отказ в соединении</font></center>";}
	   elseif ($status == 6) {echo "<center><font color=red>Ошибка: истечение TTL</font></center>";}
	   elseif ($status == 7) {echo "<center><font color=red>Ошибка: команда не поддерживается</font></center>";}
	   elseif ($status == 8) {echo "<center><font color=red>Ошибка: тип адреса не поддерживается</font></center>";}
	   else {echo "<center><font color=red>Ошибка: не определено!RFC в панике! :-)</font></center>";}
	}
	fclose($socks_server);
 }
 else
 {
   echo "<center><font color=red>SOCKS сервер недоступен!</font></center>";
 }
 echo '<br><br><table border="0" cellspacing="1" width="100%" align="center" style="background-color:#000000;"><tr><td width="100%" align="center" style="background-color:#E8E8E8;"><font size=1 color="#292929" face="verdana">[ c0ded by <b>Jinn</b> | 304227033 | http://zaeb.us ] </font></td></tr></table>';

?>

o--:[ 4 | End ]:--o

Да, статья получилась не слишком большой, и возможно вы не узнали из нее ничего нового, но все же я думаю что знать данную инфу нужно, ведь понимание сетевых протоколов является основным=) По прежнему, если возникли предложения или вопросы стучи мне в асю или пиши на мыло, постараюсь дать ответ...

o--:[ 5 | Материалы ]:--o

1.... Организация работы php скрипта через socks5 сервер, Jinn, ZaeB.uS, ]]>http://zaeb.us]]>
2.... PHP + socks5(авторизация по методу username/password), Jinn, ZaeB.uS, ]]>http://zaeb.us]]>

o--:[ Jinn | ZaeB.uS | ]]>http://zaeb.us]]> ]:--o



--[ ZaeB.uS, ]]>http://zaeb.us]]> ]---
ICQ: 304227033
Jabber: jinn@jabber.prologic.ws
OCC: 82623


Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных