Thursday, 1 August 2019

Cloning on BMW X6 M50d (2016)

Key Cloning and coding on a BMW X6 (F16) 2016

Background

So a bit of background here, I ordered a BMW X6 M50d in June 2016, and it arrived end of October 2016. Two months later I have a dodgy guy sitting outside of my house at 8pm at night, smoking a cigarette, waiting for *something* The moment I used my car key fob to open the the boot, he dumps his cigarette and drives off.

This lead me to believe he had cloned my car key.

A quick trip to BMW the next day and the service agent there assures me, it shouldn't be possible unless they had access to the ECU/OBD2 port, but my car had the latest updates. But if they are determined, they will steal the car anyway. Great!

Key Cloning

Key types

So there are different types or keys. Passive Keyless Entry (think comfort access and not pressing a button to unlock the car doors), and your standard radio key door which opens when you press a button.
There are several attack vectors to each type of key. 
PKE - Radio amplification attack.
Radio - Replay attack.

Most keys either work on the 868Mhz , 433MHz and 315Mhz and blanks can be bought off the internet from chinese websites or even Ebay.

OBD

Cloning can be done via the OBD port, and there can be a max of 10 keys programmed into the ECU. After that a new ECU is needed. This is one of the easiest attacks. Smash a window, plug a laptop into the OBD port, and clone the key onto a blank.

Coding

ESys

This is the software that enables you to do coding that, for example modifies the car software so that, it recognises you've installed a non-factory fit item like bluetooth or something.

FDL Coding

This enables to personalise the car for you. I will be disabling the start/stop feature, or at least telling it to remember the setting before the car was turned off.

There are many tutorials for hacking BMW and plenty of ways to obtain it.

Building a new VMware server

So buying HP etc is expensive.... time to build your own sourced from general parts!

I bought this:https://www.jetwaycomputer.com/NF795.html and coupled it with a crucial 32GB memory kit here https://uk.crucial.com/gbr/en/bls2k16g4s240fsd

Lots of issues - from booting taking too long to other issues where restarting took way too long...


So long story short - TURN OFF UEFI IN THE BIOS - it majorly fucks things up.


Monday, 24 July 2017

Controlling mains AC or DC via raspberry Pi and Alexa

Controlling mains AC or DC via Raspberry Pi via Alexa

Background

I have LED strip lights, lighting the floating wall, and want to control them via Alexa. The raspberry pi will be doing the actual switching.

There is a decent library which emulates a belkin wemo switch called fauxmo and Alexa can control Belkin's Wemo switches.

