IPv6 link-local and VPS-cloud services: an hidden threat?

As many IT folks, I have my VPS (for instance, this website is running on it). I use this virtual server mainly to host my blog and some other websites that I own. The main reason why I use a “server” (and not an “hosting solution”) is that, in this case, I have complete access to the machine. I like to be able to customize my services from top to bottom, even if it’s a simple blog.

The provider (Netsons) is not currently providing any IPv6 connectivity to VPSes. Even my home ISP is not providing IPv6 connectivity. Wonderful…

Some years ago I requested an account and a /48 subnet to Hurricane Electric IPv6 broker service for my house. It’s working very well (consider that it’s a VPN, only that it’s not “private“).

Then, last month I began to play with the network configuration of the VPS to check if everything is ok (I was wondering to request another tunnel for my server), and I discovered that, thanks to Link-Local IPv6 addresses, pretty much every host in my server network was reachable. No firewall, no ACLs.

If you don’t know what is a Link-Local address, let me explain you: there are some standard (one for IPv6, another for IPv6) which allows the host to autoconfigure a network interface with an IP address (IPv4 addresses are in 169.254.0.0/16, IPv6 addresses are in fe80::/64). This is optional in IPv4, but in IPv6 it’s needed for many network services. The way it works it’s quite simple: the host picks a random IP (in case of IPv6, it may use the MAC Address), then query the network if anyone has that IP address (in v4, a simple ARP request is sufficient). If there is a collision, another IP is chosen.

Link-local addresses were invented in order to satisfy the plug-and-play concept: you can plug two or more devices in an unconfigured network (no DHCP, no static IPs, …), yet these devices will be capable to talk each other (for example, a brand new PC and a printer).

Remember: even if your network is not running IPv6 (native or not), this doesn’t mean that your host cannot do IPv6 traffic. So, if you don’t use IPv6 at all (very bad move), you need to disable it completely, or you can configure a firewall rule to block all IPv6 packets.

Cold case: protocol reverse engineering (part 2)

If you missed the previous post, you can find it here.

I was determined to find out which protocol they were mimicking. If you know OSI model (often named ISO/OSI), you already know that each level may (in fact, they do) adds an header (sometimes also a footer) in every Protocol Data Unit (PDU) in a process named “encapsulation“.

So, I ignored the ethernet “type” field and I tried to manually match the protocol by looking at the raw PDU (printed in hexadecimal format in a piece of paper). After some trial-and-error, I found that the PDU was a real-complete IP packet! I haven’t tried the IP protocol as the first one because I thought that they built a custom protocol based on a simpler/older one than IP.

After that discovery, I forced Wireshark to decode it as IP, and also the TCP connection showed up. Counters, addresses and other things that I was supposing before (see previous post) were actually IP and TCP fields (IP addresses, TCP ports, sequence numbers, etc).

I was happy because this was a big step forward. Now we can assume that PDU size (at TCP level) is actually a proprietary protocol. So it comes the hardest part.

I made a number of traces (~200) and I come back to vbindiff to compare TCP data. Note that, as in the previous case, the trace is made with a passive bridge tap and by doing some action on the controller/PLC. Then, every trace is saved with raw capture and “metadata” (the complete environment, eg: what commands are sent by the controller, what actions is performed on PLC, which are the values displayed or set).

What I learned, by doing many comparison (which took me nearly two weeks), is that:

  • The “dual-reply” that we were seeing before the IP decoding were actually TCK ACKs: if the PLC was slow on reply (we’re speaking about milliseconds…), the networking component on PLC were sending ACK replies. Otherwise, if queries data were available immediately, it responds with only one ACK,PSH packet (as standard)
  • The connection is made by two kind of messages:
    • Periodic messages from PLC to the controller (not enabled by default)
    • Controller actions/queries (with relative replies)
  • Message type is an 8-bit field inside the TCP PDU
  • The second byte indicates if the PDU is a reply or a request
  • There are two counters, one used to distinguish between duplicates in dual-ethernet config, another is for duplicates in the same link
  • On value set or get, values are coded in TLV (type-length-value) at the end of the PDU, even the strings and the item ID (which, in this system, is an 8+3 static string, whitespace padded)
  • Floating point values are coded in 4 bytes IEEE 754
  • The endianess is big-endian
  • The FCS field on ethernet was used for a custom counter (maybe something that the controller board uses)

