Иногда бывает нужно определить наличие такого прокси, допустим, при тестировании вэб-приложений. Непрозрачный прокси обнаруживается достаточно легко по source/dest IP и заголовкам, которые добавляет прокси. Оговорюсь, что мы будем слушать трафик на стороне клиента и сервера OS для анализа.
Итак, обнаружение прозрачного прокси. Для этого надо сделать запрос на заведомо несуществующий IP, к примеру, на 192.168.100.100. Прокси перехватит соединение (connection) и попытается обслужить его. Когда он определит, что не доступен сервер назначения, он, возможно, вернет статус ошибки или просто закроет соединение с клиентом. Большинство браузеров сгенерируют страницу с ошибкой, если они могут соединиться с сервером. В случае, если соединение было принято, но потом закрыто, страница с ошибкой будет отличаться.
Запрос с помощью curl на этот IP:
curl -Lv -o /dev/null -A "Firefox" "http://192.168.100.100/index.html" * About to connect() to 192.168.100.100 port 80 (#0) * Trying 192.168.100.100... connected * Connected to 192.168. 100.100 (192.168.100.100 ) port 80 (#0) > GET /index.html HTTP/1.1 > User-Agent: Firefox > Host: 192.168.100.100 > Accept: */* > % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- 0:03:30 --:--:-- 0 < HTTP/1.1 502 internal error - server connection terminated < Date: Thu, 17 Jul 2014 08:26:27 GMT < Connection: keep-alive < Cache-Control: no-store < Content-Type: text/html < Content-Language: en < Content-Length: 294 < { [data not shown] |
В данном трафике 100.100.100.100 — это IP клиента.
1 0.000000 100.100.100.100 -> 192.168.100.100 TCP 76 0 3988560025 0x0002 56280 > http [SYN] Seq=3988560025 Win=14600 Len=0 MSS=1460 SACK_PERM=1 TSval=3585329416 TSecr=0 WS=128 2 0.001000 192.168.100.100 -> 100.100.100.100 TCP 76 0 3988560026 1365204930 0x0012 http > 56280 [SYN, ACK] Seq=1365204930 Ack=3988560026 Win=14480 Len=0 MSS=1460 SACK_PERM=1 TSval=4134164061 TSecr=3585329416 WS=128 3 0.001000 100.100.100.100 -> 192.168.100.100 TCP 68 0 1365204931 3988560026 0x0010 56280 > http [ACK] Seq=3988560026 Ack=1365204931 Win=14720 Len=0 TSval=3585329417 TSecr=4134164061 4 0.001000 100.100.100.100 -> 192.168.100.100 HTTP 196 128 1365204931 3988560026 0x0018 GET /index.html HTTP/1.1 5 0.001000 192.168.100.100 -> 100.100.100.100 TCP 68 0 3988560154 1365204931 0x0010 http > 56280 [ACK] Seq=1365204931 Ack=3988560154 Win=15616 Len=0 TSval=4134164062 TSecr=3585329417 6 210.944720 192.168.100.100 -> 100.100.100.100 HTTP 578 510 3988560154 1365204931 0x0018 HTTP/1.1 502 internal error - server connection terminated (text/html) 7 210.945720 100.100.100.100 -> 192.168.100.100 TCP 68 0 1365205441 3988560154 0x0010 56280 > http [ACK] Seq=3988560154 Ack=1365205441 Win=15744 Len=0 TSval=3585540394 TSecr=4134375004 8 210.945720 100.100.100.100 -> 192.168.100.100 TCP 68 0 1365205441 3988560154 0x0011 56280 > http [FIN, ACK] Seq=3988560154 Ack=1365205441 Win=15744 Len=0 TSval=3585540394 TSecr=4134375004 9 210.955719 192.168.100.100 -> 100.100.100.100 TCP 68 0 3988560155 1365205441 0x0011 http > 56280 [FIN, ACK] Seq=1365205441 Ack=3988560155 Win=15616 Len=0 TSval=4134375015 TSecr=3585540394 10 210.955719 100.100.100.100 -> 192.168.100.100 TCP 68 0 1365205442 3988560155 0x0010 56280 > http [ACK] Seq=3988560155 Ack=1365205442 Win=15744 Len=0 TSval=3585540404 TSecr=4134375015 |
Как мы видим, соединение к несуществующему хосту было принято и на него отправлен запрос GET. Но данных в ответ не получено, прокси вернул код ошибки и закрыл соединение.
В случае, если прокси в цепочке передачи данных нет, вывод curl-a будет такой:
curl -Lv -o /dev/null -A "Firefox" "http://192.168.100.100/index.html" * About to connect() to 192.168.100.100 port 80 (#0) * Trying 192.168.100.100... Connection timed out * couldn't connect to host * Closing connection #0 curl: (7) couldn't connect to host |
А перехваченный трафик будет примерно таким:
1 0.000000 100.100.100.100 -> 192.168.100.100 TCP 76 0 885915575 0x0002 56285 > http [SYN] Seq=885915575 Win=14600 Len=0 MSS=1460 SACK_PERM=1 TSval=3586242734 TSecr=0 WS=128 2 0.999847 100.100.100.100 -> 192.168.100.100 TCP 76 0 885915575 0x0002 [TCP Retransmission] 56285 > http [SYN] Seq=885915575 Win=14600 Len=0 MSS=1460 SACK_PERM=1 TSval=3586243734 TSecr=0 WS=128 3 2.999541 100.100.100.100 -> 192.168.100.100 TCP 76 0 885915575 0x0002 [TCP Retransmission] 56285 > http [SYN] Seq=885915575 Win=14600 Len=0 MSS=1460 SACK_PERM=1 TSval=3586245734 TSecr=0 WS=128 4 6.998929 100.100.100.100 -> 192.168.100.100 TCP 76 0 885915575 0x0002 [TCP Retransmission] 56285 > http [SYN] Seq=885915575 Win=14600 Len=0 MSS=1460 SACK_PERM=1 TSval=3586249734 TSecr=0 WS=128 5 14.997705 100.100.100.100 -> 192.168.100.100 TCP 76 0 885915575 0x0002 [TCP Retransmission] 56285 > http [SYN] Seq=885915575 Win=14600 Len=0 MSS=1460 SACK_PERM=1 TSval=3586257734 TSecr=0 WS=128 6 30.995257 100.100.100.100 -> 192.168.100.100 TCP 76 0 885915575 0x0002 [TCP Retransmission] 56285 > http [SYN] Seq=885915575 Win=14600 Len=0 MSS=1460 SACK_PERM=1 TSval=3586273734 TSecr=0 WS=128 |
Второй способ обнаружить прозрачный прокси — сравнить значения TCP SEQ/ACK на стороне клиента и сервера OS. Будем считать, что мы можем снять трафик и на стороне прокси – это нужно просто для наглядности того, какие значения надо сравнивать.
Трафик на стороне клиента (100.100.100.100):
1 0.000000000 100.100.100.100 200.200.200.200 TCP 57895 80 1865774121 14600 2 57895 > http [SYN] Seq=1865774121 Win=14600 Len=0 MSS=1460 SACK_PERM=1 TSval=3604767069 TSecr=0 WS=128 2 0.000000000 200.200.200.200 100.100.100.100 TCP 80 57895 4096028741 1865774122 14480 18 http > 57895 [SYN, ACK] Seq=4096028741 Ack=1865774122 Win=14480 Len=0 MSS=1460 SACK_PERM=1 TSval=4153598607 TSecr=3604767069 WS=128 3 0.000000000 100.100.100.100 200.200.200.200 TCP 57895 80 1865774122 4096028742 14720 16 57895 > http [ACK] Seq=1865774122 Ack=4096028742 Win=14720 Len=0 TSval=3604767072 TSecr=4153598607 4 0.000000000 100.100.100.100 200.200.200.200 HTTP 57895 80 1865774122 4096028742 14720 24 GET /images/new.jpg HTTP/1.1 5 0.000000000 200.200.200.200 100.100.100.100 TCP 80 57895 4096028742 1865774234 14592 16 http > 57895 [ACK] Seq=4096028742 Ack=1865774234 Win=14592 Len=0 TSval=4153598607 TSecr=3604767072 6 0.162975000 200.200.200.200 100.100.100.100 TCP 80 57895 4096028742 1865774234 14592 16 [TCP segment of a reassembled PDU] 7 0.162975000 100.100.100.100 200.200.200.200 TCP 57895 80 1865774234 4096035982 17536 16 57895 > http [ACK] Seq=1865774234 Ack=4096035982 Win=17536 Len=0 TSval=3604767235 TSecr=4153598769 8 0.162975000 200.200.200.200 100.100.100.100 TCP 80 57895 4096035982 1865774234 14592 16 [TCP segment of a reassembled PDU] 9 0.162975000 100.100.100.100 200.200.200.200 TCP 57895 80 1865774234 4096037430 20480 16 57895 > http [ACK] Seq=1865774234 Ack=4096037430 Win=20480 Len=0 TSval=3604767235 TSecr=4153598770 10 0.162975000 200.200.200.200 100.100.100.100 HTTP 80 57895 4096037430 1865774234 14592 24 HTTP/1.1 200 OK (JPEG JFIF image) |
Трафик на стороне прокси (200.200.200.200):
1 0.000000000 100.100.100.100 200.200.200.200 TCP 57895 80 1865774121 14600 2 57895 > http [SYN] Seq=1865774121 Win=14600 Len=0 MSS=1460 SACK_PERM=1 TSval=3604767069 TSecr=0 WS=128 2 0.000000000 200.200.200.200 100.100.100.100 TCP 80 57895 4096028741 1865774122 14480 18 http > 57895 [SYN, ACK] Seq=4096028741 Ack=1865774122 Win=14480 Len=0 MSS=1460 SACK_PERM=1 TSval=4153598607 TSecr=3604767069 WS=128 3 0.000000000 100.100.100.100 200.200.200.200 TCP 57895 80 1865774122 4096028742 14720 16 57895 > http [ACK] Seq=1865774122 Ack=4096028742 Win=14720 Len=0 TSval=3604767072 TSecr=4153598607 4 0.000000000 100.100.100.100 200.200.200.200 HTTP 57895 80 1865774122 4096028742 14720 24 GET /images/new.jpg HTTP/1.1 5 0.000000000 200.200.200.200 100.100.100.100 TCP 80 57895 4096028742 1865774234 14592 16 http > 57895 [ACK] Seq=4096028742 Ack=1865774234 Win=14592 Len=0 TSval=4153598607 TSecr=3604767072 6 0.120001000 100.100.100.100 200.200.200.200 TCP 57895 80 1318499263 14600 2 [TCP Port numbers reused] 57895 > http [SYN] Seq=1318499263 Win=14600 Len=0 MSS=1460 SACK_PERM=1 TSval=4153598725 TSecr=0 WS=128 7 0.120001000 200.200.200.200 100.100.100.100 TCP 80 57895 3611911297 1318499264 14480 18 http > 57895 [SYN, ACK] Seq=3611911297 Ack=1318499264 Win=14480 Len=0 MSS=1460 SACK_PERM=1 TSval=1923501909 TSecr=4153598725 WS=128 8 0.120001000 100.100.100.100 200.200.200.200 TCP 57895 80 1318499264 3611911298 14720 16 57895 > http [ACK] Seq=1318499264 Ack=3611911298 Win=14720 Len=0 TSval=4153598727 TSecr=1923501909 9 0.121001000 100.100.100.100 200.200.200.200 HTTP 57895 80 1318499264 3611911298 14720 24 GET /images/new.jpg HTTP/1.1 10 0.121001000 200.200.200.200 100.100.100.100 TCP 80 57895 3611911298 1318499376 14592 16 http > 57895 [ACK] Seq=3611911298 Ack=1318499376 Win=14592 Len=0 TSval=1923501910 TSecr=4153598728 |
Трафик на стороне OS:
1 0.000000000 100.100.100.100 200.200.200.200 TCP 57895 80 1318499263 14600 2 57895 > http [SYN] Seq=1318499263 Win=14600 Len=0 MSS=1460 SACK_PERM=1 TSval=4153598725 TSecr=0 WS=128 2 0.000038000 200.200.200.200 100.100.100.100 TCP 80 57895 3611911297 1318499264 14480 18 http > 57895 [SYN, ACK] Seq=3611911297 Ack=1318499264 Win=14480 Len=0 MSS=1460 SACK_PERM=1 TSval=1923501909 TSecr=4153598725 WS=128 3 0.000204000 100.100.100.100 200.200.200.200 TCP 57895 80 1318499264 3611911298 14720 16 57895 > http [ACK] Seq=1318499264 Ack=3611911298 Win=14720 Len=0 TSval=4153598727 TSecr=1923501909 4 0.001117000 100.100.100.100 200.200.200.200 HTTP 57895 80 1318499264 3611911298 14720 24 GET /images/new.jpg HTTP/1.1 5 0.001141000 200.200.200.200 100.100.100.100 TCP 80 57895 3611911298 1318499376 14592 16 http > 57895 [ACK] Seq=3611911298 Ack=1318499376 Win=14592 Len=0 TSval=1923501910 TSecr=4153598728 6 0.001886000 200.200.200.200 100.100.100.100 TCP 80 57895 3611911298 1318499376 14592 16 [TCP segment of a reassembled PDU] 7 0.001924000 200.200.200.200 100.100.100.100 TCP 80 57895 3611914194 1318499376 14592 16 [TCP segment of a reassembled PDU] 8 0.001930000 200.200.200.200 100.100.100.100 TCP 80 57895 3611918538 1318499376 14592 16 [TCP segment of a reassembled PDU] 9 0.001937000 200.200.200.200 100.100.100.100 HTTP 80 57895 3611919986 1318499376 14592 24 HTTP/1.1 200 OK (JPEG JFIF image) 10 0.002162000 100.100.100.100 200.200.200.200 TCP 57895 80 1318499376 3611914194 17536 16 57895 > http [ACK] Seq=1318499376 Ack=3611914194 Win=17536 Len=0 TSval=4153598729 TSecr=1923501911 |
Как мы видим значения SEQ/ACK одинаковы в направлении от клиента к прокси и отличаются в направлении к OS. По другим капчам замечено, что прокси иногда меняет TCP window scale, но на этот признак полагаться не стоит.
Заметим, что на стороне прокси пакеты «дублируются» — прокси принимает пакет от клиента и переправляет на OS.
И, наконец, последний способ. Он базируется на предположении из первого метода — прокси сначала принимает соединение от клиента и только после этого делает запрос на OS. Т.е. Мы можем измерить задержку между клиентским и серверным SYN и SYN/ACK. Если известно, что OS расположен далеко, а задержка в районе 1-10 миллисекунд, то можно сделать вывод о наличии прокси.
Перехвачен трафик без прокси (оставлены только существенные пакеты SYN и SYN/ACK; прокси — 173.194.113.52 ):
1 0.000000 100.100.100.100 -> 173.194.113.52 TCP 64204463 14600 0x0002 43102 > http [SYN] Seq=64204463 Win=14600 Len=0 MSS=1460 SACK_PERM=1 TSval=3669511612 TSecr=0 WS=128 2 0.031995 173.194.113.52 -> 100.100.100.100 TCP 64204464 2342845794 42540 0x0012 http > 43102 [SYN, ACK] Seq=2342845794 Ack=64204464 Win=42540 Len=0 MSS=1430 SACK_PERM=1 TSval=831970729 TSecr=3669511612 WS=64 3 0.031995 100.100.100.100 -> 173.194.113.52 TCP 2342845795 64204464 14720 128 0x0010 43102 > http [ACK] Seq=64204464 Ack=2342845795 Win=14720 Len=0 TSval=3669511644 TSecr=831970729 4 0.031995 100.100.100.100 -> 173.194.113.52 HTTP 2342845795 64204464 14720 128 0x0018 GET / HTTP/1.1 |
Как мы видим, задержка между SYN и SYN/ACK примерно 32 миллисекунды.
Трафик при наличии прокси:
1 0.000000 100.100.100.100 -> 173.194.113.52 TCP 278229736 14600 0x0002 43103 > http [SYN] Seq=278229736 Win=14600 Len=0 MSS=1460 SACK_PERM=1 TSval=3669576737 TSecr=0 WS=128 2 0.001999 173.194.113.52 -> 100.100.100.100 TCP 278229737 96176689 14480 0x0012 http > 43103 [SYN, ACK] Seq=96176689 Ack=278229737 Win=14480 Len=0 MSS=1460 SACK_PERM=1 TSval=4218397903 TSecr=3669576737 WS=128 3 0.001999 100.100.100.100 -> 173.194.113.52 TCP 96176690 278229737 14720 128 0x0010 43103 > http [ACK] Seq=278229737 Ack=96176690 Win=14720 Len=0 TSval=3669576739 TSecr=4218397903 4 0.001999 100.100.100.100 -> 173.194.113.52 HTTP 96176690 278229737 14720 128 0x0018 GET / HTTP/1.1 |
Задержка (0.001999) стала гораздо меньше из-за того, что расстояние от клиента до прокси меньше расстояния от клиента до OS. Данный метод не совсем надежен, т. к. прокси может быть расположен примерно посередине между клиентом и OS и задержки будут одинаковыми.