Aug 10, 2019 Tags: reverse-engineering, security
This will be a stream of consciousness as I take a look at Square’s S6 reader. I’m not a hardware person whatsoever, so it’ll be a pretty superficial exploration.
The S6 is pretty inconspicuous looking:
The FCC ID (2AF3K-1SQHW) is the only identifier on it, apart from a (presumably) unique serial number.
I tried plugging it in, with some initial results in lsusb
and dmesg
:
Based on the hiddev
/hidraw
registration, I figured that I might get lucky
and get some output during a card read by directly pulling from /dev/hidraw0
:
1
sudo dd if=/dev/hidraw0 of=/tmp/foo
But no luck: it’s probably waiting for something from the host first.
A quick search for “Square reader linux” yielded some initially promising results: a blog post by Andy Bromberg and a paper presented at Black Hat 2015 (?).
Unfortunately, both are about the “original”1 3.5mm jack-type reader, which is magstripe only and a lot simpler internally (see Bromberg’s photos). Bromberg’s post also contains this concerning phrase:
Unfortunately, Square moved from a very simple circuit design to a larger, encrypted version before I got mine.
So there might be some device signing going on. Sigh.
Square’s Secure Data Encryption page isn’t very helpful — it’s mostly PCI-DSS filler.
A 2012 Verge article says that Square’s readers include “hardware encryption”, but that doesn’t mean that the device itself requires signing with a known client.
This spammy-looking site says that Square accounts are linked to their POS2 application, not to a particular reader. That’s good, at least.
Permutations on {"Square reader", "encryption", "s6", "signing", "driver", "linux"}
don’t turn
up anything new.
Looking up the FCC ID yielded some helpful component images, and im_eningeer pointed out some test points to yours truly.
The images aren’t high-res enough to see the numbers on the Square-branded chip, but the other one says:
1
2
3
4
MK21
FX512V12
1N41K
CTAQ?1531J
Which appears to be a Kinetis K21 with 512KB of flash.
New idea: download Square’s Android POS app and see if it contains anything helpful. I wasn’t hopeful since Square hints that their Android app only supports BLE3, but who knows.
I downloaded v5.17 from
this sketchy site
and used apktool
to unpack it:
1
2
apktool d 'Square Point of Sale POS_v5.17_apkpure.com.apk'
cd 'Square Point of Sale POS_v5.17_apkpure.com'
The manifest offers a hint:
1
2
3
4
5
6
7
8
9
10
11
12
<activity android:name="com.squareup.hardware.UsbAttachedActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar">
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/>
</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/usb_device_filter"/>
</activity>
<receiver android:name="com.squareup.hardware.UsbDetachedReceiver">
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED"/>
</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" android:resource="@xml/usb_device_filter"/>
</receiver>
And grep
ing for android.hardware.usb.action.USB_DEVICE_ATTACHED
in the
smali yielded some interesting calls and
namespaces:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
.method private a(Lcom/starmicronics/starioextension/u;)V
.locals 3
iget-boolean v0, p0, Lcom/starmicronics/starioextension/StarIoExtManager;->o:Z
if-eqz v0, :cond_0
new-instance v0, Lcom/starmicronics/starioextension/t;
sget-object v1, Lcom/starmicronics/starioextension/t$a;->c:Lcom/starmicronics/starioextension/t$a;
invoke-direct {v0, v1, p1}, Lcom/starmicronics/starioextension/t;-><init>(Lcom/starmicronics/starioextension/t$a;Lcom/starmicronics/starioextension/u;)V
iget-object p1, p0, Lcom/starmicronics/starioextension/StarIoExtManager;->u:Landroid/os/Handler;
invoke-virtual {p1, v0}, Landroid/os/Handler;->post(Ljava/lang/Runnable;)Z
return-void
:cond_0
new-instance v0, Landroid/content/IntentFilter;
invoke-direct {v0}, Landroid/content/IntentFilter;-><init>()V
const-string v1, "android.hardware.usb.action.USB_DEVICE_ATTACHED"
invoke-virtual {v0, v1}, Landroid/content/IntentFilter;->addAction(Ljava/lang/String;)V
const-string v1, "android.hardware.usb.action.USB_DEVICE_DETACHED"
invoke-virtual {v0, v1}, Landroid/content/IntentFilter;->addAction(Ljava/lang/String;)V
iget-object v1, p0, Lcom/starmicronics/starioextension/StarIoExtManager;->n:Landroid/content/Context;
iget-object v2, p0, Lcom/starmicronics/starioextension/StarIoExtManager;->A:Landroid/content/BroadcastReceiver;
invoke-virtual {v1, v2, v0}, Landroid/content/Context;->registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;
const/4 v0, 0x1
iput-boolean v0, p0, Lcom/starmicronics/starioextension/StarIoExtManager;->o:Z
new-instance v0, Lcom/starmicronics/starioextension/StarIoExtManager$1;
invoke-direct {v0, p0, p1}, Lcom/starmicronics/starioextension/StarIoExtManager$1;-><init>(Lcom/starmicronics/starioextension/StarIoExtManager;Lcom/starmicronics/starioextension/u;)V
invoke-virtual {v0}, Ljava/lang/Thread;->start()V
return-void
.end method
It looks like Star Micronics is a POS company, which was initially
promising. However, searching for more strings suggests that starioextension
et al. are part of
a (receipt) printing SDK, not card reading. So probably a dead end.
I’ve run out of time. Maybe I’ll pick this up again. If I do, these are probably the next steps:
/dev/hidrawN
to see if it’ll respond to somethingapktool
’s output