A side node: actually the first thing that I noticed was the floating point value. I still remember the IEEE 754 logic and structure (I’ve studied that in High school, nearly 7 years ago), that helped me because floating point values are stored in a particular (characteristic) format.

There was sufficient data to write a custom software to do tests. But one question remains: how do I simulate a “wrong” ethertype for IP? I was suspecting that the ethertype were modified by the industrial ethernet board (or its driver), so I build my “PLC”-client for Windows and I made it run over the controller. And I was right: every ethernet frame with an IP/TCP connection to the PLC was changed to adjust the ethertype.

After some adjustment and testing, my client was working well (as the original controller) for setting and getting values (not the PLC-programming part yet). But still, how to use another industrial ethernet card with Windows and make it change the ethertype?

With a kernel driver, of course.

The Windows Kernel Driver parabola

I must admit: that was a really impulsive decision. But still, it taught me a lot.

Unfortunately I do not remember a lot – I’m not a Windows fan. I downloaded the whole Windows Driver toolkit and I began to play with some examples. Then, I wrote a simple “network filter” that was doing the same as the board: checking if the connection was for the TCP port of the PLC and change the ethertype field.

The “development-environment” was a pain: two physical machines (why I didn’t use VMs? I tried, but something in Windows kernel didn’t cooperate…) linked with both ethernet and serial connection. There was an option to use ethernet-only, but for some reason it didn’t work at all. The “host” was a simple-plain Windows 7 PC with Visual Studio, the “guest” was a Windows 7 with debug enabled.

As you can expect, with a debugger attached to a kernel you can do pretty much everything: freeze the machine (and then continue the execution), inject drivers, trigger events, and, of course, trigger an Blue Screen Of Death.

The driver was working perfectly – except for only two bugs (which causes some BSODs in tests) that I fixed immediately after the crash. I checked with Wireshark: packets were indistinguishable (I mean, you cannot tell if it was sent by the original controller or my software).

Then, after the tests with my client over the “driver-equipped-machine”, I accidentally launched my PLC client even on the host machine (which didn’t have the driver). And it worked like a charm. WTF? Why?

It turns out that custom ethertype (and so the Windows driver) was not really necessary. Even standard IP ethertype was OK.

See why I say that was an impulsive decision?

Conclusion

After that, I moved all the code into the OPC toolkit to build an OPC driver, so I was able to get/set values by using OPC compliant software, such as the Kepware one.

It took me nearly three months to reverse engineer this protocol. And I’m still asking me how the hell I made it.

Appendix – tools

To summarize tools and usages:

  • Wireshark and tcpdump: used for capturing and decoding packets. Wireshark made this work possible.
  • A binary diff-like software (like vbindiff), if you have a binary protocol to decode, or the standard diff if your protocol is plain-text (like HTTP).
  • A Linux distribution (Debian in this case) with bridge utils: by using the brctl command you can setup a bridge between two (or more) interfaces in a PC.
  • In order to do the bridge, I usually have with me one or more USB-to-Ethernet converter.
  • You may want to disable IPv6, disable Stateless IPv4 config, Zeroconf/Avahi/Bonjour services, DHCP clients, Network managers and other things that immediately do something when you plug a cable in your computer. If you don’t know what will happen, you need to study more in order to know more about what’s running on your computer (eg. your operative system).
  • The previous point is why I use GNU/Linux: I have full control on what is running (and where). By disabling pretty much every automation, you still have a full control of your system without garbage. For example, with Windows you’ll have SMB broadcast packets and things like that.
  • Reverse engineering a protocol is a matter of knowledge, hard work and luck: you need to know your environment perfectly (eg. protocols at each levels, engineering solutions embedded in various standards, etc); you need to do comparison, tests, speculations, inference, hypothesis, [go back to 1] for an unknown time, a lot more that you might expect; and you need to be lucky.

A lot of things that helped me were not coming from networking study: programming skills (I’m a C developer, and I made some small software in assembly), operative system internals, RFC comments about some technical trick in standards (see, for example, RFCs about IEEE 754 and TCP Tahoe/Reno).

Cold case: protocol reverse engineering (part 1)

Some years ago I was asked to do a reverse engineering of an older protocol used in automation systems. The goal was to be able to communicate with some equipment already in-place in some industrial buildings nearby. Let me explain.

