sobota 12. listopadu 2016

Sniffování provozu na šifrované WiFi

Jistě se Vám už stalo, že jste měli nějaké IoT zařízení s neznámým protokolem, obyčejnému uživateli to může stačit. Ale hračička si říká, jaká data se mimo jiné z mého zařízení odesílají a co by se s nimi dalo dělat. Nebo proč si rovnou neudělat sběrný portál sám a třeba lépe ... Máme tedy zařízení, které se připojuje do sítě, ke které známe šifrovací klíč a pouze Androidovskou aplikaci pro ovládání, jak tedy zkoumat komunikaci z dalšího počítače? Ještě, že existuje promiskuitní režim ovladačů WiFi karet, stačí jen spustit Linuxové LiveCD (LiveUSB), v našem případě Kali Linux, a postupovat podle dále popsaného návodu (založeného na překladu článku, viz zdroj).

Pustíme příkazový řádek a zadáme příkaz iwconfig, ten nám zobrazí všechna dostupná rozhraní, v našem případě nás zajímá wlan0 a vůbec nám nevadí, že není připojeno k žádné wifi síti (ba naopak).


 Dále pustíme airmon, příkazem airmon-ng start wlan0, to se nám patrně na poprvé nepodaří, nejprve je nutné killnout procesy, které nám wlan0 blokují pro sebe.



V tomto případě stačí zadat kill [PID_procesu], tedy kill 3004 atd.



A nyní už máme rozhraní jen sami pro sebe, pustíme si tedy monitor. airmon-ng stop mon0


A nyní si můžeme v příkazové řádce dumpnout komunikaci nebo si ji rovnou zobrazovat ve WireSharku. Pro nahrávání využívám airodump-ng mon0 --channel [číslo_wifi_kanálu] -w log.pcap, kde mon0 definuje rozhraní na kterém airodump naslouchá, channel definuje kanál wifi a přepínačem w říkáme, kam nasniffovaná data ukládat.
Další možností je otevřít rozhraní mon0 ve WireSharku, je potřeba zkonrolovat, zda máme zapnutou volby promiscuous a monitor mode.
Při výchozím nastavení se nám budou ve WireSharku zobrazovat jen 802.11 rámce, což je logické, protože WireShark pro jejich rozšifrování nemá klíč (viz obrázek z příkladu).


Na stránkách dokumentace k WireSharku (druhý odkaz) je možné stáhnout příklad, tedy nasniffovanou komunikaci sítě s názvem SSID  Coherer a heslem Induction. Pro rozšifrování musíme do nastavení Edit -> Preferences... a v záložce Protocols vybereme IEEE 802.11. Zde stačí povolit dešifrování (Enable decryption) a zadat šifrovací klíč.


A nyní už máme komunikaci, tak jako bychom ji poslouchali přímo na Ethernetu.



https://documentation.meraki.com/MR/Monitoring_and_Reporting/Capturing_Wireless_Traffic_from_a_Client_Machine
https://wiki.wireshark.org/HowToDecrypt802.11

pondělí 14. března 2016

Bulid jaderného balíčku pro hwmon

Nejprve je třeba naklonovat verzi OpenWRT pro aktuálně používané jádro. Pomocí příkazu git tag, se nám zobrazí seznam "otagovaných" verzí. Pro verzi Turris OS 2.8 je to vyznačené vydání deploy-2015-12-18.

$ git tag
deploy-2014-04-24
deploy-2015-11-25
deploy-2015-12-18
gen-certuma-0.v1
gen-certuma-0.v2
hotfix-2015-08-18
upstream-merge-2014-06-27

A když už máme představu, jakou verzi požadujeme, tak si ji prostřednictvím checkout můžeme stáhnout.


git checkout deploy-2015-12-18

Nyní necháme jádro přeložit, tak aby se nám stáhly všechny zdroje. Při tvorbě balíčku jsem vycházel z kmod-hwmon-sht21, ten je nutné povolil v make menuconfig (podmenu Kernel modules -> Hardware Monitoring Support).

Soubor příkladu by měl pro jedno zařízení vytvořit dva virtuální soubory, které při čtení vrací inkrementující se hodnoty, viz následující soubor pokus.c.

#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/device.h>
#include <linux/jiffies.h>

/**
* struct pokus - pokus device specific data
* @hwmon_dev: device registered with hwmon
* @lock: mutex to protect measurement values
* @valid: only 0 before first measurement is taken
* @last_update: time of last update (jiffies)
* @number1:
* @number2:
*/
struct pokus
{
        struct device *hwmon_dev;
        struct mutex lock;
        char valid;
        unsigned long last_update;
        int number1;
        int number2;
};

/**
* pokus_show_number1() - return value in sysfs
* @dev: device
* @attr: device attribute
* @buf: sysfs buffer (PAGE_SIZE) where measurement values are written to
*
* Will be called on read access to number1 sysfs attribute.
* Returns number of bytes written into buffer, negative errno on error.
*/
static ssize_t pokus_show_number1(struct device *dev, struct device_attribute *attr, char *buf)
{
        struct pokus *pokus = dev_get_drvdata(dev);
        /*int ret;

        ret = pokus_update_measurements(dev);
        if (ret < 0) return ret;*/
        return sprintf(buf, "%d\n", pokus->number1++);
}

/**
* pokus_show_number2() - return value in sysfs
* @dev: device
* @attr: device attribute
* @buf: sysfs buffer (PAGE_SIZE) where measurement values are written to
*
* Will be called on read access to number1 sysfs attribute.
* Returns number of bytes written into buffer, negative errno on error.
*/
static ssize_t pokus_show_number2(struct device *dev, struct device_attribute *attr, char *buf)
{
        struct pokus *pokus = dev_get_drvdata(dev);
        /*int ret;

        ret = pokus_update_measurements(dev);
        if (ret < 0) return ret;*/
        return sprintf(buf, "%d\n", pokus->number2++);
}

