Friday 8 December 2017

Wake on lan (WOL) from Microsoft SCCM through Cisco Layer3 Switches

How to securely forward wake-on-lan packets from remote subnets through Cisco layer 3 switches

To facilitate software deployments, we need to wake PCs up from the deployment server. As the server uses directed broadcasts to the destination subnet, this fails in any reasonably secure network.

In our scenario, the SCCM server resides in VLAN10, while the destination PC lives in VLAN20. The SCCM server sends a "magic packet" to 192.168.20.255. This packet will normally be discarded by the router / L3 switch.

To be a bit more obscure, we have choosen port 12287. During the tests it seemed like the packet needed to be allowed in several ways:

  1. explicitly enable forwarding for udp 12287
  2. explicitly allow such a packet on the ingress interface with an ACL
  3. explicitly allow the packet on the egress interface with an ACL
    (but I might be mistaken here. -> needs testing if it works without)



Despite the fact that we do use a Microsoft SCCM server, it's WOL function wouldn't work for us. We used a 3rd party WOL tool instead and schedule the wake-ups. Wolcmd could do that for you.

Friday 1 December 2017

Some fun with bad-usb devices (not rubber ducky)

Some fun with Leonardo-like usb devices

No, it is not rubber-ducky.

I was looking for a cheaper alternative to the rubber ducky devices to use for a user security awareness training at the media company I work for.

Comprehensive video instructions >>>HERE<<<

mmmmh... Payroll data. Who could resist?
I found those USB devices resembling an ordinary thumb drive here:
At a little under 10€, it is a somewhat overpriced Leonardo without any useable GPIOs. But it perfectly serves my purpose.

From what I could see with Wireshark's USB sniffer, my devices came without anything malicious preinstalled. As expected, the device identified as an Arduino Leonardo board.

Being what it is, it can easily be programmed in the Arduino IDE.
Simply use it as a Leonardo board


 /*  
 Some fun with Keyboard Emulation  
 Shuts down a windows machine after 20 seconds  
  */  
 // the following line may not be needed by current versions of the IDE  
 //#include "Keyboard.h"  
 //some definitions, I do not really use  
 char ctrlKey = KEY_LEFT_CTRL;  
 char winKey = KEY_LEFT_GUI;  
 char altKey = KEY_LEFT_ALT;  
 void setup() {  
  // we only need a keyboard for this prank...  
  Keyboard.begin();  
 }  
 void loop() {  
 // 20 seconds to load a new sketch  
  delay(20000);  
 //Now run the shutdown command  
  Keyboard.press(KEY_LEFT_GUI);  
  Keyboard.press('r');  
  delay(200);  
  Keyboard.releaseAll();  
  delay(200);  
  Keyboard.print("shutdown /t 1 /f /s");  
  delay(100);  
  Keyboard.press(KEY_RETURN);  
  Keyboard.releaseAll();  
  // wait forever...   
  while (true);  
 }  

This script works as expected and shuts down the PC. It could just as well start an Internet Explorer and visit a malicious web site.
Keep in mind that everything runs under the current user's privileges, so users without administrative privileges can only do limited damage.

It became very clear to everyone attending my training, that plugging in an USB device of unknows contents and origin is simply a bad idea.

Friday 9 June 2017

ESP8266 Sniffers, Deauthers and Scanners

Using the ESP8266 for (IoT) security research and testing

Why would I want to break stuff?

I have a background in education, but have worked as a network administrator with a strong security focus for the last 20+ years. So from time to time I do half-day user security awareness trainings in the company I work for.
To spice things up around the middle of the training, I have a collection of IT-security parlor tricks that don't require a lot of preparation, like manipulated DNS in a router and bit of fun with BeEF on Kali Linux.
I had used the ESP8266 in presentations a few times with some novelty projects like the Pong Clock. Never for nefarious purposes. Time to have a closer look.

What is it all about?

The ESP8266, like quite a few other WiFi chips (Atheros 9271 being one of the most notorious examples), has both the ability to send "manually" crafted packets, and to enter "monitor", or (not quite correctly in this context) "promiscuous"mode to receive data not specifically directed to the module.

Sounds pretty interesting, huh? - BUT:
  • The "wifi_send_pkt_freedom()" function was sadly removed from Espressif's SDK when upgrading from 1.3.0 to 1.4.0
  • The promiscuous mode only captures only 112 Bytes per packet. (128 Bytes, of which 16 are metainfo)
The good thing is that Kieran Simkin has put the original SDK 1.3.0 files here on Github, so not all of the freedom is lost.

(Note: The April 6th release notes for ESP-IDF 2.0 (ESP32 platform) mention "support for full packet-receive in sniffer mode" - Interestíng times ahead...)

What's out there? (In June 2017)

The IMHO most noteworthy examples:

Breadboarded deauther with OLED display

Why deauthenticate clients?

Being a royal pain in the ...uuh.. "behind" of other Wifi users, seems to be the main target of the majority of deauther-users. But the aforementioned monitor (or in this case: promiscuous) mode enables an attacker to capture the four-way handshake when the client re-connects to the access-point and get hold of the password hash.
If the password is short and/or weak enough to be brute forced or guessed from the hash, the attacker will get hold of the WPA preshared key (AKA Wifi password).
At the moment the limited promiscuous mode of the ESP8266 and/or it's SDK prevents this.
Not sure about the ESP32 yet, though.

Anything I can do about it?

Wifi equipment certified after July 2014 will support the 802.11w standard (defined some time around 2009) and will be immune to deauthentication attacks. A good reason to update your gear.

Sunday 14 May 2017

WhatsApp neue Farben (Betrug?)

Im Laufe des Abends sind über WhatsApp einige Meldungen mit dem Wortlaut
"Ich liebte whatsapp neue Farben" oder "ich liebte neue Farben für Whatsapp" eingegangen.
Dabei sieht die URL sehr verdächtig nach einem homographischen Angriff aus.

Verdächtig...