Note: at the end of the story I’ll put some commands and techniques that I applied in order to reverse engineer this protocol. If you’re not interested in this story, feel free to subscribe and wait for the last part you can find the second post here.

Some background

In industrial sector, automation is everything. Either long or short processes are automated nowadays: there are many mechanical devices controlled by one or more PLCs (Programmable Logic Controller). Today PLC is a sort of “dedicated-computer”. Each PLC is connected to an automation network via fieldbus-protocols, such as PROFINET (over Industrial Ethernet).

Usually PLCs have some logic (for example, open valve X if temperature Y is raising), but of course your building process may require many variables and on-the-fly changes, so they’re constantly connected to one (or more) server, named supervisor. This system is called DCS, or Distributed control system, or SCADA, Supervisory control and data acquisition. Many PLCs with logic, some control stations (for local operators) and some supervisors.

With the same system you can acquire, store and manipulate data regarding the build process: for example, quantities of chemical compound, temperatures, timing.

Some of these systems (mostly the older one, the DCS) uses proprietary protocols to talk between PLC and supervisors, and offers no APIs. SCADA systems often uses standards protocols (as alternative with proprietary ones) and/or APIs thru OPC drivers.

Times go by

Times go by, for everything. In this case, I had my hands on a 15-years-old system, with a spare PLC and a spare supervisor (as the real system is still in use, and producing). The PLC was equipped with some digital and analog I/O boards. It was working perfectly: the PLC logic was ok, the supervisor was supervis-ing, etc.

So, why I was there? Because the supervisor had one big issue: it runs on Windows 2000. And there was no way to make software work with newer systems nor accessing/interfacing with some driver. Of course, there was an easy way to solve this: dismantle everything and rebuild the building chain with newer hardware. In short, replace fully-functional hardware (and software) with a new product (which may have some issues, who knows).

You would agree with me by thinking that rebuild the chain was a big waste of time, money and hardware.

So my job was find a way to interface PLCs with a newer system.

Ground truth

I had little clues. All that I had was:

  • An OPC devkit to write a driver which talks OPC (an open standard SCADA-compatible)
  • The PLC and the supervisor in my hands

The first thing that I noticed is that the supervisor and the PLC were connected with two (distinct) cables that looked like industrial ethernet cables. Pin mapping and some tests revealed that I was right: interfaces were ethernet. That might be consistent with some sort of ancient PROFINET drafts. At least, I was hoping that.

So the first step was doing a man-in-the-middle “attack”: with a dual-ethernet workstation, I made a passive-tap-bridge and I put the workstation in the middle of supervisor-PLC connection. A passive-tap-bridge is an ethernet bridge with some features:

  • No change on packets (no firewall, etc)
  • No Spanning Tree Protocol, loop protections or something like that
  • Promiscuous interface set
  • No IP address or something like that
  • and Wireshark, of course

A side note: the PLC was connected with both cables (for redundancy purpose), so I took offline the second cable to force the supervisor and PLC to talk with me listening on the first link.

I wasn’t lucky enough. The data stream that I expected was something like a TCP/UDP connection of some sort. Instead, I had a bunch of Ethernet II frames with unknown data.

I made some hypothesis:

  • The protocol was too old for some sort of encryption (so, no encryption)
  • I was looking at the raw data of a proprietary protocol
  • OR, there was some sort of proprietary weak encryption for higher protocols than Ethernet

It’s not uncommon to see direct-to-ethernet C&C protocols. So I started to analyze some frames.

The analysis (part 1)

At first look, no clue. There were two strings of 3 chars (maybe some sort of “magic” for that protocol, or maybe some random coincidence) in many frames. Also, layer 2 protocol 0x8275 said nothing to me. So I collected some data streams between supervisor and PLC (by query the PLC from the supervisor’s software), extracted the ethernet payload and I started to analyze it with vbindiff, a diff-like tool that deals with binary files.

I noticed that there were some bytes incremented linearly, like a counter. Other bytes instead were swapped if the direction was the opposite (eg. on PLC response). That might indicate some sort of addressing (it makes sense). Then, the value that I was querying was probably at the end of the frame, because a change on the PLC side was reflected by a change (somehow) at the end of the ethernet payload. But it was not linear (consistent with real changes), so no idea how that value was calculated.

