[PHP] anon proxies detecteren bij login

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • sjhgvr
  • Registratie: Januari 2004
  • Laatst online: 09-06 07:17
Ik ben bezig met het schrijven van een challenge-response login script in html/js/php.
Dat lukt aardig, alleen zit ik nu met een klein dilemma..
Ook al wil ik mijn gebruikers forcen een sterk paswoord te nemen.. ik block toch ook liever anonieme proxies om zo bruteforce attempts tegen te gaan.

Nu heb ik uren zitten zoeken op t net, en ben ik tot conclusie gekomen dat dit op enkele manieren te doen is;
1: Het IP adres van de gebruiker zo ver mogenlijk ontrafelen en dan kijken als er op dat adres (achter de meest bekende poorten) een proxy server draait.
2: Kijken als het IP adres geblacklist is.
3: Lijsten van de meest bekende anonymous proxy list websites samenvoegen, en daar een grote blacklist van maken.

Ik heb van wat ik hierover totnutoe gevonden heb wat samengevoegd, en dit is het geworden:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<?php
function PMA_getenv($var_name) {
 if (isset($_SERVER[$var_name])) $out = $_SERVER[$var_name];
 else if (isset($_ENV[$var_name])) $out = $_ENV[$var_name];
 else if (getenv($var_name)) $out = getenv($var_name);
 else if (function_exists('apache_getenv') && apache_getenv($var_name, true)) $out = apache_getenv($var_name, true);
 else $out = '';
 return $out;
}

function PMA_getIp() {
 if (empty($REMOTE_ADDR) && PMA_getenv('REMOTE_ADDR')) $direct_ip = PMA_getenv('REMOTE_ADDR');
 if (empty($HTTP_X_FORWARDED_FOR) && PMA_getenv('HTTP_X_FORWARDED_FOR')) $proxy_ip = PMA_getenv('HTTP_X_FORWARDED_FOR');
 if (empty($HTTP_X_FORWARDED) && PMA_getenv('HTTP_X_FORWARDED')) $proxy_ip = PMA_getenv('HTTP_X_FORWARDED');
 if (empty($HTTP_FORWARDED_FOR) && PMA_getenv('HTTP_FORWARDED_FOR')) $proxy_ip = PMA_getenv('HTTP_FORWARDED_FOR');
 if (empty($HTTP_FORWARDED) && PMA_getenv('HTTP_FORWARDED')) $proxy_ip = PMA_getenv('HTTP_FORWARDED');
 if (empty($HTTP_VIA) && PMA_getenv('HTTP_VIA')) $proxy_ip = PMA_getenv('HTTP_VIA');
 if (empty($HTTP_X_COMING_FROM) && PMA_getenv('HTTP_X_COMING_FROM')) $proxy_ip = PMA_getenv('HTTP_X_COMING_FROM');
 if (empty($HTTP_COMING_FROM) && PMA_getenv('HTTP_COMING_FROM')) $proxy_ip = PMA_getenv('HTTP_COMING_FROM');
 if (!isset($proxy_ip)) $userIP = $direct_ip;
 else $userIP = $proxy_ip;
 $is_ip = preg_match('|^([0-9]{1,3}\.){3,3}[0-9]{1,3}|', $userIP, $regs);
 return ($is_ip && (count($regs) > 0)) ? $regs[0] : 'unknown';
}

$userIP = PMA_getIp();

$badProxy = false;
$ports = array(50050, 3128, 3124, 8080);

while ($port = array_pop($ports)) {
 $socket = @fsockopen("tcp://$userIP", $port, $errno, $errstr, 3);
 if ($errno == 0) {
  $request = "GET http://www.google.com/ HTTP/1.0\r\n";
  $request .= "Proxy-Connection: Keep-Alive\r\n";
  $request .= "Pragma: no-cache\r\n";
  $request .= "Host: www.google.com\r\n";
  $request .= "User-Agent: MSIE 6.0\r\n";
  $request .= "\r\n";
  fputs($socket, $request);
  $response = fputs($socket, 128);
  if (strlen(stristr($response, "200")) > 0) $badProxy = true;
  fclose($socket);
 }
}