Tatsächlich ist die Zielseite erst seit dem 28.4. anonym über GoDaddy registriert und hat bei Talos einen schlechten "Ruf" (Web reputation: poor)

Tatsächlich ist der Name der Domain: XN--80AA2CAH8A7F73B.COM
Das soll den Anschein erwecken als sei whatsapp.com der Betreiber.
Schlechtes Deutsch und fragwürdige Bedingungen


also: Finger weg

Kennt jemand die Hintergründe? -> Bitte Kommentar hinterlassen.

Saturday 22 April 2017

Systemwiederherstellung nach Microsoft Tech Support Betrug

Computer nach Anruf von "Microsoft Tech Support" Betrügern befreien

Es gibt diesen Blogeintrag auch auf ENGLISCH.
This article is also available in ENGLISH.

Ein unerwarteter Anruf

Eine Freundin bekam kürzlich einen Anruf von einem freundlichen, englischsprachigen Microsoft Mitarbeiter, der ihr helfen wollte ein Virusproblem auf ihrem PC zu beheben. Das behauptete er jedenfalls.

Hinweis: Microsoft ruft niemals Endkunden an. Jeder Anrufer der das behauptet ist ein Betrüger

Hier ist eine grobe Rekonstruktion des Scripts dem der Angreifer folgte. Es ist aus ihrer Erinnerung und dem rekonstruiert was ich auf dem PC fand.

Ihr PC meldet Fehler an unsere Server

Der Betrüger zeigte eine bewundernswerte Geduld dabei mit meiner Freundin die Brisanz der Lage begreiflich zu machen und ihr Vertrauen zu gewinnen.

Schritt 1: Vertrauen herstellen

Er ließ sie die Windows-Taste und "r" drücken und mit "CMD" eine Shell aufmachen. Dann bat er sie "assoc" zu tippen und die Enter-Taste zu drücken. Wenn die weltweit einzigartige Client ID "888DCA60-FC0A-11CF-8F0F-00C04FD7D062" am Ende der Ausgabe angezeigt werde, dann sei das der PC, der das Problem verursache.


Oh nein!
Und wer hätte es gedacht: genau diese ID stand da. Hier musste sofort eingegriffen werden.

Fernsteuerung

Nach dem was wir rekonstruieren konnten, wurde sie dann auf eine Webseite gelotst, die aber wenig später schon nicht mehr existierte. Vermutlich um von dort TeamViewer herunter zu laden.
Jetzt gab ihr der Angreifer eine kleine Tour durch ihr System:

Eventvwr:
Oh, so viele Fehler! Da muss etwas faul sein.

Tree:
Der Trick ist nett und es hat eine Weile gedauert bis ich verstanden hatte was das soll.
Da: Es sagt, dass es gehackt ist!
Der Angreifer bat sie "tree c:\ /F" in das Kommandofenster einzugeben. Damit ist das System eine Weile beschäftigt. Dank Teamviewer tippt der Betrüger jetzt einen beängstigenden Satz ein und drückt dann STRG+C. Die Ausgabe bricht ab und die Meldung erscheint auf dem Bildschirm

Gib mir Dein Geld!

So ungefähr das muss der Moment gewesen sein in dem ihr das 300€ "full-service" angeboten wurde. Als sie zögerte das anzunehmen, bereitete der Betrüger drastischere Schritte vor.

Schilde runter!

Er rief jetzt "msconfig" auf. Vermutlich um dort die Systemwiederherstellung abzuschalten. Nicht ganz sicher, aber das war in der Befehlshistorie der vorletzte Befehl der gespeichert war und die Systemiederherstellung war abgestellt als ich später versuchte die Maschine wiederherzustellen.

So um diese Zeit herum muss er auch das "syskey" Kommando aufgerufen haben. Damit lässt sich die Datei der Registry verschlüsseln, die die Benutzerkennwörter speichert. Dabei ist egal ob die Benutzer der Maschine überhaupt Passwörter haben oder nicht.

Zu gruselig

Der Anrufer wollte, dass sie auch Ihre Banksoftware testen sollte, was sie aber so unter Beobachtung nicht tun wollte. Beim nächsten Schritt wuede es ihr zu bunt: Der Anrufer, offensichtlich durch die angenehme Damenstimme am anderen Ende etwas aus dem Konzept gebracht wollte mehr sehen. Vermutlich rief er dazu die "Kamera" App auf. Als die Freundin sich selbst auf dem Bildschirm sah, klappte sie das Gerät zu und legte auf.

In den folgenden Stunden bekam sie mehrere Anrufe von unbekannten Nummern aus dem Ausland, die sich nicht annahm. Vermutlich wollte ihr jemand das Passwort zu ihrem PC verkaufen.

AReResearch zu Hilfe!

Sie zeigte den Vorfall bei der Polizei an, die das Thema zwar kannten, aber nicht wirklich helfen konnten. Also rief sie bei mir an und kam am nächsten Tag vorbei.

Als ich das Laptop bekam, lief es noch einwandfrei. Nach einem kurzen Blick auf die zuletzt aufgerufenen Kommandos (Windows+r und dann den Dropdown-Pfeil drücken) habe ich den Rechner heruntergefahren. (Das war möglicherweise nicht die cleverste Entscheidung.)
Das Laptop war nicht gerade neu, hatte aber schon ein UEFI Bios mit aktiviertem Safeboot.
Um von einem anderen Medium booten zu können musste ich auf "LegacyBios" umstellen um von einem USB-Stick mit einem aktualisierten "Desinfec't" starten zu können.
Dabei hanelt es sich um eine auf Ubuntu basierende Linux Live DVD mit mehreren Virenscannern, die jährlich dem c't Magazin beiliegt. (Aber auch zu einem moderaten Preis gekauft werden kann.)
Die Scanner fanden keine Infektionen auf der Platte. Offenbar hatte der Angreifer keine Schadsoftware auf dem System hinterlassen.

Alles ok also?

