Hulu és BBC iPlayer regionális védelmének kijátszása

RoliSoft
2010 August 02, Monday 23:00

BBC iPlayer és HuluNéhány weboldal korlátozza a hozzáférést egy országra. Ilyen például a Hulu amit csak Amerikából lehet elérni, vagy a BBC iPlayer, amit csak Angliából. Az előző két oldal TV sorozatokat és egyéb behind the scenes vagy web exclusive videókat tartalmaz, de sajnos nem lehet elérni nemzetközileg. Nos, ez nem egészen igaz, ugyanis ki lehet játszani a védelmüket és meg lehet nézni a videókat.

Talán a legelső módszer az lenne, hogy keress egy amerikai vagy angliai SOCKS5 proxyt ami gyors és nem küld X-Forwarded-For headert. Ez viszont nem lesz egyszerű, úgyhogy nem ez lesz az első módszer amit itt leírok.

The Onion Router

A TOR egy elég népszerű szoftver. Eredeti célja titkosítani és anonimizálni az online aktivitásod, így nem kerülsz bajba, ha illegális dolgot csinálsz. Sok vita van a körül, hogy mennyire hatékony a teljes anonimizálás terén, viszont ez minket nem érdekel, ugyanis csak arra fogjuk használni, hogy a hozzáférést korlátozó oldalaknak megfeleljünk.

A TOR három véletlenszerűen választott proxy szerveren küldi át az adatforgalmat, mielőtt az eléri a cél szervert. A legelső az entry node, valamennyivel növelheted a sebességet, ha egy hozzád közeli entry node-ra korlátozod a listát. (Normális körülmények között nagyon nem ajánlott azonos országból választani entry node-ot, de emlékezz, hogy ez nem egy hack cikk, hanem csak videóportál védelem átlépése.)

A második szerver holléte nem érdekes, viszont a legfontosabb az utolsó node, azaz az exit node, ugyanis ez a szerver fog csatlakozni a cél szerverhez, így a weboldal azt fogja hinni, hogy abból az országból vagy ahol az exit node van.

Válassz egy UK exit node-ot és kész is, nézheted a BBC iPlayert míg meg nem unod.

És végül egy-két szó a sebességről. Ez ugyan nagyon változik, viszont legtöbbször alkalmas arra, hogy megszakítások nélkül lejátssz egy videót. Átlagosan 50 kB/s sebességű a kapcsolat, de találkoztam már olyannal is, ahol elértem a 200 kB/s-et. Innen ugyan még sok van az én direkt kapcsolatomig, ami felmegy 12000 kB/s-ig, viszont videólejátszásra tökéletes ez is.

Lépésről Lépésre

  1. Töltsd le a TOR szoftvert. A következő oldalon, http://www.torproject.org/download.html.enDownload Stable alatt kattints a legelső linkre. Töltsd le és telepítsd.
  2. Keresd meg a TOR konfigurációs fájlját. A start menüben keresd meg a Vidalia Bundle mappát, majd a Tor nevű almappájában kattints a Torrc fájlra.
  3. Állítsd be, hogy az exit node UK vagy US proxy legyen. A fájl végére írd be, hogy:
    StrictExitNodes 1
    Ez azt jelenti, hogy nem használ más exit node-ot, csak amit megadsz neki. Ezután pedig jön a lényeg. Egy új sorba, írd be a következőt:
    ExitNodes {XX}
    Ahol pedig az XX van, oda az ország kódját írd be. GB Anglia (iPlayer-hez), US Amerika (Hulu, Pandora, stb). A kapcsos zárójeleket NE töröld ki.
  4. Állítsd be, hogy a böngésződ a TOR-on keresztül csatlakozzon az internetre. Ezzel viszont van egy baj, mégpedig az, hogy a Flash nem a böngésző proxyját használja, így, ha beállítod, hogy a Firefox a TOR-on keresztül csatlakozzon, a videólejátszó még mindig direkt kapcsolatot fog létesíteni, és nem fogja lejátszani a videót a korlátozások miatt. A leggyorsabb megoldás az, hogy letöltöd a Switchy-t, ami egy Chrome kiterjesztés. Miután feltelepítetted, a címsor mellett megjelenik egy Földgömb ikon, kattints rá, majd Options. Nyomd meg a New Profile-t, névnek adj akármit, mondjuk TOR, majd a SOCKS Host-hoz írd be, hogy 127.0.0.1 a porthoz pedig 9050 alatta pedig válaszd a SOCKS v5 opciót. A Network fülön aktiváld a Proxy for VPN/Dial-up opciót, majd Save.
  5. Indítsd el a TOR-t. Kattints a Vidalia-ra a start menüben, majd várj, míg kiírja, hogy Connected to the Tor network! Ha ez meglett, akkor nyomd meg, hogy Hide, menj vissza a Chrome-hoz és a Switchy menüjében kattints a TOR-ra.
  6. Ennyi az egész. Kiadhatod magad akárkinek akármelyik országból. Plusz, ha a szolgáltatód cenzúráz vagy van parental control a számítógépeden, ezzel a megoldással simán elérheted a cenzúrázott oldalakat is.