To recap, this analysis told me that:

  • The protocol was not encrypted – eg. if it had been encrypted I would not have seen the same bits, in the same place, between two messages.
  • There was some sort of counter: usually this is made to avoid duplicating packets at the destination, and to provide flow-control/retransmissions/etc. So at least one of these mechanism were in place.
  • There was some sort of addressing scheme (with at least 1 byte)
  • That two cables were meant to be used with two separated networks, but they were transmitting the same data (for redundancy purpose)
  • Each command (eg. set this value to X) requires at least 1 reply. Usually 2.
  • The Ethernet FCS (Frame Check sequence) was wrong. In each frame.

With 50-60 traces (with various commands and replies each), I started to look for correlations between these bytes in different frames.

One thing that I noticed after some hours of digging is that, when there were two replies, the first one was somehow really small. Then, analyzing more I discovered that there was another short (16bit) value that was swapped between two frames of the same transmission. Last conclusion collides with the addressing scheme assumption said before, so I was really unhappy.

I tried to do some interesting thing, such as byte conversions and endianess swapping. There was no clue until I found something caught my attention: swapping the cable results in a change on a byte before the “address-byte” we mentioned before. So it might indicate some sort of 2-byte addressing scheme or subnetting thing.

After a week of testing, I was about to surrender. There was something familiar with all these bits, but I didn’t know what.

Then, I had somehow a breakthrough: what if that is a subset (or custom version) of a wide-used protocol?

(go to part 2)

Mikrotik: how to use hostnames in firewall rules (instead of IP addresses)

Althrough the IP layer doesn’t carry the hostname used to send that packet (in fact, may not exists, because DNS is higher in ISO/OSI stack), some firewall allows DNS hostnames in “Source” or “Destination” fields. It might be useful in many situations: a fast TTL (for example, NTP Pool project hostnames, “pool.ntp.org”), a dynamic IP address associated to the hostname, a round-robin record with many IPs that might change often (CDN, load balancers, etc). So, how these firewalls can discriminate if there is no such info at IP layer?

A very ugly hack that works

In fact, they don’t. Instead, they resolve each hostname at regular interval (smarter firewall uses TTL DNS field) and use the result (IP addresses of course) to build the firewall rule. A very ugly hack.

If you wonder if there is any other solution for these requirements, the answer is no, AFAIK.

Doing this on Mikrotik routers

Mikrotik RouterOS firewall is an iptables-based firewall, so there is no embedded support to this trick (it might be supported on a fully-fledged OS with some iptables module, but this is not the case).

RouterOS has a “scripting language” to achieve some automations. With this simple script, we exploit the embedded resolver and cache to popolate firewall address-lists.

:local hosts {"it.pool.ntp.org"; "time.nist.gov"; "0.debian.pool.ntp.org"; "1.debian.pool.ntp.org"}
:foreach k,v in=$hosts do={
  :log info "Doing $v"
  :local listname $v
  :resolve $v
  :local iscname [/ip dns cache all find where name=$v and type="CNAME"]
  :if ($iscname != "") do={
    :local newname [/ip dns cache all get $iscname data]
    :log info "$v is CNAME to $newname"
    :set v $newname
  }
  :resolve $v
  /ip firewall address-list remove [/ip firewall address-list find where list=$listname]
  :foreach i in=[/ip dns cache all find where name=$v and type="A"] do={
    :local ipaddr [/ip dns cache all get $i data]
    /ip firewall address-list add list=$listname address=$ipaddr comment=$v
    :log info "IP address: $ipaddr"
  }
  /ipv6 firewall address-list remove [/ipv6 firewall address-list find where list=$listname]
  :foreach i in=[/ip dns cache all find where name=$v and type="AAAA"] do={
    :local ipaddr [/ip dns cache all get $i data]
    /ipv6 firewall address-list add list=$listname address=$ipaddr comment=$v
    :log info "IPv6 address: $ipaddr"
  }
}
:log info "end"

Let’s explain:

  • The first step is to define the host list (first row): a simple array of hostnames. This script will create the address-lists with these names (either in IPv4 and/or IPv6 firewall)
  • If the hostname is a CNAME, the script resolves the pointed hostname (just as expected from a DNS resolver)
  • All IPs (for every hostname) that are in DNS cache (due to “:resolve”) are copied into the relevant address-list (that is temporarly cleared before this step)