function get_reversed_ip($ip) {
 $ip_exploded = explode('.', $ip);
 $reverse_ip = "$ip_exploded[3].$ip_exploded[2].$ip_exploded[1].$ip_exploded[0]";
 return $reverse_ip;
}

$reverse_ip = get_reversed_ip($userIP);

$rbl_dns_servers = array(
'.bl.spamcop.net',
'.blackholes.five-ten-sg.com',
'.combined.njabl.org',
'.dnsbl.sorbs.net',
'.dynablock.easynet.nl',
'.http.dnsbl.sorbs.net',
'.list.dsbl.org',
'.misc.dnsbl.sorbs.net',
'.opm.blitzed.org',
'.proxies.blackholes.easynet.nl',
'.relays.ordb.org',
'.sbl-xbl.spamhaus.org',
'.socks.dnsbl.sorbs.net',
'.spam.dnsbl.sorbs.net',
'.virbl.dnsbl.bit.nl');

while ($reverse_dns = array_pop($rbl_dns_servers)) {
 $rlookup = $reverse_ip . $reverse_dns;
 if ($rlookup != gethostbyname($rlookup)) $badProxy = true;
}

if ($badProxy) echo "BUSTED";
else echo "TRUSTED";
?>


Nu heb ik echter 2 problemen.. t blijkt dat de host waar het script op gaat draaien de poorten 50050, 3128, 3124, 8080 blocked, dus /* die optie valt af */
De andere optie: blacklist checking .. kan ik echter niet verifieren omdat ik geen blacklisted IP weet.
Via google dacht ik er wel enkele gevonden te hebben, maar die bleken niet geblacklist te zijn.. ?

Mijn vragen aan jullie zijn;
Weten jullie enig blacklisted ip's ( testen door $userIP = PMA_getIp(); te vervangen door: $userIP = "12.34.567.890"; )
en
Weten jullie misschien een betere/effiecientere oplossing? (Het script gaat alleen draaien bij login, dus een lag van +/- 3 sec is geen ramp)

edit: Het blijkt dat het script werkt, alleen zijn er genoeg anonymous proxies die niet geblacklist zijn, en ik merk ook false positives op .. enig idee hoe die problemen af te vangen?

[ Voor 139% gewijzigd door sjhgvr op 05-09-2006 20:44 ]

oisd.nl


Acties:
  • 0 Henk 'm!

  • moto-moi
  • Registratie: Juli 2001
  • Laatst online: 09-06-2011

moto-moi

Ja, ik haat jou ook :w

DapinododiadeaL schreef op dinsdag 05 september 2006 @ 11:25:De andere optie: blacklist checking .. kan ik echter niet verifieren omdat ik geen blacklisted IP weet.
Via google dacht ik er wel enkele gevonden te hebben, maar die bleken niet geblacklist te zijn.. ?

Mijn vragen aan jullie zijn;
Weten jullie enig blacklisted ip's ( testen door $userIP = PMA_getIp(); te vervangen door: $userIP = "12.34.567.890"; )
heel simpel:
Vul maar eens 127.0.0.2 of 127.0.0.3 in ofzo op http://www.kloth.net/services/dnsbl.php en zie wat er gebeurt ;)

God, root, what is difference? | Talga Vassternich | IBM zuigt


Acties:
  • 0 Henk 'm!

  • sjhgvr
  • Registratie: Januari 2004
  • Laatst online: 09-06 07:17
moto-moi schreef op dinsdag 05 september 2006 @ 11:44:
[...]

heel simpel:
Vul maar eens 127.0.0.2 of 127.0.0.3 in ofzo op http://www.kloth.net/services/dnsbl.php en zie wat er gebeurt ;)
Mijn excuses voor het plots editten van mijn post.. wilde replies voor zijn, helaas kon ik niet tippen aan uwe snelheid.