Hulu és BBC iPlayer

A legjobb módszer email címek validálására

RoliSoft
2010 May 31, Monday 19:00

Email címet validálni egy nagyon nehéz feladat. Ha azt hiszed, hogy egy szimpla [a-z0-9]+@[a-z0-9]+\.[a-z]+ reguláris kifejezés megteszi, akkor nagyon rossz hírem van neked. &*=?^+{}'~@árvíztűrő-tükörfúrógép.net bizony egy szintaktikailag valid email cím.

Ha meg szeretnéd tudni egész pontosan hogyan is kell validálni egy címet, akkor a következőket tanulmányozd:

  1. RFC0822 – Az eredeti specifikáció; az egyetlen problémája, hogy 1982-ben lett megírva, úgyhogy...
  2. RFC1123, 5.2.15 RFC-822 Syntax Change
  3. RFC2822, 3.4. Address Specification

Ha sikerült keresni vagy összedobni egy reguláris kifejezést, ami ezeknek a feltételeknek megfelelően validál, akkor jön a következő kérdés: a cím valid, de létezik-e az a cím? És igen, ezt könnyen le lehet ellenőrözni.

Ebben a cikkben bemutatom, hogy hogyan lehet egy email címet teljesen leellenőrizni három lépésből.

Első lépés – Az email cím szintaktikai ellenőrzése

Noha nem létezik olyan reguláris kifejezés ami tökéletesen validálna, léteznek olyanok amik közel vannak hozzá.

Ha egy egyszerű preg_match-et szeretnél használni egy cím validálásához, akkor a következő reguláris kifejezés a legjobb (a cikk írásakor):