Many other Mikrotik scripts exists for that, but every script has some flaws: the main one is that everyone use “:resolve” to get IP address (but “:resolve” only returns one ip address, even if the hostname has multiple IPs). This script instead is capable to get all IPs (4 or 6).

How to use

Copy this script in RouterOS system scripts, modify the first line (for hostnames to be resolved) and schedule this script to run at regular intervals. After the first execution you’ll have the lists populated, and then you can modify firewall rules.

Please mind that “:resolve” on Mikrotik throws uncatchable errors: if the hostname doesn’t exists, this script will stop at some point, leaving some items not updated.

IoT party: installing InfluxDB (+Grafana) on a Raspberry PI for IoT sensors

Last year I upgraded my solar water panels with some temperature probes, and I scattered NodeMCU in my house (with some DHT22 and DHT11 sensors). At the time I had an old PC that was acting as a server: IoT devices were sending readings to RabbitMQ instance on that server, with a shell script that was bridging between MQTT and RRDTool database.

Of course, for me that was perfect. But I when I tried to share these tools with my family, quickly became clear that I had to make a nice interface. I ended up by sending the chart by Telegram with a bot.

Then, during last month, the old server died. I moved some things to the cloud, and some other things were archived. After some free-time during cleanup (I had two 1TB disks to cleanup…) I landed into Grafana home page. And I decided to give it a try.

Continue reading “IoT party: installing InfluxDB (+Grafana) on a Raspberry PI for IoT sensors”

Raspberry PI bluetooth backdoor/serial access

Aka: install a safe-mode-access.

I was programming my RasPI 3 to be a Wi-Fi AP. I don’t have an HDMI monitor, only an HDMI converter and I’m not happy to use it. So, I was trying to setup my RPI by SSH. Of course, I was locked out by a wrong command in a script.

So, I was looking for an off-road access. RPI has an embedded WiFi and Bluetooth chipset. I’m using an USB WiFi dongle (because RPI chip doesn’t support multiple SSID), so I can use both.
I prefer Bluetooth over embedded Wi-Fi for one reason: if I broke some other things (like routing),
I still have a way in (using a Serial bluetooth connection).

I’m using the latest (2017-07-05) Raspbian Lite image. Based on stretch I presume, because there is SystemD that is really annoying.

To initialize bluetooth connection, we need to add this unit to systemd:

[Unit]
Description=Bluetooth Backdoor

[Service]
ExecStart=/opt/backdoor.sh

[Install]
WantedBy=multi-user.target

(yes, the script is named “backdoor” for a reason)
Now we need the script itself:

#!/bin/bash
expect -f /opt/bluetooth.exp
sdptool add SP
/usr/bin/rfcomm watch rfcomm0 1 /sbin/agetty --noclear rfcomm0 38400 linux

Then, we need the expect file for bluetoothctl:

spawn bluetoothctl
send "power on\r"
expect "\[bluetooth]# "
send "agent on\r"
expect "\[bluetooth]# "
send "discoverable on\r"
expect "\[bluetooth]# "
send "default-agent\r"
expect "\[bluetooth]# "
send "quit\r"

Save these three files. Then, launch bluetoothctl and pair/trust your device. Then:

# systemctl enable backdoor.service

That’s it. You can connect to it using (on another PC):

$ sudo rfcomm connect rfcomm0 AA:BB:CC:DD:EE:FF 1

And then using some terminal emulator (minicom) on

/dev/rfcomm0

(speed 38400).

You may need to add “–compat” to “ExecStart” for unit “bluetooth.service” in order to enable SDP (you can check by launching “sdptool browse local”: if you see an error, you need to edit that systemd unit and then restart the daemon)

Superficie d’attacco (informatico)

La “superficie d’attacco” è l’insieme dei possibili punti di un software/sistema/infrastruttura che sono più o meno accessibili da un eventuale attaccante. E’ fondamentale quindi conoscere e gestire la superficie d’attacco della nostra infrastruttura informatica.