Requirements:

  • Raspberry Pi (I will be using a 3 model b)
  • Opto relays (I Bought mine from Amazon UK https://www.amazon.co.uk/gp/product/B06XK6HCQC/ref=oh_aui_search_detailpage?ie=UTF8&psc=1 )
  • Amazon echo or echo dot 
  • Wires and a breadboard

Wiring

  •  Install N00bs, following the raspberry pi guide here: https://www.raspberrypi.org/documentation/installation/noobs.md
  • Attach everything (I am using a breadboard), according to this pinout (raspberry pi 2/3 specific)  

So:
GND on the relay -> GND on the raspberry Pi
IN1,2,3,4 -> GPIO 2,3,4,17
VCC -> 5v power.

As of writing this, n00bs, has all the pre-reqs pretty much installed already, but you will need to double check, using this excellent guide from adafruit ( https://learn.adafruit.com/adafruits-raspberry-pi-lesson-4-gpio-setup/configuring-gpio )

Testing

Write some test code to check it all works (this will need to be run as root)
Change the GPIO numbers according to your setup.

#!/usr/bin/python
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)

# init list with pin numbers
pinList = [2, 3, 4, 20, 21]

# loop through pins and set mode and state to 'high'

for i in pinList:
    GPIO.setup(i, GPIO.OUT)
    GPIO.output(i, GPIO.LOW)
    print i

print "ALL SET LOW"
# time to sleep between operations in the main loop

SleepTimeL =3
time.sleep(SleepTimeL);

# main loop

try:
  time.sleep(SleepTimeL);
  GPIO.output(2, GPIO.HIGH)
  print "TWO"
  time.sleep(SleepTimeL);
  GPIO.output(3, GPIO.HIGH)
  print "THREE"
  time.sleep(SleepTimeL);
  GPIO.output(4, GPIO.HIGH)
  print "FOUR"
  time.sleep(SleepTimeL);
  GPIO.output(20, GPIO.HIGH)
  print "20"
  time.sleep(SleepTimeL);
  GPIO.output(21, GPIO.HIGH)
  print "21"
  time.sleep(SleepTimeL);
  print "Good bye!"
  for i in pinList:
    GPIO.output(i, GPIO.LOW)
  #  GPIO.cleanup()

# End program cleanly with keyboard
except KeyboardInterrupt:
  print "  Quit"

  # Reset GPIO settings
  GPIO.cleanup()

Alexa integration

pip install fauxmo

Check the code out in my repo: https://bitbucket.org/c240amg/raspberry-pi-alexa/src/



Sunday, 4 September 2016

Multi master write/write MySQL cluster troubleshooting

Multi-master write/write MySQL Cluster

Background

So I have 4 payments servers located around the world:
London, Paris, Netherlands and Frankfurt. My customers are based around Europe, so these locations are best suited for us.

I operate a auto failover via Amazon DNS and using its health checks is very cost effective. If a server is non-responsive, AWS takes it out and routes traffic to another payments server.

Due to the fact that communication between servers has to be encrypted, and I will want to, eventually, pass more traffic between them (i.e. mysql + wddx, api calls etc etc), I decided to skip the SSL connection between MySQL processes.

Instead I decided to establish, effectively a site-to-site VPN connection using OpenVPN.
Due to the fact that this relies on a 'central' node, like a star topology, having that central node go down would be an issue. So I decided to make at least 2 central nodes, that would act as 'servers' to the client VPNs to connect to.

With this method, I'd only have to maintain 2 sets of VPN connections, rather than the 4 (one for each payment server), that would make it truly resilient. It would also need 50% of payment servers to go down before a split-brain situation would occur.

For MySQL, I decided to use Galera cluster for master/master (active/active) replication. This has been working very well, and ~600mb of state data (on initial node setup) takes very little time. If you find that initial startup takes longer than 30 minutes, then I would suspect a networking issue (rate limiting etc). This had occurred to myself in with the Paris payments server, and sadly it took around 6 hrs to sync the node, before it could take on incrementals.

Configuration

They are all connected via VPN tunnels to each other in a mesh network, to allow secure communications (it was easier than messing around with SSL certs), and are running Galera.
This works very well, as any changes to a server are instantly replicated out within a couple of seconds.

Troubleshooting

Node re-syncing

If a node in the cluster drops off, you can tell with the query:
SHOW STATUS LIKE 'wsrep_cluster_size';
which in my case, shows 4.

If for any reason something does drop off, this will show less than 4.

To resync the node that's disconnected, you can simply restart mysql, or if the donor is too slow, you can select another donor by using the command:
/etc/init.d/mysql restart --wsrep_sst_donor=payments3

Identifying the most advanced node

 This is done by checking the Global Transaction ID, in the grastate.dat file (usually in /var/lib/mysql/)
Check the latest sequence number

Tuesday, 31 May 2016

OpenVPN clients, allowing access between clients

See I need access between clients and also to set them on a static IP address.


This is achieved by setting up a client configuration directory on your server.
First get the CN from the certificate you created for each client.

 ./build-key client1
Country Name (2 letter code) [UK]:
State or Province Name (full name) [LDN]:
Locality Name (eg, city) [London]:
Organization Name (eg, company) [CNetwork]:
Organizational Unit Name (eg, section) [IT]:
Common Name (eg, your name or your server's hostname) [p1]:
Name [EasyRSA]:pclient1



So the name of your client is pclient1

Create a directory for client configuration e.g.

mkdir /etc/openvpn/ccd

Then set your server config

openvpn.cnf
client-to-client
client-config-dir ccd
push "route 1.2.3.4 255.255.255.0"
route 1.2.3.4 255.255.255.0
 

Then create a file in /etc/openvpn/ccd called pclient1
The contents should be as follows:
iroute 1.2.3.4 255.255.255.0
ifconfig-push 10.30.30.30 255.255.255.0


The above pushes the route for pclient1 (1.2.3.4) into the route table of the kernel and opevpn, and the pclient1 file allocates 10.30.30.30 as the static ip address.

Sunday, 10 April 2016

Hacking the Amazon Dash for the UK

 Intro

So you want to use the Amazon Dash button but live in the UK?First issue, is actually getting them. They are only available in the US and you require a US address. Once you've actually obtained one of them, the next bit is pretty easy...

Configuration- android

Well you have to setup the dash button through the amazon.com app....

The easiest thing to do is to press and hold the dash until it flashes blue. Once it is in this mode, it creates a access point called 'Amazon ConfigureMe'. I used the excellent tool iStumbler to find this:


Once connected to it (192.168.0.2), I used firefox to http://192.168.0.1

There I entered the SSID and password of my local wireless LAN network and bam. It gave me the success sceen.


This, unfortunately, did not work, because the amazon app has a cert which automagically activates the dash, and in part of that process requires you to have a US IP address. So I fired up openvpn and connected to an endpoint in the US then did the setup via the amazon app.

Each time the dash connects to my wireless LAN, it sends a gratuitous arp and then shuts down. Note that the configuration mac address ( 6c:0b:84:34:ce:ed )is different to the actual mac address it uses once setup.

Programming

I am using my current favourite language python, and we're going to use the scapy library.
Firstly, we need to install the library:
sudo pip install scapy
Then run this script to find out what the mac address is:
from scapy.all import *


def arp_display(pkt):
  if pkt[ARP].op == 1: #who-has (request)
    if pkt[ARP].psrc == '0.0.0.0': # ARP Probe
      print "ARP Probe from: " + pkt[ARP].hwsrc

print sniff(prn=arp_display, filter="arp", store=0, count=10)
 
So now that I know this I can plug this into a proper python program, which sends me an email when my 9month old baby poos.
from scapy.all import *
import smtplib
server = smtplib.SMTP('192.168.2.254', 25)


def arp_display(pkt):
  if pkt[ARP].op == 1: #who-has (request)
    if pkt[ARP].psrc == '0.0.0.0': # ARP Probe
      if pkt[ARP].hwsrc == 'a0:02:dc:88:94:ea': # digestive disadvantage
        print "Pushed Poo"
    msg = "Scarlett pooed" # The /n separates the message from the headers
    server.sendmail("dash@amz.org", "phil.spencer@gmail.com", msg)   
  
      elif pkt[ARP].hwsrc == '10:ae:60:b1:97:73': # Depends
        print "Pushed Depends button"
      else:
        print "ARP Probe from unknown device: " + pkt[ARP].hwsrc

while True:
  print sniff(prn=arp_display, filter="arp", store=0, count=10)
 
Next part I will show how to log this data into an Excel sheet for later analysis.


Sunday, 20 March 2016

Dual internet connections at home (primary/backup) with martians pt1

So I work a lot from home, approx 99% of the time, and soon my wife will be joining me in working from home, one day a week.

Preamble

One line is fibre from Virgin Media (150mb+), the other is an ADSL BOnline (7mb+), which uses the Tiscali network (AS9105).

I kept them separate, as the missus isn't technical so auto route failing issues, might not be diagnoseable for her, and it's easy for her to swap between primary and backup lines by just changing wifi SSIDs.

So one of the things that was provided by BOnline was a Technicolor TG582n router (not the best, but it'll do) - it is afterall a backup line to get internet access.
Current setup. The switches are HP Procurve managed switches with 4gb trunked, portchanneled connections between them both.

Internet1 ---> [eth2] Firewall1 (vlan1) +----- wifi1 (vlan1)
                                        |
                                        +----- switch1 (vlan 1,2)
                                               | | | |
Internet2 ---> Technicolor (vlan2)  ----+----- switch2 (vlan 1,2)
                                        |
                                        +----- wifi2 (vlan2)

Requirements

For traffic on the backup line to be able to access the internal LAN (192.168.2.0/24)
For traffic on the internal LAN, to be access anything on the backup line LAN (192.168.1.0/24)
For both lines, to be able to access the internet independently of each other.
To be able to VPN/SSH into to the firewall from either the primary line or backup line.

Steps

So one of the first things to do is get it connected to my main LAN.
Steps needed

* Add VLAN for backup line
* ensure DHCP scopes do not conflict
* Add static routing to the Technicolour.
* Add routing to the firewall

Setup

So I added a VLAN to the HP procurve switch (conneted to eth1), and untagged it to force all traffic to be backup VLAN, and excluded all others to eth1


Internet ---> [eth2] Firewall +----- [eth0] LAN 192.168.2.254/24
                              |
                              +----- [eth1] Backup 192.168.1.200/24
                              |
                              +----- [eth3] DMZ 10.40.0.0/24
                              |
                              |
    


I allocated eth1 to the new LAN, and assigned 192.168.1.200 to it (set it in /etc/network/interfaces). I needed to add a static route on the Technicolour so that everything on the backup line knew how to access everything on the main LAN (192.168.2.0/24). You can't do this via the web i/f as it doesn't have anything that advanced listed there.
The Technicolour has telnet access, so after seting myself and account and telnetting in I issued:

ip rtadd dst=192.168.2.0/25 gateway=192.168.1.200
ip saveall

Don't forget to saveall, otherwise it'll be running under the running-config, and next boot, it will not be applied.

Then I portforwarded a port from the Technicolour WAN for SSH access to my firewall [eth1/192.168.1.200].
Testing SSH access I tried sshing to my backup line and got this in the firewall logs (if you've enabled martian logging, your syslog will have entries similar to this):

Mar 18 15:56:31 aibo2 kernel: [586653.881530] IPv4: martian source 192.168.1.200 from 77.96.x.x, on dev eth1

This looked funny to me, as 77.96.x.x is my primary line (virgin media). My backup line was 79.78.x.x W00t was going on?

This is due to the fact that linux is not expecting a packet with that source address from that destination. i.e It's not expecting an internal address with that subnet to come from an external IP address. The external IP address is actually the interface belonging to Virgin Media, as that is my default route.

So we need to change the routing, so that all packets from the backup line are associated with the backup interface, and not get routed through my default route)

Routing 

Pre-req: iproute2 (this should be installed by default)

So we need linux to understand that packets from eth1, stay with eth1, and are not routed via the default eth2.
So edit /etc/iproute2/rt_tables
I added a table for beonline
#
# reserved values
#
255     local
254     main
253     default
0       unspec
#
# local
#
#1      inr.ruhep
1 beonline

Then added routing to tell that anything from 192.168.1.0/24 and eth1, store it in table beonline
Then that a default route for traffic destined for table beonline is the default gateway of beonline
Then add anything from table beonline has a src of 192.168.1.200

ip route add 192.168.1.0/24 dev eth1 192.168.1.200 table beonline
ip route add default via 192.168.1.254 table beonline
ip rule add from 192.168.1.200 table beonline


This works for me, with my routing table looking like so:
root@aibo2:/etc# ip route
default via 77.96.x.x dev eth2  metric 100
77.96.x.0/22 dev eth2  proto kernel  scope link  src 77.96.x.x
192.168.1.0/24 dev eth1  proto kernel  scope link  src 192.168.1.200
192.168.2.0/24 dev eth0  proto kernel  scope link  src 192.168.2.254

NAT/Masquerade

As an extra step, I added an iptables rule to masquerade all traffic from eth1 to the Technicolour router. I wasn't sure if this was necessary, but added it anyway (thinking about it, probably not since I added a static route on the technicolour)

To test this is all working, you can use ping or better, traceroute from your firewall:

via virgin media
root@aibo2:/etc# traceroute 8.8.8.8
traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets
 1  10.89.x.x (10.89.x.x)  6.719 ms  6.675 ms  6.640 ms
 2  croy-core-2a-ae6-648.network.virginmedia.net (81.96.228.201)  9.544 ms  9.576 ms  9.528 ms
 3  * * *
 4  * * *
 5  * * *
 6  72.14.198.97 (72.14.198.97)  18.411 ms  18.529 ms  18.611 ms
 7  72.14.233.247 (72.14.233.247)  23.630 ms 209.85.253.95 (209.85.253.95)  27.590 ms  27.279 ms
 8  209.85.245.187 (209.85.245.187)  32.126 ms 209.85.242.123 (209.85.242.123)  32.164 ms 209.85.142.177 (209.85.142.177)  32.024 ms
 9  google-public-dns-a.google.com (8.8.8.8)  31.025 ms  21.973 ms  11.934 ms


via beonline
root@aibo2:/etc# traceroute -s 192.168.1.200 8.8.8.8
traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets
 1  192.168.1.254 (192.168.1.254)  0.729 ms  0.946 ms  1.408 ms
 2  host-62-24-254-203.as13285.net (62.24.254.203)  27.596 ms  29.215 ms  28.727 ms
 3  host-78-151-228-57.as13285.net (78.151.228.57)  29.979 ms  31.896 ms  31.348 ms
 4  host-78-151-228-78.as13285.net (78.151.228.78)  33.601 ms host-78-151-228-72.as13285.net (78.151.228.72)  34.557 ms host-78-151-228-70.as13285.net (78.151.228.70)  34.967 ms
 5  host-78-144-11-223.as13285.net (78.144.11.223)  36.972 ms host-78-144-11-117.as13285.net (78.144.11.117)  37.424 ms host-78-144-9-81.as13285.net (78.144.9.81)  38.420 ms
 6  72.14.214.222 (72.14.214.222)  39.440 ms  25.707 ms  27.260 ms
 7  216.239.56.67 (216.239.56.67)  27.685 ms 216.239.56.203 (216.239.56.203)  26.193 ms 216.239.56.67 (216.239.56.67)  26.010 ms
 8  216.239.57.131 (216.239.57.131)  31.134 ms 216.239.57.153 (216.239.57.153)  29.699 ms 216.239.57.131 (216.239.57.131)  32.021 ms
 9  google-public-dns-a.google.com (8.8.8.8)  34.251 ms  32.332 ms  34.870 ms


Note that the traffic by default routes over my primary line (virgin media), so no source address needed. With beoline, I have to specify the source address, so that it knows to push the traffic via eth1 (backup line)

In part 2, I will be discussing how to route specific traffic over one connection or another.
e.g. You want FTP traffic going over your primary line, by skype traffic going over your backup line.