/^([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)$/i

Ha pedig inkább egy pontosabb függvényt szeretnél használni akkor meg töltsd le az EmailAddressValidation osztályt. A használata nagyon egyszerű:

include('EmailAddressValidator.php');

$validator = new EmailAddressValidator;

if ($validator->check_email_address('rolisoft@gmail.com')) { 
    // A cím szintaktikailag helyes, jöhet a következő lépés...
} else {
    die('A beírt email cím nem helyes!');
}

Második lépés – Tud-e a domain emaileket fogadni

Megnézzük hogy az email cím domainjének van-e MX vagy A rekordjai. Ha nincs, akkor nem tud emailt fogadni.

rolisoft@ncc1701e:~$ nslookup -type=MX gmail.com
Server:         208.113.192.18
Address:        208.113.192.18#53

Non-authoritative answer:
gmail.com       mail exchanger = 40 alt4.gmail-smtp-in.l.google.com.
gmail.com       mail exchanger = 5 gmail-smtp-in.l.google.com.
gmail.com       mail exchanger = 30 alt3.gmail-smtp-in.l.google.com.
gmail.com       mail exchanger = 10 alt1.gmail-smtp-in.l.google.com.
gmail.com       mail exchanger = 20 alt2.gmail-smtp-in.l.google.com.

rolisoft@ncc1701e:~$ nslookup -type=A gmail.com
Server:         208.113.192.18
Address:        208.113.192.18#53

Non-authoritative answer:
Name:   gmail.com
Address: 209.85.225.83
Name:   gmail.com
Address: 74.125.79.83
Name:   gmail.com
Address: 74.125.127.83

PHP-ből az MX és A rekordokat a Net_DNS segítségével lehet megnézni.

Harmadik lépés – Megpróbálunk emailt küldeni

Megpróbálunk csatlakozni az előzőleg kapott MX vagy A rekordokhoz és megpróbálunk elküldeni egy emailt. A cím beírása után a mail server figyelmeztet ha a cím nem létezik, ha pedig létezik akkor kijelentkezünk.

Egy létező email cím esetén így folyik le a beszélgetés:

rolisoft@ncc1701e:~$ telnet gmail-smtp-in.l.google.com 25
Trying 209.85.212.84...
Connected to mail-vw0-f84.google.com.
Escape character is '^]'.
220 mx.google.com ESMTP 16si12020910vwj.23
HELO rolisoft.net
250 mx.google.com at your service
MAIL FROM: <address-probe@rolisoft.net>
250 2.1.0 OK 16si12020910vwj.23
RCPT TO: <rolisoft@gmail.com>
250 2.1.5 OK 16si12020910vwj.23
QUIT
221 2.0.0 closing connection 16si12020910vwj.23
Connection closed by foreign host.

Ha pedig nem létezik az email cím, akkor:

rolisoft@ncc1701e:~$ telnet gmail-smtp-in.l.google.com 25
Trying 209.85.210.8...
Connected to mail-yx0-f8.google.com.
Escape character is '^]'.
220 mx.google.com ESMTP 8si21418269yxe.0
HELO rolisoft.net
250 mx.google.com at your service
MAIL FROM: <address-probe@rolisoft.net>
250 2.1.0 OK 8si21418269yxe.0
RCPT TO: <nem-regisztralt-cim@gmail.com>
550-5.1.1 The email account that you tried to reach does not exist. Please try
550-5.1.1 double-checking the recipient's email address for typos or
550-5.1.1 unnecessary spaces. Learn more at
550 5.1.1 http://mail.google.com/support/bin/answer.py?answer=6596 8si21418269yxe.0
QUIT
221 2.0.0 closing connection 8si21418269yxe.0
Connection closed by foreign host.

Ezek után teljesen biztos lehetsz, hogy egy email cím létezik, és nem kelletett megerősítő emailt sem küldened a felhasználónak. Meg kell említenem ugyan, hogy ez a módszer sem véd a disposable email szolgáltatások – mint például mailinator.com – ellen, ugyanis ott bármilyen cím el lesz fogadva.

Bemutatóként megvalósítottam PHP-ben a fenti három lépést. Az ékezetes domainek egyelőre nem mennek át a második lépésen, ugyanis a Net_DNS meg a PHP úgy nagyjából eléggé shit és nem támogatja még az ékezetes domaineket.

Próbáld ki:

Morse kódok Console.Beep()-pel

RoliSoft
2010 May 30, Sunday 17:27

Érdekességként írtam ezt a kódrészletet, ami a Console.Beep()-pet hasznossá teszi. Megadsz neki egy üzenetet, azt meg átalakítja morse kóddá és lecsipogja. Hasznos lehet például tanulás céljából, de akármilyen célra fel lehet használni. Mondjuk puskázás céljából.

A függvény pedig a következő: Nem, nem működik szervereken, így ASP.Net-ből nem lehet a szervergépet csipogtatni a szerverteremben. Shit.

// A tábla forrása: http://hu.wikipedia.org/wiki/Morzekód
public static readonly Dictionary<char, string> Table = new Dictionary<char, string>
{
	// latin betűk
	{ 'A', ".-"     }, { 'B', "-..."    }, { 'C', "-.-."   }, { 'D', "-.."    }, { 'E', "."       },
	{ 'F', "..-."   }, { 'G', "--."     }, { 'H', "...."   }, { 'I', ".."     }, { 'J', ".---"    },
	{ 'K', "-.-"    }, { 'L', ".-.."    }, { 'M', "--"     }, { 'N', "-."     }, { 'O', "---"     },
	{ 'P', ".--."   }, { 'Q', "--.-"    }, { 'R', ".-."    }, { 'S', "..."    }, { 'T', "-"       },
	{ 'U', "..-"    }, { 'V', "...-"    }, { 'W', ".--"    }, { 'X', "-..-"   }, { 'Y', "-.--"    },
	{ 'Z', "--.."   },
	// számok
	{ '1', ".----"  }, { '2', "..---"   }, { '3', "...--"  }, { '4', "....-"  }, { '5', "....."   },
	{ '6', "-...."  }, { '7', "--..."   }, { '8', "---.."  }, { '9', "----."  }, { '0', "-----"   },
	// speciális karakterek
	{ '/', "-..-."  }, { '+', ".-.-."   }, { '=', "-...-"  }, { '.', ".-.-.-" }, { ',', "--..--"  },
	{ '?', "..--.." }, { '!', "--.--"   }, { '(', "-.--."  }, { ')', "-.--.-" }, { '-', "-....-"  },
	{ '_', "..--.-" }, { '\'', ".----." }, { ':', "---..." }, { ';', "-.-.-." }, { '$', "...-..-" },
	{ '@', ".--.-." }, { ' ', " "       },
	// magyar ékezetes karaterek
	{ 'Á', ".--.-"  }, { 'É', "..-.."   }, { 'Ö', "---."   }, { 'Ü', "..--"   }, { 'Í', ".."      },
	{ 'Ó', "---"    }, { 'Ú', "..-"     }, { 'Ő', "---."   }, { 'Ű', "..--"   }
};

public static void Morse(string message)
{
	Console.Write(String.Format("Üzenet: '{0}'\r\nMorse : ", message));

	foreach (var codes in from chr in message.ToUpper() where Table.ContainsKey(chr) select Table[chr])
	{
		foreach (var code in codes)
		{
			Console.Write(code);

			switch (code)
			{
				case '.':
					Console.Beep(392, 500); // ti esetén 392 Hz 500 milliszekundumig
					Thread.Sleep(100);
					break;
				case '-':
					Console.Beep(220, 1000); // tá esetén 220 Hz 1 másodpercig
					Thread.Sleep(100);
					break;
				case ' ':
					Thread.Sleep(1000); // szóköz esetén 1 másodpercig kussol
					break;
			}
		}

		Console.Write(" ");
		Thread.Sleep(1000);
	}
}

Egyszerű titkosítás C#-ban a String osztály kibővítésével

RoliSoft
2010 May 24, Monday 23:57

A titkosítás egy nehéz feladat tud lenni kezdőknek és haladóknak is egyaránt. Velem is többször előfordult, hogy C#-ban valamit titkosítani kelletett, éppen ezért írtam egy kis osztályt ami kihasználja az osztályok bővíthetőségét és beszúrja az Encrypt() meg Decrypt() függvényeket a System.String osztályba. Így bármilyen stringre meg lehet majd őket hívni.

A függvények a .Net Framework beépített AES 256 bites algoritmust használják CBC módban és PBKDF2-t jelszó generáláshoz.

public static class EncryptionExtensions
{
    public static string Encrypt(this string secret, string password)
    {
        var raw = Encoding.UTF8.GetBytes(secret);

        var pdb = new Rfc2898DeriveBytes(password,
                                         new byte[]
                                             {
                                                 0x20, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
                                                 0x72, 0x6f, 0x6c, 0x69, 0x73, 0x6f, 0x66, 0x74, 0x2e,
                                                 0x6e, 0x65, 0x74, 0x2f, 0x20, 0x3b, 0x29, 0x20, 0x20
                                             });

        var ms = new MemoryStream();

        var alg = Rijndael.Create();
        alg.Mode = CipherMode.CBC;
        alg.Key = pdb.GetBytes(32);
        alg.IV = pdb.GetBytes(16);

        var cs = new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write);
        cs.Write(raw, 0, raw.Length);
        cs.Close();

        return Convert.ToBase64String(ms.ToArray());
    }

    public static string Decrypt(this string secret, string password)
    {
        var enc = Convert.FromBase64String(secret);

        var pdb = new Rfc2898DeriveBytes(password,
                                         new byte[]
                                             {
                                                 0x20, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
                                                 0x72, 0x6f, 0x6c, 0x69, 0x73, 0x6f, 0x66, 0x74, 0x2e,
                                                 0x6e, 0x65, 0x74, 0x2f, 0x20, 0x3b, 0x29, 0x20, 0x20
                                             });

        var ms = new MemoryStream();

        var alg = Rijndael.Create();
        alg.Mode = CipherMode.CBC;
        alg.Key = pdb.GetBytes(32);
        alg.IV = pdb.GetBytes(16);

        var cs = new CryptoStream(ms, alg.CreateDecryptor(), CryptoStreamMode.Write);
        cs.Write(enc, 0, enc.Length);
        cs.Close();

        return Encoding.UTF8.GetString(ms.ToArray());
    }
}