La prima azione da fare è quella di individuare i servizi disponibili dal sistema che stiamo studiando. Questo ovviamente va fatto verificando quelli che sono veramente attivi sul sistema. Inoltre, vanno considerati tutti quei servizi che non sono in ascolto diretto (come potrebbe fare, ad esempio, un server web su una porta TCP), ma anche quei servizi che si connettono verso l’esterno del sistema o che comunque interagiscono in qualche modo in base al traffico che transita sulla scheda di rete (ad esempio, se abbiamo sistemi che passivamente monitorizzano la scheda di rete per statistiche sui flussi, dobbiamo considerare anche quei servizi). Se il sistema è dotato di firewall, IDS o IPS, anche questi vanno considerati come servizi.

Per ognuno di questi servizi, dobbiamo individuare i possibili flussi dati, individuando ogni dispositivo (router, firewall hardware/software, etc) che si pone tra l’eventuale attaccante ed il nostro sistema. Poiché gli attacchi possono arrivare da più punti (internet, altri server, client aziendali, etc) è necessario quindi dividere l’esame in più sezioni, ognuna con la specifica della porzione di superficie esposta. Questo ci permette di individuare correttamente quali servizi sono esposti rispetto a quale “area” esterna al nostro sistema (è possibile infatti che un servizio non sia esposto perché un firewall è configurato per bloccarlo).

A questo punto, per ogni servizio, dobbiamo individuare le possibilità che offre ad un attaccante in termini di:

  • Information disclosure: dobbiamo valutare quante informazioni il servizio espone (con o senza richieste dirette da parte del client); ad esempio, un server web potrebbe esporre la versione e le librerie compilate (esempio da una pagina di errore di un sito internet):

    Apache/2.2.9 (Debian) PHP/5.2.6-1+lenny16 with Suhosin-Patch mod_ssl/2.2.9 OpenSSL/0.9.8g Server at www.website.it Port 443

    Ovviamente tali informazioni sono eccessive: un attaccante può determinare le vulnerabilità molto più facilmente.

  • Authentication bypass: valutare quanto il sistema è robusto in termini di controllo di autenticazione (per questo ci possono essere utili le CVE presentate sotto)
  • Denial of service (DoS): quali sono le opzioni lasciate ad un attaccante nel momento in cui il servizio è non disponibile (ad esempio, se al fallimento di un servizio viene aperta una porta o viene lanciato un automatismo che aumenta o cambia la superficie d’attacco, ad esempio lanciando un altro software)
  • Remote code execution (RCE): in caso di RCE, quali sono le possibilità che ha un attaccante di eseguire delle azioni utilizzando, come “ponte”, il servizio: se il suddetto servizio gira con un utente, ogni cosa che può fare quell’utente (eliminare/creare file, aprire connessioni, etc) fa parte della superficie d’attacco in caso di RCE
  • CVEs: sono bollettini per la sicurezza. E’ fondamentale controllare se le versioni dei software utilizzate nei sistemi hanno vulnerabilità già note. Le vulnerabilità note cambiano notevolmente il “peso” di una singola componente del sistema nella superficie di attacco, poiché la documentazione sulla vulnerabilità ora è disponibile al pubblico.

Infine, individuata l’ampiezza della superficie e gli attori in essa, dobbiamo stabilire:

  • Le regole corrette in base a quelle che sono le reali necessità (ad esempio, eliminare la possibilità di accesso ad un servizio da una zona che non ne ha bisogno) usando il principio di least privilege: consentire solo i servizi necessari (bloccando il resto) al minimo livello di accesso possibile.
  • Le regole per limitare il “danno” causato da uno dei punti appena visti (RCE, DoS, etc.), posizionando firewall applicativi, sistemi di contenimento, etc.

La complessità di tutto questo può sembrare eccessiva per lo status quo in una azienda, ma la regola d’oro è sempre di considerare questo “costo” (anche in termini di tempo) un investimento rispetto al costo della perdita catastrofica dei dati e dei sistemi (causata da un attaccante). In altre parole, dobbiamo investire in sicurezza tanto quanto siamo disposti a pagare per riavere indietro tutti i dati (e l’infrastruttura) qualora venisse presa in ostaggio da un malvivente.

Tessera da socio del circolo vizioso

Ieri, un torrido 10 di Agosto, mi sono unito a Salvatore Antoci in un lavoretto di manutenzione “ordinaria”: la riparazione di una panchina (qui le foto di prima e dopo). Ovviamente non facciamo parte della “squadra di manutentori del Comune”.