oisd.nl


Acties:
  • 0 Henk 'm!

Anoniem: 14829

Was 't niet slimmer geweest om je oplossing toe te voegen aan je vraag i.p.v. deze te vervangen?
Een stuk handiger voor de search, en je zult vast niet de enige GoTter zijn die nu of in de toekomst met een soortgelijke vraag zal komen te zitten...

Acties:
  • 0 Henk 'm!

  • sjhgvr
  • Registratie: Januari 2004
  • Laatst online: 09-06 07:17
Anoniem: 14829 schreef op dinsdag 05 september 2006 @ 19:44:
Was 't niet slimmer geweest om je oplossing toe te voegen aan je vraag i.p.v. deze te vervangen?
Een stuk handiger voor de search, en je zult vast niet de enige GoTter zijn die nu of in de toekomst met een soortgelijke vraag zal komen te zitten...
Doen we, ik fix t ff, en stel de vraag ff anders.
edit: done, srry for the confusion

[ Voor 4% gewijzigd door sjhgvr op 05-09-2006 20:41 ]

oisd.nl


Acties:
  • 0 Henk 'm!

  • sjhgvr
  • Registratie: Januari 2004
  • Laatst online: 09-06 07:17
Heb t idee even uitgewerkt:

ClientServer ($solidSalt = 'bla123';)
Page request
Create Session
$_SESSION['loginsalt'] = generateRandomCrap();
$salt = sha2($_SESSION['loginsalt'].$solidSalt);
Genereer pagina met $salt in een hidden form field
Login pagina nu zichtbaar
Gebruiker typt gebruikersnaam, en zodra hij het gebruikernaamveld verlaat om zijn wachtwoord in te typen, word er een AJAX GET request met username (plaintext) naar server verzonden.
$_SESSION['username'] = clean($_GET['username']);
In de database word gecheckt naar de bijbehorende $userSalt
Indien die niet gevonden word: $userSalt = sha2($_GET['username']."blabla");
Geen random string omdat de user op die manier kan checken als een username daadwerkelijk voorkomt in de database.

$userSalt word naar de browser gestuurd.
userSalt word nu onthouden in een hidden form field.

Op t moment van login:
Javascript: loginString = sha2(salt+sha2(password,userSalt))

loginString word verstuurt naar de server;
Server checkt als het ip adres voorkomt in een blacklist.
Zoja, check hoevaak er het afgelopen uur al in is proberen te loggen met een blacklisted IP. Als dat meer dan 10 keer is, word de login geblocked voor blacklisted IP's voor 15 minuten.
Als het ip blacklisted is maar in het afgelopen uur minder dan 10 keer in is proberen te loggen met een blacklisted ip kan t dus een false positive zijn, of als het ip niet blacklisted is; check of clean($_GET['loginString']) === sha2(sha2($_SESSION['loginsalt'].$solidSalt).$dbPassword)

Als de gegeven informatie overeenkomt, userLoggedIn = true;
anders nog 2 inlogpogingen over op dat ip adres.
Komt de gegeven informatie niet overeen en zijn de 3 inlogpogingen verprutst, ip geblocked voor 15 minuten.

Ik heb vernomen dat het ip adres van een gebruiker tijdens het browsen plots kan veranderen (AOL?) Dan kan er dus niet altijd op het IP adres worden gerekend bij de verificatie.
Wat ik ook aan het toevoegen ben is een optie net zoals hier op t.net tijdens het inloggen je IP adres mee te nemen in de "check". Is het niet veiliger als alleen van de mensen die van die functie gebruik maken de optie te geven hun login te onthouden dmv een cookie? En voor diegenen die die optie niet aanvinken dus niet te laten onthouden = cookie verwijderd bij sluiten browser = logout?
Ook als ik dingen over het hoofd zie hoor ik dat graag.

oisd.nl

Pagina: 1