/* sysfs attributes */
static SENSOR_DEVICE_ATTR(number1, S_IRUGO, pokus_show_number1,
        NULL, 0);
static SENSOR_DEVICE_ATTR(number2, S_IRUGO, pokus_show_number2,
        NULL, 0);

static struct attribute *pokus_attributes[] =
{
        &sensor_dev_attr_number1.dev_attr.attr,
        &sensor_dev_attr_number2.dev_attr.attr,
        NULL
};

static const struct attribute_group pokus_attr_group = {
        .attrs = pokus_attributes,
};

static int pokus_probe(struct i2c_client *client,
        const struct i2c_device_id *id)
{
        struct pokus *pokus;
        int err;

        if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA))
        {
                dev_err(&client->dev, "adapter does not support SMBus word transactions\n");
                return -ENODEV;
        }

        pokus = devm_kzalloc(&client->dev, sizeof(*pokus), GFP_KERNEL);
        if (!pokus) return -ENOMEM;

        i2c_set_clientdata(client, pokus);

        mutex_init(&pokus->lock);

        err = sysfs_create_group(&client->dev.kobj, &pokus_attr_group);
        if (err) {
                dev_dbg(&client->dev, "could not create sysfs files\n");
                return err;
        }
        pokus->hwmon_dev = hwmon_device_register(&client->dev);
        if (IS_ERR(pokus->hwmon_dev)) {
                dev_dbg(&client->dev, "unable to register hwmon device\n");
                err = PTR_ERR(pokus->hwmon_dev);
                goto fail_remove_sysfs;
        }

        dev_info(&client->dev, "initialized\n");

        return 0;

fail_remove_sysfs:
        sysfs_remove_group(&client->dev.kobj, &pokus_attr_group);
        return err;

}

/**
 * pokus_remove() - remove device
 * @client: I2C client device
 */
static int pokus_remove(struct i2c_client *client)
{
        struct pokus *pokus = i2c_get_clientdata(client);

        hwmon_device_unregister(pokus->hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &pokus_attr_group);

        return 0;
}

/* Device ID table */
static const struct i2c_device_id pokus_id[] =
{
        { "pokus", 0 },
        { }
};
MODULE_DEVICE_TABLE(i2c, pokus_id);

static struct i2c_driver pokus_driver =
{
        .driver.name = "pokus",
        .probe       = pokus_probe,
        .remove      = pokus_remove,
        .id_table    = pokus_id,
};

module_i2c_driver(pokus_driver);

MODULE_AUTHOR("JFila <jfila@xxx.cz>");
MODULE_DESCRIPTION("Pokus driver");
MODULE_LICENSE("GPL");



Do Kconfig doplnit následující definici (build_dir/target-powerpc_8540_uClibc-0.9.33.2/linux-mpc85xx_p2020-nand/linux-3.10.49/drivers/hwmon/Kconfig)

config SENSORS_POKUS
tristate "JFíla pokus driver."
depends on GPIOLIB
help
Pokusný balíček pro hwmon

Do Makefile (build_dir/target-powerpc_8540_uClibc-0.9.33.2/linux-mpc85xx_p2020-nand/linux-3.10.49/drivers/hwmon/Makefile) přidat binárku s názvem balíčku (pokus.o)

obj-$(CONFIG_SENSORS_POKUS) += pokus.o

A hwmon.mk také doplnit popis balíčku a jeho závislostí. (package/kernel/linux/modules/hwmon.mk)

define KernelPackage/hwmon-pokus
  TITLE:=pokus device for test
  KCONFIG:=CONFIG_SENSORS_POKUS
  FILES:=$(LINUX_DIR)/drivers/hwmon/pokus.ko
  AUTOLOAD:=$(call AutoProbe,pokus)
  $(call AddDepends/hwmon,+kmod-i2c-core)
endef

define KernelPackage/hwmon-pokus/description
 Kernel module for pokus device (for test only)
endef

$(eval $(call KernelPackage,hwmon-pokus))

Hotový modul můžeme instalovat jako balíček ale pozor na hash jádra, pro otestování stačí pokus.ko nakopírovat do /lib/modules/3.10.49-xxxxx

Zavedeme modul do jádra a je to:

root@JFila:/# insmod pokus.ko
root@JFila:/# lsmod | grep pokus
hwmon                    990  3 pokus
pokus                   1468  0

Nyní by již mělo stačit vytvořit nové zařízení:

root@JFila:/# echo pokus 0x27 > /sys/bus/i2c/devices/i2c-1/new_device
root@JFila:/# cd /sys/bus/i2c/devices/
0-004c/  0-006f/  1-0027/  1-0040/  i2c-0/   i2c-1/   i2c-2/
root@JFila:/# cd /sys/bus/i2c/devices/1-0027/
root@JFila:/sys/devices/soc.0/ffe03100.i2c/i2c-1/1-0027# ls
driver     hwmon      modalias   name       number1    number2    power      subsystem  uevent

A čtením number jedna bychom měli získávat inkrementující hodnotu:

root@JFila:/sys/devices/soc.0/ffe03100.i2c/i2c-1/1-0027# cat number1
0
root@JFila:/sys/devices/soc.0/ffe03100.i2c/i2c-1/1-0027# cat number1
1
root@JFila:/sys/devices/soc.0/ffe03100.i2c/i2c-1/1-0027# cat number1
2
root@JFila:/sys/devices/soc.0/ffe03100.i2c/i2c-1/1-0027# cat number1
3

https://blog.root.cz/posvic/jak-napsat-ovladac-pro-zarizeni-usb-pro-linux/