Durante la riparazione, diverse persone ci guardavano, qualcuno si è avvicinato e qualcuno si è complimentato con noi per il lavoro che stavamo facendo. E ci hanno anche indicato la prossima panchina da riparare. Quello che non ho realizzato subito, e che il buon Salvatore mi ha fatto notare, è di quanto sia “strano” vedere la “manutenzione”.

Finita la riparazione, mi sono girato intorno e ho notato l’enorme quantità di immondizia presente nel parco. Certo, fior fior di commentatori, politici e “giornalisti” si affrettano a commentare la vicenda dell’azienda speciale sui servizi, ma nessuno si è mai chiesto, in tutti questi anni: qual è il danno, non economico, ma culturale, delle varie azioni messe in atto dai vari soggetti in campo (politici/amministratori/…)?

Eccolo il danno culturale: le persone che gettano i rifiuti nel proprio parco. Le persone che, vedendo qualcosa divelta o distrutta (vedi la panchina), non spingono perché venga riparata (o si alzano le maniche e si dan da fare), ma lasciano i loro commenti arrabbiati su Facebook con chiunque (tanto, per l’Italiano medio, la colpa è sempre di qualcun altro) e passano sopra e di fianco a questo squallore senza sentirsi in colpa. Anche quando questo squallore lo hanno davanti casa.

Il problema è che questi comportamenti sono una massa critica d’attrazione, un polo magnetico per altri comportamenti negativi: prima è la carta del pacchetto di sigarette, poi il fazzoletto, poi quella del panino, poi passa qualche teppista che rompe un vetro e distrugge una panchina. Mancando il controllo, quindi, il teppista evolve in qualcosa di più grande, commette crimini maggiori, e la legalità sparisce. E’ un pericolosissimo circolo vizioso, in cui ogni persona che ignora la singola carta per terra è inserito e lo alimenta.

“Secondo me gli italiani al bar, sono tutti dei grandi statisti, ma quando vanno in parlamento, sono tutti statisti da bar.”
Giorgio Gaber

La fervida ed immediata (??) risposta dei cittadini è stata quella di indignarsi: in principio al bar, quindi sul sito www.q4q5.it, ora siamo passati a Facebook e domani chissà dove, ma sempre con la qualità delle chiacchiere da bar. Questa è la “tessera del socio iscritto al circolo vizioso“. Un club, purtroppo, con molti iscritti.

E l’attuale amministrazione? Di sicuro, tra i lettori, ci sarà chi mi avrà già etichettato come “uno di LBC” perché non ha detto che è colpa anche loro; e ci sarà anche chi, all’opposto, dice che “vedi? è la prova che la colpa è anche di LBC“. Perché un’altra cosa che non sappiamo fare in Italia è capire come funzionano le cose: vogliamo che qualcuno agiti la bacchetta magica e risolva i problemi. E senza romperci le scatole nel frattempo.

Ebbene, io non so se LBC sta cambiando, cambierà o no, le cose. Quello che so è che, in primis, decenni di autodistruzione della cultura non si riparano in 12 mesi. E, in secondo luogo, che se vogliamo che le cose cambino, dobbiamo prima cambiare noi. A prescindere dai governi.

Siamo pronti a cambiare? Bella domanda. Cambiare significa rispettare ogni legge, ogni regolamento, da “non rubare“, al “buttare la carta dentro l’apposito contenitore“. Significa parcheggiare solo dove è consentito; buttare la busta della differenziata solo dove e quando è previsto, significa farsi fare lo scontrino sempre e comunque, anche se si paga di più. Perché la cultura della legalità non è un prodotto, è un processo.

Too much confidence in user input: the Gemtek WLTXFSQ-102N case

Yesterday I was having a break from studying for next exam. I had few minutes of free time, so I decided to spend that time going around inside the web interface of Gemtek WiMax/4G router that my ISP installed here. I had a “guest” account, as specified in the router’s manual.

During my “exploration” of router’s web interface I landed into “utility” web page. As usual, “utility” means “ping” and “traceroute“, nothing more. Usually, these utilities are installed as executable in router’s firmware (sometimes with busybox package), and very often web developers use these executables instead of reinventing the wheel.

Both tests (“ping” and “traceroute”) need a destination: host name or IP address. What if I insert a different thing?

Input sanitization