Használatuk egyszerű, a kód bemásolása után bármilyen stringre meghívhatod őket:

var secretMessage = "Árvíztűrő-tükörfúrógép";

var encryptedMesssage = secretMessage.Encrypt("fl00d-t0l3r4nt m1rr0r dr1ll");
// encryptedMessage = "5qB0JeE+gk+qcT505YwftIxQDnHzhZ/rROW/JGBLbxE="

var decryptedMessage = encryptedMessage.Decrypt("fl00d-t0l3r4nt m1rr0r dr1ll");
// decryptedMessage = "Árvíztűrő-tükörfúrógép"

Cross-Site Scripting in the wild

RoliSoft
2010 May 21, Friday 23:23

A Cross-Site Scripting ma már egy nagyon ismert módszer, és mindenki védekezik ellene. Viszont vannak helyek ahol azt gondolod, hogy nincs minek szűrni az adatot és kiírod úgy ahogy van. Ezzel viszont azonnal megszegted azt az aranyszabályt, hogy don't trust user input.

A rolisoft.net-en már régebb óta állítgatok saját Server headert, eleinte viszont csak rövidebb neveket, mint például "bunch of monkeys", ezúttal viszont kíváncsiságból és érdekességből a következőt állítottam be:

header("Server: <script>alert('hello from rolisoft.net!')</script>");