Nachdem ich das Bios zurück in die Ausgangskonfiguration gefummelt hatte, wollte das Windows nicht mehr starten, sondern blieb an einer mir bislang unbekannten Passwortaufforderung hängen.
"Zum Starten des Computers ist ein Kennwort erforderlich. Geben Sie das Startkennwort ein."

Und jetzt???


Ich kam nicht weiter.Die üblichen, nicht-destruktiven Reparaturmechanismen beim Systemstart klappten alle nicht, weil (wie ich zu diesem Zeitpunkt noch nicht wusste) die Systemwiederherstellung deaktiviert worden war.
Ein bisschen Goooogeln brachte dann schnell Klarheit: Die Passwortabfrage bedeutete, dass die SAM-Datei verschlüsselt worden war.
Windows legt (unabhängig von der Systemwiederherstellung) zyklisch (ich konnte nicht herausfinden wann) eine Kopie der Registry an.
Mit etwas Glück sollten die noch da sein.

Und so wird's gemacht:

  • PC von einer Linxu Live-DVD/USB-Stick starten. Das muss nicht Desinfec't sein, da die Virenscanner hier nicht benötigt werden.
  • Das "C-Laufwerk" im Schreib/Lese Modus verbinden. Für Ungeübte könnte das knifflig sein. Am einfachsten ist die Windowspartition an ihrer Datenträgerbezeichnung zu erkennen.
  • Mit dem Dateimanager der live-DVD zum windows-Verzeichnis auf dem neu eingehängten Laufwerk wechseln. Dort dann nach "system32" und "config"
  • Dort die folgenden Dateien umbenennen (z.B. mit einer ".orig" Dateierweiterung)
  1. DEFAULT
  2. SAM
  3. SECURITY
  4. SOFTWARE
  5. SYSTEM
  • Dann eine Verzeichnisebene tiefer in den Ordner "RegBack" wechseln
  • Die 5 oben genannten Dateien vom Ordner "RegBack" eine Ebene höher in den "config" Ordner kopieren
  • PC neu starten (vorher evtl. BIOS Einstellungen zurück setzen)

Das war's. Sie konnte ihre Maschine wieder mitnehmen. Ich habe noch den nicht benötigten Teamviewer, der sich beim Systemstart gestartet hatte deinstalliert und nochmal mit Microsofts "Autoruns"-Tool über das System geschaut. Dabei aber keine Unregelmäßigkeiten festgestellt.


Recover from Microsoft Tech Support Scam

How to recover from the "Microsoft Tech Support Scam"

There is also a GERMAN VERSION of this in my blog.
Diesen Artikel gibt es in meinem Blog auch AUF DEUTSCH.

An unexpected call

A friend of mine got a call from a friendly Microsoft support technician to help her fix a virus on her PC. - That is what he claimed, anyway.
Note: Microsoft will never call you about problems with your computer. 100% of the callers claiming to do so are fraudsters.

Here is a rough idea of the scammer's script as we could reconstruct it from her PC and what she remembered.

Your PC reports problems to our servers

With my friend, being a native German speaker, the scammer showed amazing patience making her understand the seriousness of the problem.

Step one: establsh trust

He let her type "Windows+r", then cmd to run a command shell. There he asked her to type "assoc" and asked if a line near the bottom read "888DCA60-FC0A-11CF-8F0F-00C04FD7D062" which is a globally unique identifier for the machine that causes the problem.
Oh no!
Sure enough the IDs matched. This calls for immediate action!

RemoteControl

From what I could gather, she was then asked to go to a website, that had already been taken down when I went to investigate. Presumably she installed TeamViewer from there.
Now the attacker gave her a tour of her system:

Eventvwr:
Just look at all these errors. There must be something wrong!

Tree:
That is a neat one and I had to investigate a little how it works.
There: It says it's been hacked!
The attacker let her run "tree c:\ /F" in the cmd-window. That takes a loooong time to complete. While it is running, the attacker (thanks to teamviewer) types some scary text and hits CTRL-C.

Give me your money

This must have been the moment when she was offered the 300€ full service support package. As she was still hesitant to accept that, the attacker prepared the more drastic moves.

Shields down!

Now he called msconfig, presumably to disable system recovery. Not absolutely sure, though, but system recovery was off when I got the machine and there were no restore points to revert to.

Around that time, he also must have run the syskey command that encrypts the SAM hive of the registry. That is the part that stores the user's password hashes.

Too scary

When he asked her to check her banking software, she started to smell a rat.
But the point when my friend freaked out was this: The caller, obviously sidetracked by my friend's friendly female voice, Wanted to see who he was dealing with and presumably ran the "camera" utility. When my friend saw herself on the screen, she closed the laptop's lid and hung up.

In the following hours, she got a number of calls from several unknown, foreign numbers which she didn't take. Presumably to "sell" her the password to her system.

AReResearch to the rescue!

She reported the incident to the police, who are aware of the problem, but couldn't offer much help. So she called me and came over to my house the next day.

The laptop still ran but I shut it down. (In retrospect, possibly not the best idea.)
The laptop was not new, but new enough to have an UEFI bios with safeboot. I set it to legacy mode and started the system from a "Desinfec't 2017" USB thumbdrive.
That is essentially an Ubuntu live linux with a selection of virus scanners, published annually by the renowned German c't magazine.
The scanners came up empty. The attacker apparently hadn't left any malicious software on the system.
So I set the bios back to uefi, but windows wouldn't boot but came up with a password dialog I hadn't seen before:
"This computer is configured to require a password in order to start up. Please enter the Startup Password below."

Now what???


I was stuck. The usual repair mechanisms wouldn't work. (I was not aware of the disabled system recovery at this point)
A bit of googling helped me find a solution:
The password dialog meant, that the SAM file was encryptend.
Windows does save a copy of the registry files from time to time, regardless of the system recovery settings.With a little luck, those were still in place.