The golden rule for web programming is: don’t trust user’s input (actually I think that is the golden rule for everything in IT…).

I choose “ping” test. The “destination” input is protected by a Javascript that doesn’t allow me to proceed if the field doesn’t match a specific set of regular expressions. Let’s disable that check (very easy to do with Firefox/Chrome developer tools) and test some inputs:

www.google.it;ls

It doesn’t work (the output shows: “unknown host www.google.it;ls“). I was hoping that the field was appended as raw text to ping CLI utility. That’s not the case: apparently, the field is quoted with single or double quote. So let’s try with:

www.google.it';ls

Nope. Even with double-quote. Apparently the double-quote gets replaced (from server) with single-quote. So, we can assume that the web interface is launching the ping utility with destination into double-quote. Let me try something stupid:

www.google.it$(ls)

Bingo!ls” is executed, and the output is appended to ping as destination argument. That’s not a problem, because we can see the error message (“unknown host: …“) with the full output of “ls“. Ok, let’s check how the web interface is running these commands:

www.google.it$(ps)

the output is

 1399 root sh -c (ping -4 -c 5 -s 64 -W 10 "www.google.it$(ps)" > /tmp/mon_diag.log 2>&1)&

Wait a moment! We’re running as root! In fact, I was able to launch a telnet daemon and acquire a full root shell access. Then, I was able to download and decrypt some critical files, such as /etc/passwd and /etc/shadow.

How to avoid that?

The key concept is “input sanitization“. You should clean (or reject) user input server-side with a very specific filter. Are you planning to have an hostname? You should remove all chars that are not in DNS specifications. Then remote all problematic characters (if any) such as $ (dollar sign), ` (backtick) and others.

Another layer of security is executing programs with the “least-privilege” concept: you should enforce software to run with the minimum subset of privileges. If you don’t need to be root to ping, don’t be. If you don’t need “telnetd”, negate execution/access/remove from firmware.

Implementing both these best pratices will render this attack impossible.

A word about NSA/CIA

Yes, this kind of attack can be useful to NSA/CIA/hackers to hack your router and install a spyware into it. You should reduce your attack surface: change router default passwords and parameters, learn how to do it. Protect your own PC even in home network. Install a firewall, configure it. Keep your PC’s software up-to-date.

HCI-Sec: la sicurezza passa anche dalla Human Interface

Anche se non è immediato, è chiaro che la sicurezza informatica passa anche per la HCI (Human Computer Interaction). Il modo in cui sono progettati i sistemi di sicurezza influenzano in maniera sostanziale l’efficacia dei suddetti.

Facciamo un esempio? Come ricorda il blog della sicurezza di Sophos, far scadere le password in modo cadenzato, senza motivo, non ha più senso. Anche le vecchie “regole” iniziano a decadere, come i caratteri richiesti. Meglio frasi lunghe, meglio 2FA e altre tecniche più user-friendly.

Per un utente ricordarsi una password complessa, composta da lettere maiuscole e minuscole, caratteri speciali e numeri, è molto complesso: finisce per scriverla su un post-it vicino al monitor, sotto la tastiera e/o finisce ad usare sempre la stessa password (cambiando, ad esempio, un solo carattere finale, spesso con il numero).

L’autenticazione a due fattori, quando necessaria, rende il sistema molto più resistente: la conoscenza della sola password non basta, serve anche avere qualcosa dell’utente (spesso il telefono).

Inoltre dovremmo configurare i sistemi di autenticazione per essere molto più intelligenti: dovrebbero essere capaci, come fanno alcuni (Google in testa), di distinguere i PC utilizzati in passato e spesso, e fare controlli ulteriori sugli accessi non usuali (IP, orario, posizione geografica). Un po’ come alcune banche fanno con gli acquisti con le carte: se c’è un movimento fuori dal “normale” per l’utente in questione, lo chiamano chiedendo se è tutto nella norma. Se l’operazione è fraudolenta, può essere bloccata immediatamente.

L’eccesso di controlli, di barriere di accesso, specialmente di tutti quei controlli invasivi, portano gli utenti a trovare delle “scorciatoie” che, di fatto, bypassano (passatemi il termine) il livello di protezione e sicurezza desiderato. La sicurezza deve diventare un processo trasparente, deve richiedere (da parte dell’utente) meno interazione possibile.