Teszteljük le a headert:

rolisoft@ncc1701e:~$ wget -S --spider http://rolisoft.net
--20:24:20--  http://rolisoft.net/
           => `index.html'
Resolving rolisoft.net... 69.163.231.16
Connecting to rolisoft.net|69.163.231.16|:80... connected.
HTTP request sent, awaiting response...
  HTTP/1.1 200 OK
  Date: Fri, 21 May 2010 20:24:20 GMT
  Content-Type: text/html; charset=UTF-8
  Connection: keep-alive
  Server: <script>alert('hello from rolisoft.net!')</script>
  Set-Cookie: PHPSESSID=6a9c1ii20c75atbah3sq6j5687; path=/
  Expires: Thu, 19 Nov 1981 08:52:00 GMT
  Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
  Pragma: no-cache

Azok az oldalak amelyek szerver információkat gyűjtenek vagy csak headereket mutatnak, valószínűleg bele fognak esni a csapdába, mivel senki sem gondolt arra, hogy szűrjék a Server mezőt, mikor ideálisan csak a szerver nevét és verzióját kellene tartalmazzák, mint például "Apache/2.2.12" vagy "nginx/0.7.64".

Nos, akkor próbáljuk ki. Az első lesz a kedvenc eszközöm, a hurl.it:

hurl.it xss
Mission accomplished!

Google-ben kerestem még hasonló eszközöket, és a következők XSS-elhetőek még:

Nagyjából az összes eszköz ami a "server header checker" queryre kijön sebezhető. Ouch!

Pár eszköz véletlenül escape-elte a ' karaktert és emiatt a JavaScript nem futott le. Ezt nagyon egyszerűen meg lehet oldani, mindössze nem használunk idézőjeleket az üzenethez:

<script>alert(String.fromCharCode(104,101,108,108,111,32,102,114,111,109,32,114,111,108,105,115,111,102,/*...*/))</script>