So here is what to do:
  • Boot the locked machine from a linux live DVD. It doesn't need to be Desinfec't, as we don't need the scanners.
  • Mount your "C-drive" in R/W mode. For beginners, is might be easiest to recognize the right partition from it's volume name.
  • Using the file manager of the live-DVD (or USB-drive for that matter), navigave to your windows directory. Go to "system32" and then "config"
  • Rename the following files (e.g. with a ".orig" extension)
  1. DEFAULT
  2. SAM
  3. SECURITY
  4. SOFTWARE
  5. SYSTEM
          • Then go one step deeper in the directory tree to the "RegBack" folder
          • Copy the 5 files with the names listed above from the "RegBack" folder up to the config folder
          • Reboot the machine from the windows drive (you might have to change back the bios settings)

          That was it. The machine was good to go. I just uninstalled the unwanted version of TeamViewer and checked for anomalies with autoruns. Nothing out of the ordinary.


          Sunday 2 April 2017

          Web-enable the Tivoli model One with style

          Turn your Tivoli Audio Model One into a web radio with Onion.io's Omega2


          EDIT: you can now have a look at the build here on youtube.

          Model One downsides

          My Model One suffers from a few shortcomings:
          • interference from the switching power supplies of the kitchen lights
          • FM reception limited to local stations
          • AM unuseable because of interference
          • no short- or longwave reception
          This particular Model One is the old version without the individual AUX setting. So with a plug in the AUX input, AM/FM reception is impossible.

          So what I need is an underpiece to match the style of the Model One that provides reception of all my favourite stations, both domestic and foreign.


          Underpiece design idea

          Onion.io Omega2

          When I was contacted by Randolf from Onion.IO, if I wanted to have a go at the Onion2, this looked like the ideal system to upgrade my Model One:

          • below 1 W power consumption (including USB audio dongle)
          • GPIOs easily accessible with the expansion dock (also has a serial-usb bridge and power regulator)
          • supported usb audio dongle available
          • all packages required for my project already available

          Easy as Pi

          I work with linux systems for a living and have quite a few RaspberryPis scattered around the house. I have also done projects with OpenWRT systems, so getting the Omega2 to work was an easy task. It is also extremely well documented.

          Test setup


          How it works

          I designed the underpiece to have six pushbuttons. Each one connects one of the GPIO pins to the 3V3 rail.

          The resistors are a bit of an afterthought. Still simple enough.



          The command:
          gpioctl dirin 1
          sets GPIO #1 as an input. It's state can be queried with:

          root@Omega-8D3B:/etc# gpioctl get 1
          Using gpio pin 1.
          Pin 1 is LOW
          root@Omega-8D3B:/etc#

          If scripted, this output needs a bit of tidying. I couldn't figure out where to get the value from the sysfs. If anyone knows, please let me know.

          The only additional piece of software needed is mpg123 simply installed by:

          opkg install mpg123

          (You might need to run opkg update first)

          On a microcontroller, reacting to the push of a button would normally be a job for an interrupt. The following script works without that. At the cost that the button has to be pressed for up to a second.

          So when I momentarily connect any of the GPIOs (with the exception of GPIO6) to 3.3V, the script starts mpg123 with the appropriate stream URL.

          The "radio.sh" script to be placed in /usr/bin

           #!/bin/ash
          
                  gpioctl dirin 0
                  gpioctl dirin 1
                  gpioctl dirin 2
                  gpioctl dirin 3
                  gpioctl dirin 6
                  gpioctl dirin 7
                  gpioctl dirin 8
                  gpioctl dirin 9
          
          
                   COUNTER=0
                   while [  $COUNTER -lt 100 ]; do
                  #     echo The counter is $COUNTER
                  #     let COUNTER=COUNTER+1
          
          
          BUTTON0=$(gpioctl get 0 | grep Pin | cut -b 10)
          BUTTON1=$(gpioctl get 1 | grep Pin | cut -b 10)
          BUTTON2=$(gpioctl get 2 | grep Pin | cut -b 10)
          BUTTON3=$(gpioctl get 3 | grep Pin | cut -b 10)
          #BUTTON6=$(gpioctl get 6 | grep Pin | cut -b 10)
          BUTTON7=$(gpioctl get 7 | grep Pin | cut -b 10)
          BUTTON8=$(gpioctl get 8 | grep Pin | cut -b 10)
          BUTTON9=$(gpioctl get 9 | grep Pin | cut -b 10)
          
          
          if [ $BUTTON0 = 'H' ]; then
          killall mpg123
                         echo starting radio mode
                          echo BBC 1
          mpg123 http://bbcmedia.ic.llnwd.net/stream/bbcmedia_radio1_mf_p &
                      fi
          
          
          if [ $BUTTON1 = 'H' ]; then
          killall mpg123
                         echo starting radio mode
                          echo BBC-World
          mpg123 http://bbcwssc.ic.llnwd.net/stream/bbcwssc_mp1_ws-einws &
                      fi
          
          
          
          if [ $BUTTON2 = 'H' ]; then
          killall mpg123
                         echo starting radio mode
                          echo France inter
          mpg123 http://direct.franceinter.fr/live/franceinter-midfi.mp3 &
                      fi
          
          #world: http://bbcwssc.ic.llnwd.net/stream/bbcwssc_mp1_ws-einws
          
          if [ $BUTTON3 = 'H' ]; then
          killall mpg123
                         echo starting radio mode
                          echo SWR3
          mpg123 http://swr-mp3-m-swr3.akacast.akamaistream.net/7/720/137136/v1/gnl.akacast.akamaistream.net/swr-mp3-m-swr3 &
                      fi
          
          
          #if [ $BUTTON6 = 'H' ]; then
          #killall mpg123
          #               echo starting radio mode
          #               echo D-Radio
          #mpg123 http://stream.dradio.de/7/249/142684/v1/gnl.akacast.akamaistream.net/dradio_mp3_dlf_m &
          #            fi
          
          
          if [ $BUTTON9 = 'H' ]; then
          killall mpg123
                         echo starting radio mode
                          echo D-Radio Kultur
          mpg123 http://stream.dradio.de/7/530/142684/v1/gnl.akacast.akamaistream.net/dradio_mp3_dkultur_m &
                      fi
          
          
          if [ $BUTTON8 = 'H' ]; then
          killall mpg123
                         echo starting radio mode
                          echo D-Radio Wissen
          mpg123 http://stream.dradio.de/7/698/142684/v1/gnl.akacast.akamaistream.net/dradio_mp3_dwissen_s &
                      fi
          
          
                  sleep 1
                   done
          
          

          The script is called from the file /etc/rc.local, so it starts when the Omega2 reboots:

           # Put your custom commands here that should be executed once  
           # the system init finished. By default this file does nothing.  
           /usr/bin/radio.sh & > /dev/null  
           exit 0  
          





          #arduinoD17 project: Arduino decodes the BSIDE ADM20 serial infrared protocol

          ##### THIS  POST  NEEDS  MORE WORK ####

          Due to the time constraints, my video on decoding the protocol is not quite as polished as usual, but possibly more "authentic".

          A look inside

          Although it did not make it into my review video, I one of the first things I did was taking the meter apart. Apart from making sure that the basic safety features were in place, the thing that caught my eye was the USB Interface.
          It is completely a self-contained module powered by the PC over the USB cable. The CH340 USB-UART bridge chip should be familiar to anyone using Arduino knockoffs.
          The module, of course is completly insulated against the meter, which sends a stream of serial data through a single infrared LED.


          Where to get the multimeter
          The meter is available under several names:

          Other materials

          ... and as I have been asked about the cute scope I used:
          It is around 20€ and easy to build. There is a firmware update available from JYE Tech. I'll do a video about the process.

          The protocol

          As mentioned previously, the meter sends a continuous stream of data at a rate of 2400 baud. This can be captured easily.
          The only part of the protocol I figured out so far are the actual digits. I still have too look into the units and the "minus". The protocol is not "human-friendly", but feels like it is derived from the meter's data stream to the LCD module.


          Code

          So here is the code for you to try:

           //Meater-Reater (Arduino version)  
           //Arduino infrared interface for BSIDE ADM20 Multimeter  
           //see www.AReResearch.net for details  
           //20170401 by Andy Reischle  
           #include <SoftwareSerial.h>  
           // Softserial only required during development to preserve  
           // serial debugging. When done, move to hardware UART  
           SoftwareSerial swSer(8,9);  
           uint8_t inByte = 0;  
           int initvalues[6] = {0xAA, 0x55, 0x52, 0x24, 0x01, 0x10};  
           int line[22];  
           int measures[4];  
           int counter = 0;  
           int dval;  
           String result = "";  
           bool initstart = false;  
           void setup() {  
            Serial.begin(9600);  
            swSer.begin(2400);  
            Serial.println("\nStart reading from Soft UART");  
                  }  
           void loop() {  
            // Serial.println("Doing my thing");  
            Serial.println(measure());  
            delay(5000);  
           }  
           String measure() {  
            initstart = true;  
            result="";  
            counter=0;  
            swSer.flush();  
            while (initstart) {  
             if (swSer.available() > 0)  
             {  
             inByte = swSer.read();  
           // Serial.print(inByte, HEX);  
           //  Serial.print(" ");  
             if (counter >5 )  
              {  
               measures[counter-6] = inByte;  
               //Serial.print("result: ");  
               //Serial.println(inByte, HEX);  
               if (counter == 9)  
                {  
                 if (measures[3] > 128) result = result + ".";  
                 result = result + displval(measures[3]);  
                 if (measures[2] > 128) result = result + ".";  
                 result = result + displval(measures[2]);  
                 if (measures[1] > 128) result = result + ".";  
                 result = result + displval(measures[1]);  
                 if (measures[0] > 128) result = result + ".";  
                 result = result + displval(measures[0]);  
                 // Serial.println (result);  
                 return result;  
                 initstart = false;  
                }  
               counter++;  
               if (counter > 9)  
                {  
                 counter = 0;  
                 result="";  
                 initstart = false;  
                }  
              }  
             else if (inByte == initvalues[counter])  
              {  
               counter ++;  
              }  
                           }  
                 }  
           }  
           //  
           // Convert display values  
           //  
           int displval(int dval)  
           {  
           if (dval > 128)  
            {  
             dval = dval -128;  
            }  
            if (dval == 95) return 0;  
            if (dval == 6) return 1;  
            if (dval == 107) return 2;  
            if (dval == 47) return 3;  
            if (dval == 54) return 4;  
            if (dval == 61) return 5;  
            if (dval == 125) return 6;  
            if (dval == 7) return 7;  
            if (dval == 127) return 8;  
            if (dval == 63) return 9;  
            if (dval == 0) return 0;  
           }  
          

          Friday 10 March 2017

          Detect CO with a MQ-7 sensor module

          How to detect carbon monoxide with a MQ-7 sensor module

          How gas sensors work

          I found an excellent thesis paper on how Tin Dioxide (SnO2) gas sensors work here. It also goes into the details of it's temperature dependency. (See details further down)

          Video

          Watch my video on the tests here.

          The module from ICStation

          You can get this module here. (Use code andyics for 15% off your order)
          The intended mode of operation is to apply 5V to the module and either read analog values from AOUT or set the threshold of the comparator to the desired value and read from the DOUT pin if it has tripped.


          The terminals

          Comparator and trimmer


          It seems to me that ICStation treats all MQ-series sensors the same way. But the MQ-7 is different from the rest. According to the data sheet, it gives the best results on the following cycle:

          • Pre-heat sensor for 48h 
          • Heat heater with 5V for 60 seconds
          • Heat at 1.4V for 90 seconds
          • Read the sensor near the end of the 90 seconds
          On 5V alone, the module does "sortof" work.

          You can see me breathing at the sensor

          I am quite sure there is no siginificant quantity of CO in my breath. And I not a smoker. The sensor reacts to a wide range of gases, as well as moisture and ambient temperature,

          Tricking the module into datasheet-like conditions

          To build this, you need the following components:



          The IRLZ34N is a very common N-Channel MosFET what already has a very low (0.046 Ohm) source-drain resistance with 5V at the gate. It can handle currents way beyond our reqirements for the flimsy heater on the module.
          The heater can run on DC or AC, so PWM should be ok. I can then set the duty cycle of the PWM so that it is the equivalent of 1.4V. (See code below.)


          The 10k resistor is optional

          The setup with the "switching" mosfet.
          Setup with Mosfet



          The Arduino code

          The code for the "proper" usage cycle:

           /*  
           MQ-7 cheater  
           Uses PWM and an N-Channel MosFET to trick an ICSTATION MQ-7 CO detector  
           into measuring CO according to the datasheet of the manufaturer.  
           */  
           int sensorPin = A0;  // select the input pin for the CO sensor  
           int sensorValue = 0; // variable to store the value coming from the sensor  
           // Initial setup  
           void setup() {  
            // initialize digital pin LED_BUILTIN as an output  
            pinMode(LED_BUILTIN, OUTPUT);  
            // initialize the serial port  
            Serial.begin(9600);  
           }  
           // the loop function runs over and over again forever  
           void loop() {  
            analogWrite(LED_BUILTIN, 255);  // turn the heater fully on  
            delay(60000);            // heat for 60 second  
           // now reduce the heating power  
            analogWrite(LED_BUILTIN, 72);  // turn the heater to approx 1,4V  
            delay(90000);            // wait for 90 seconds  
           // we need to read the sensor at 5V, but must not let it heat up. So hurry!  
            digitalWrite(LED_BUILTIN, HIGH);  
            delay (50); //don't know how long to wait without heating up too much. Getting an analog read apparently takes 100uSec  
             // read the value from the sensor:  
            sensorValue = analogRead(sensorPin);  
            Serial.println(sensorValue);  
           }  
          

          Increased sensitivity

          Under the same conditions (candle suffocated under jar), the FET-Pulsed version showed a significantly higher peak.
          FET-Pulsed heater

          Heater on 5v constantly
          While the pulsed version of the detector has a slower detection rate (once every 2.5 minutes), the signal's signal-to-noise ratio is signigicantly better (400:14 vs 220:28), resulting in better sensitivity.

          Other options:

          Cut the traces on the PCB and rewire, so the heater and the sensor don't run from the same power source. (I.e. run cycle the heating element at 5/1.4, while keeping constant 5V on the sensing element's voltage divider)

          Friday 24 February 2017

          Hacking the BSIDE ADM20 Multimeter - Software

          BSIDE ADM20 hack 1: Software

          How I got into this

          When I worked on a review of a battery charger, I came accross some potential issues that I had to investigate things more thoroughly. I needed a multimeter to record the charge curves.
          So my contact at Gearbest sent me this BSide ADM20 Multimeter. This has a built-in USB interface to display and record mesaurements on the PC.
          Values imported into LibreOffice Calc
          It turned out I quite like the meter. See my review video here. (Hardware-hack will follow) The software however was rather basic and wouldn't allow to set a sample rate or measurement duration.

          The meter is available under several names:

          I already had a look inside the meter and see pretty cool options to turn this into an IoT device. But let's not jump to conclusions. Some more work needs to go into that and I have only focussed on the software side here.

          Plug&Play

          Fortunately it is pretty obvious how the meter communicates with (or rather "to") the PC:
          A new COM port appears, presented through the well known CH340 USB-to-SERIAL bridge driver.
          And you thought COM-Ports were a thing of the past
          If you then fire up the software (DMM Data logger) that came with the meter, you're good to go.

          Original Software

          Nooo! Boooooooring!!!!

          A look at the protocol

          Pretty obvious that I should see something when I start a a terminal program like TeraTerm od Putty.
          In part 2 of this post, you'll see that this is strictly a one-way communication. So we can't talk back to the meter.

          • The port speed is 2400 baud.
          • There is no CR or LF at the end of each data set (see below)
          • The usual 8n1 seems to apply
          • Continuous stream of data: no xon/xoff
          • No return channel

          With the width set properly, TeraTerm's hex mode shows a pattern:
          The 5Fs are the Zeroes, the DF has the decimal point

          Whatever I do, the transmission always starts with a series of HEX values: AA5552240110
          followed by four bytes that change when stuff moves on the display. I could map the values to the following displayed digits: (excerpt from my visual basic prog)

                  If SerVal = 95 Then measured = 0
                  If SerVal = 6 Then measured = 1
                  If SerVal = 107 Then measured = 2
                  If SerVal = 47 Then measured = 3
                  If SerVal = 54 Then measured = 4
                  If SerVal = 61 Then measured = 5
                  If SerVal = 125 Then measured = 6
                  If SerVal = 7 Then measured = 7
                  If SerVal = 127 Then measured = 8
                  If SerVal = 63 Then measured = 9

          It turns out that the most significant bit is the decimal point, the other bits map to the seven segments. It also sends the measured unit and the polarity further back in the data stream. Up to now I choose to ignore all of that.

          The four bytes with the four digits are in reverse order, of course, for more programming fun.

          So my VisualBasic program listens for the "AA555224110" sequence and then decodes the four following bytes.

          I suspect that the data stream is derived from the communication with the display driver, as many bits in the data stream can directly be mapped to segments on the display.

          More on those details in the second part where I will look at the hardware of both the meter and it's communication.

          First try in VisualBasic

          No decimal point yet.
          That was once a 9v battery

          If you want to have a go at the experimental code, here is where I left off for the moment:

           Imports System.Threading.Tasks  
           Imports System.Timers  
           Imports System.IO  
           Imports System.IO.Ports  
           Imports System.Threading  
           Public Class Form1  
             Dim datensatz As String  
             Dim rohwert As Integer  
             Dim werte(22) As Integer  
             Dim decodewerte(4) As Integer  
             Dim recorddata As Boolean = False  
             Dim i As Integer = 0  
             Delegate Sub DataDelegate(ByVal sdata As Integer)  
             REM Define the method (Function) that will be called by the Invoke method   
             Private Sub PrintData(ByVal sdata As Integer)  
               Dim startsequence As String = "AA555224110"  
               Dim tmpchar As String  
               Dim str As Integer  
               Dim measured As Integer  
               Dim x As Integer  
               If recorddata Then  
                 werte(i) = sdata  
                 Console.Write("I= ")  
                 Console.WriteLine(i)  
                 If i = 4 Then  
                   recorddata = False  
                   i = 0  
                   tmpchar = Hex(werte(1))  
                   REM Console.WriteLine(werte(1))  
                   x = DecodeValue(werte(1))  
                   decodewerte(1) = x  
                   Console.WriteLine(x)  
                   Label2.Text = x  
                   tmpchar = Hex(werte(2))  
                   REM Console.WriteLine(werte(2))  
                   x = DecodeValue(werte(2))  
                   decodewerte(2) = x  
                   Console.WriteLine(x)  
                   Label3.Text = x  
                   tmpchar = Hex(werte(3))  
                   REM Console.WriteLine(werte(3))  
                   x = DecodeValue(werte(3))  
                   decodewerte(3) = x  
                   Console.WriteLine(x)  
                   Label4.Text = x  
                   tmpchar = Hex(werte(4))  
                   REM Console.WriteLine(werte(4))  
                   x = DecodeValue(werte(4))  
                   decodewerte(4) = x  
                   Console.WriteLine(x)  
                   Label5.Text = x  
                   TextBox1.Text = CStr(decodewerte(4)) & CStr(decodewerte(3)) & CStr(decodewerte(2)) & CStr(decodewerte(1))  
                   sp.DiscardInBuffer()  
                 End If  
                 i = i + 1  
               End If  
               tmpchar = Hex(sdata)  
               Label1.Text = tmpchar  
               datensatz = datensatz + tmpchar  
               Console.WriteLine(datensatz)  
               If (datensatz.Contains(startsequence)) Then  
                 REM Console.WriteLine("Got Header")  
                 datensatz = ""  
                 recorddata = True  
               End If  
             End Sub  
             Public Sub New()  
               ' This call is required by the designer.  
               InitializeComponent()  
               ' Add any initialization after the InitializeComponent() call.  
             End Sub  
             Dim WithEvents sp As New SerialPort  
             Private Sub GetSerialPortNames()  
               sp.BaudRate = 2400  
               sp.PortName = "COM3"  
               sp.Open()  
               sp.DataBits = 8  
               sp.Parity = Parity.None  
               sp.StopBits = StopBits.One  
               sp.Handshake = Handshake.None  
               REM sp.Encoding = System.Text.Encoding.Default  
               sp.Encoding = System.Text.Encoding.Default  
             End Sub  
             Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load  
               GetSerialPortNames()  
             End Sub  
             Private Sub SerialPort_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles sp.DataReceived  
               Dim str As Integer  
               REM Dim str2 As Char  
               str = sp.ReadChar()  
               REM Console.WriteLine(str)  
               REM str2 = Convert.ToChar(str)  
               Dim adre As New DataDelegate(AddressOf PrintData)  
               Me.Invoke(adre, str)  
             End Sub  
             Function DecodeValue(ByVal SerVal As Integer)  
               Dim decimalpoint As Boolean = 0  
               Dim measured As Integer  
               If SerVal > 128 Then  
                 SerVal = SerVal - 128  
                 decimalpoint = True  
               End If  
               measured = 99  
               If SerVal = 95 Then measured = 0  
               If SerVal = 6 Then measured = 1  
               If SerVal = 107 Then measured = 2  
               If SerVal = 47 Then measured = 3  
               If SerVal = 54 Then measured = 4  
               If SerVal = 61 Then measured = 5  
               If SerVal = 125 Then measured = 6  
               If SerVal = 7 Then measured = 7  
               If SerVal = 127 Then measured = 8  
               If SerVal = 63 Then measured = 9  
               If SerVal = 8097 Then measured = 7  
               If SerVal = 8096 Then measured = 1  
               If SerVal = 0 Then measured = 0  
               Console.Write("Decoder got a: ")  
               Console.Write(SerVal)  
               Console.Write(" decoded as: ")  
               Console.WriteLine(measured)  
               Return measured  
             End Function  
           End Class  
          

          If you have done work on hard- or software-hacking those meters please let me know.


          Saturday 18 February 2017

          Can't make voice call with Siri - Solution

          Since the upgrade to iOS 10, I could not get Siri to dial any numbers from my address book.
          I changed quite a few of Siri's settings back and forth, but was unable to fix the problem. Resets and restarts would not help either.

          What finally helped was a rather unexpected:


          • I switched off the "Dial Assist" function in the "Phone" settings and Siri was able to make calls again.
          • I then switched "Dial assist" back on and Siri could still dial without any issues.




          Problem solved.
          I can just assume, that some not otherwise accessible parmeter has been set to a valid value when switching Dial Assist off and on.

          Sprachwahl mit Siri funktioniert nicht: Lösung

          Siri hat ein Problem:

          Seit dem Update auf iOS 10 konnte ich per Siri - Sprachwahl nicht mehr wählen. Neustart oder die Änderung von Siri - Einstellungen blieben wirkungslos.

          Keine Sache der Einstellung

          Die Lösung für dieses Problem liegt nicht in den Siri-Einstellungen, sondern ist unter "Telefon" zu finden:

          • Nachdem ich die Funktion "Wählhilfe" abeschaltet hatte, ging die Sprachwahl.
          • Wählhilfe wie der aktiviert: Siri kann noch wählen.


          Ich kann nur spekulieren, daß ein nicht anderweitig zugänglicher Parameter durch das Aus- und einschalten der Wählhilfe korrekt gesetzt wurde.

          Friday 3 February 2017

          Using the Nitecore SC2 superb charger

          Superb charger

          on Nitecore's web pages for the "SC2 superb charger", there is no shortage of superlatives. Charging with "Infinite Intelligence" certainly is the boldest claim.



          See for yourself >>> HERE <<< in my review video on YouTube.

          Infinite intelligence

          So I tried to find out more about the limits of this "active charging with infinite intelligence" thing. Gearbest sent me a unit for review and I put it through a few tests to see how it performs.

          First impression

          The charger feels quite tough & beefy to the to touch. The kind of plastic that doesn't feel plasticy, but rather reminds of high quality power tools. A good start.

          Second impression

          But why-oh-why are the settings for the current and max. charge voltage printed on what looks like a sheet of protective film that easily comes off the display.
          I'm sure if I don't constantly use that charger, I'll have forgotten what which LED means what after a few days. Nitecore has to do something about that in the next iteration of the SC2.

          Automatic battery capacity detection

          Now this should be what is at the heart of this ominous infinite intelligence. The traditional way to determine the battery's capacity is to discharge them and measure the capacity that they charge to, possibly adding another discharge/charge cycle. Nitecore's web pages claim that it automatically detects the battery's capacity and sets the charge current accordingly.
          So come on SC2, impress me!

          Test setup

          First, I have to know about my cell's actual capacity. To find that out, I use an improved version of my previously published Arduino battery tester.

          Makeshift battery tester


          I use four cells for testing:
          1. AWT 18650 35A 3000 mAh IMR cell 
          2. Ultrafire 18650 3000mAh (Really is only 300mAh)
          3. KeepPower 14500 800mAh 
          4. Ultrafire 14500 1200mAh (Really a little over 200 mAh)
          With automatic battery capacity detection, The good quality cells AWT and KeepPower cells should charge at a higher rate than the Ultrafires (who in all tests had only a fraction of their nominal capacity, regardless of the charger.)

          Size matters

          As cells with the same size charge at the same current, I wondered what happened if I make the 14500 appear bigger. So I inserted a spacer with the 14500 cell.
          14500 to 18650 converter :-)


          Nut&bolt spacer inserted
          It charged at 2A. Way above the recommended 0,4-0,8A (Unconfirmed, from reseller pages)

          The assumption that bigger cells hold more capacity might on the whole be correct. But we all know that there are good and bad cells and that makes way more of a difference than the size.

          The limits of infinite intelligence

          There is more that will confuse the charger:
          1. LiFePO4 cells: The charger can't distinguish LiFePO4 cells from Li-Ion cells and would overcharge them. So the maximum charge voltage has to be set manually
          2. 3,8V Li-Ion cells. I've never had or seen any of these, But as they are indistinguishable from a 3.7V cell, The charge voltage needs to be set manually.

          Example Charge

          While I had initially observed some brief overvoltage conditions, All the voltage (and charge curves I took) did not exhibit that phenomenon.
          0,5A charge curve
          I did many of the long-term measurements with PC on the USB-Port of the bside ADM20 Multimeter that I quite like. I also got from Gearbest to get a better grip on some problems I suspected with the SC2 charger.
          bside ADM20 at work with a current shunt resistor
          The multimeter turned out to be quite hackable. But that will be a whole new blog entry & video.

          Final word

          Pros:
          • Great charger if you're in a hurry. Very fast and reasonably safe.
          • Supports all currently available battery chemistry types.
          Cons:
          • Sometimes has trouble disabling the protection circuit in KeepPower batteries.
          • Needs help choosing the right battery chemistry.



          Thursday 26 January 2017

          High CPU usage on Surface Pro3 running Windows 10

          System interrupt uses one CPU core

          Windows 8.1

          I already had this issue running Windows 8.1 and could work around it, simply disabling the realtek high definition audio driver, that seems to be the docking station's audio system.

          Windows 10

          The problem came back with Windows 10. But this time disabling drivers did not help.
          That should be an "idle" system

          What brought the fan to a standstill, however was:
          Restarting the Surface Pro 3 while in the docking station.
          I don't mean powering it down and switch it back on again. That doesn't do any good. It is the restart that does the trick for me.
          A very relaxed CPU
          This, of course, is only a very temporary solution. So whenever the fan (which rarely ever stops completely) gets on my nerves, I reboot and things are better for the rest of the day.

          Docking station drivers?

          I suppose that a driver for the docking station's peripherals causes the problems. But disabling any of them did not cure the problem, so I might be wrong. Can anyone shed more light on that issue?

          --

          Edit 2017-03-08: The current driver package SurfacePro3_Win10_1700802_1.msi did not help either.

          Monday 23 January 2017

          More work on the TOP-308 IP Camera

          Great news on the TOP-308 IP camera

          Root access to the camera

          Last year I got this Top-308 IP camera and got a little stuck as I couldn't get full access.
          Now user Choziro over on the IPCamTalk-Forum has found a great way to get full root access to the Linux OS of the camera.

          This is how it is done:

          • Telnet to port 9527 of your camera. (Most likely 192.168.1.10 9527)
          • log on as "admin" with an empty password
          • type "shell"
          • type "telnetd -f"

          The session is more or less stuck at that point, but that does not matter.


          • Now telnet to your camera (192.168.1.10) at the default telnet port 23
          • User name is "root"
          • Password is "xmhdipc"
          • You now have a nice busybox shell that behaves much better than on port 9527
          Rootshell !

          No still images from the camera

          Nosing around in the file system showed that there was no obvious way to get a single image from the camera. But that is what I need. So I resorted to letting my Raspberry Pi do that job:

          This works both with avidemux and ffmpeg:

          avconv -i "rtsp://192.168.1.10/user=admin_password=_channel=1_stream=0.sdp" -vframes 1 "image.png"

          That will capture a single frame from the camera and write it to a file "image.png".
          Putting that into the RasPi's crontab could copy an image to a web site.