<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title>VSzA techblog</title>
	<link rel="alternate" type="text/html" href="http://techblog.vsza.hu/"/>
	<link rel="self" type="application/atom+xml" href="http://techblog.vsza.hu/atom.xml"/>
	<updated>2013-05-15T16:50:01+02:00</updated>
   <generator uri="http://github.com/stef/utterson">utterson v0.4</generator>
   <id>http://techblog.vsza.hu/</id>
	<entry>
		<title>Bootstrapping the CDC version of Proxmark3</title>
		<link rel="alternate" type="text/html" href="http://techblog.vsza.hu/posts/Bootstrapping_the_CDC_version_of_Proxmark3.html"/>
		<updated>2013-05-15T16:50:01+02:00</updated>
      <id>http://techblog.vsza.hu/posts/Bootstrapping_the_CDC_version_of_Proxmark3.html</id>
      <author><name>dnet</name></author>
		<category term="POSTCATEGORY" scheme="http://www.sixapart.com/ns/types#category"/>
		<content type="html" xml:lang="en" xml:base="http://techblog.vsza.hu"><![CDATA[
      <p>A few weeks ago I updated my working directory of <a href="https://code.google.com/p/proxmark3/">Proxmark3</a> and found
that <a href="http://www.cs.ru.nl/~rverdult/">Roel Verdult</a> finally improved the USB stack by ditching the old
HID-based one and using <a href="https://en.wikipedia.org/wiki/USB_communications_device_class">USB CDC</a>. My only problem was that having a device
running the HID bootloader and a compiled version of the CDC flasher caused a
chicken-egg problem. I only realized it when running <code>make flash-all</code> resulted
in the following error message.</p>

<pre><code class="no-highlight">client/flasher -b bootrom/obj/bootrom.elf armsrc/obj/osimage.elf armsrc/obj/fpgaimage.elf
Loading ELF file 'bootrom/obj/bootrom.elf'...
Loading usable ELF segments:
0: V 0x00100000 P 0x00100000 (0x00000200-&gt;0x00000200) [R X] @0x94
1: V 0x00200000 P 0x00100200 (0x00000e1c-&gt;0x00000e1c) [RWX] @0x298
Attempted to write bootloader but bootloader writes are not enabled
Error while loading bootrom/obj/bootrom.elf
</code></pre>

<p>I checked the <code>flasher</code> and found that it didn't recognize the <code>-b</code> command
line switch because it expected a port name (like <code>/dev/ttyACM0</code>) as the first
argument. So I needed an old <code>flasher</code>, but first, I checked if the <code>flasher</code>
binary depended on any Proxmark3 shared object libraries.</p>

<pre><code class="no-highlight">&#x24; ldd client/flasher
    linux-vdso.so.1 =&gt;  (0x00007fff6a5df000)
    libreadline.so.6 =&gt; /lib/x86_64-linux-gnu/libreadline.so.6 (0x00007fb1476d9000)
    libpthread.so.0 =&gt; /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fb1474bd000)
    libstdc++.so.6 =&gt; /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fb1471b5000)
    libm.so.6 =&gt; /lib/x86_64-linux-gnu/libm.so.6 (0x00007fb146f33000)
    libgcc_s.so.1 =&gt; /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fb146d1d000)
    libc.so.6 =&gt; /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb146992000)
    libtinfo.so.5 =&gt; /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007fb146769000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fb147947000)
</code></pre>

<p>Since the above were all system libraries, I used an old <code>flasher</code> left behind
from the ages before I had commit access to the Proxmark3 SVN repository.</p>

<pre><code class="no-highlight">&#x24; /path/to/old/flasher -b bootrom/obj/bootrom.elf \
    armsrc/obj/osimage.elf armsrc/obj/fpgaimage.elf
Loading ELF file 'bootrom/obj/bootrom.elf'...
Loading usable ELF segments:
0: V 0x00100000 P 0x00100000 (0x00000200-&gt;0x00000200) [R X] @0x94
1: V 0x00200000 P 0x00100200 (0x00000e1c-&gt;0x00000e1c) [RWX] @0x298

Loading ELF file 'armsrc/obj/osimage.elf'...
Loading usable ELF segments:
1: V 0x00110000 P 0x00110000 (0x00013637-&gt;0x00013637) [R X] @0xb8
2: V 0x00200000 P 0x00123637 (0x00002c74-&gt;0x00002c74) [RWX] @0x136f0
Note: Extending previous segment from 0x13637 to 0x162ab bytes

Loading ELF file 'armsrc/obj/fpgaimage.elf'...
Loading usable ELF segments:
0: V 0x00102000 P 0x00102000 (0x0000a4bc-&gt;0x0000a4bc) [R  ] @0xb4

Waiting for Proxmark to appear on USB...
Connected units:
        1. SN: ChangeMe [002/007]
 Found.
Entering bootloader...
(Press and release the button only to abort)
Waiting for Proxmark to reappear on USB....
Connected units:
        1. SN: ChangeMe [002/008]
 Found.

Flashing...
Writing segments for file: bootrom/obj/bootrom.elf
 0x00100000..0x001001ff [0x200 / 2 blocks].. OK
 0x00100200..0x0010101b [0xe1c / 15 blocks]............... OK

Writing segments for file: armsrc/obj/osimage.elf
 0x00110000..0x001262aa [0x162ab / 355 blocks]................................................................................................................................................................................................................................................................................................................................................................... OK

Writing segments for file: armsrc/obj/fpgaimage.elf
 0x00102000..0x0010c4bb [0xa4bc / 165 blocks]..................................................................................................................................................................... OK

Resetting hardware...
All done.

Have a nice day!
</code></pre>

<p>After resetting the Proxmark3, it finally got recognized by the system as a CDC
device, as it can be seen below on a <code>dmesg</code> snippet.</p>

<pre><code class="no-highlight">[10416.461687] usb 2-1.2: new full-speed USB device number 12 using ehci_hcd
[10416.555093] usb 2-1.2: New USB device found, idVendor=2d2d, idProduct=504d
[10416.555105] usb 2-1.2: New USB device strings: Mfr=1, Product=0, SerialNumber=0
[10416.555111] usb 2-1.2: Manufacturer: proxmark.org
[10416.555814] cdc_acm 2-1.2:1.0: This device cannot do calls on its own. It is not a modem.
[10416.555871] cdc_acm 2-1.2:1.0: ttyACM0: USB ACM device
</code></pre>

<p>The only change I saw at first was that the client became more responsive and
it required the port name as a command line argument.</p>

<pre><code class="no-highlight">&#x24; ./proxmark3 /dev/ttyACM0
proxmark3&gt; hw version
#db# Prox/RFID mark3 RFID instrument                 
#db# bootrom: svn 699 2013-04-24 11:00:32                 
#db# os: svn 702 2013-04-24 11:02:43                 
#db# FPGA image built on 2012/ 1/ 6 at 15:27:56
</code></pre>

<p>Being happy as I was after having a working new CDC-based version, I started
using it for the task I had in mind, but unfortunately, I managed to find a bug
just by reading a block from a Mifare Classic card. It returned all zeros for
all blocks, even though I knew they had non-zero bytes. I found the bug that
was introduced by porting the code from HID to CDC and <a href="https://code.google.com/p/proxmark3/source/detail?r=702">committed my fix</a>,
but I recommend everyone to test your favorite functionality thoroughly to
ensure that changing the USB stack doesn't affect functionality in a negative
way. If you don't have commit access, drop me an e-mail with a patch or open
an issue on the <a href="https://code.google.com/p/proxmark3/issues/list">tracker of the project</a>.</p>

<p>Happy RFID hacking!</p>
]]></content>
	</entry>
	<entry>
		<title>Bootstrapping MySQL for testing</title>
		<link rel="alternate" type="text/html" href="http://techblog.vsza.hu/posts/Bootstrapping_MySQL_for_testing.html"/>
		<updated>2013-05-06T19:42:24+02:00</updated>
      <id>http://techblog.vsza.hu/posts/Bootstrapping_MySQL_for_testing.html</id>
      <author><name>dnet</name></author>
		<category term="POSTCATEGORY" scheme="http://www.sixapart.com/ns/types#category"/>
		<content type="html" xml:lang="en" xml:base="http://techblog.vsza.hu"><![CDATA[
      <p>When I created <a href="https://github.com/dnet/registr">registr</a>, I wanted a way to test it on the same RDBMS as the
one I use for <a href="http://www.redmine.org/">Redmine</a>, MySQL. For the purposes of testing, I wanted to
start a fresh instance of <code>mysqld</code> that could be ran without superuser
privileges, without affecting other running MySQL instances, and with
minimal resource consumtion.</p>

<p>Although the test suite was developed in Python, the idea can be used with any
language that makes it possible to create temporary directories in a manner
that avoids race conditions and spawn processes. The code can be found in the
<a href="https://github.com/dnet/registr/blob/mysql/test_redmine.py">TestRedmineMySQL class</a>, and it follows the steps described below.</p>

<ul>
<li>Create a temporary directory (<code>path</code>)</li>
<li>Create a directory inside <code>path</code> (<code>datadir</code>)</li>
<li>Generate two fil&#x65;names inside <code>path</code> (<code>socket</code> and <code>pidfile</code>)</li>
<li>Spawn the <code>mysqld_safe</code> binary with the following parameters.
<ul>
<li><code>--socket=</code> and the value of <code>socket</code> makes MySQL accept connections throught that file</li>
<li><code>--datadir=</code> and the value of <code>datadir</code> makes MySQL store all databases in that directory</li>
<li><code>--skip-networking</code> disables the TCP listener, thus minimizes interference with other instances</li>
<li><code>--skip_grant_tables</code> disables access control, since we don't need that for testing</li>
<li><code>--pid-file=</code> and the value of <code>pidfile</code> makes MySQL store the process ID in that file</li>
</ul></li>
<li>Do what you want with the database</li>
<li>Open the file named <code>pidfile</code> and read an integer from the only row</li>
<li>Send a <code>SIGTERM</code> to the PID</li>
<li>Wait for the process to finish.</li>
</ul>

<p>The above way worked fine for me, didn't leave any garbage on the system, and
ran as fast as an Oracle product could do. :)</p>
]]></content>
	</entry>
	<entry>
		<title>Using Android emulator with Burp Suite</title>
		<link rel="alternate" type="text/html" href="http://techblog.vsza.hu/posts/Using_Android_emulator_with_Burp_Suite.html"/>
		<updated>2013-05-02T17:34:15+02:00</updated>
      <id>http://techblog.vsza.hu/posts/Using_Android_emulator_with_Burp_Suite.html</id>
      <author><name>dnet</name></author>
		<category term="POSTCATEGORY" scheme="http://www.sixapart.com/ns/types#category"/>
		<content type="html" xml:lang="en" xml:base="http://techblog.vsza.hu"><![CDATA[
      <p>I still find <a href="http://portswigger.net/burp/">Burp Suite</a> the best tool for web-related penetration testing,
and assessing Android applications are no exception. In the past, I used my
phone with iptables, but lately – especially since the emulator <a href="http://developer.android.com/tools/devices/emulator.html#accel-graphics">supports
using the host OpenGL for graphics</a> – I started to prefer the emulator.</p>

<p>First of all, setting an emulator-wide proxy is really easy, as <a href="http://fas.mide.dk/2011/11/make-android-emulator-ready-for-ssl.html">Fas wrote</a>,
all I needed was the <code>-http-proxy</code> command line argument. Because of this, I
had to start the emulator from command line – I've only used the GUI provided
by <code>android</code> before. I looked at the output of <code>ps w</code> for hints, and at first,
I used a command line like the following.</p>

<pre><code class="no-highlight">&#x24; tools/emulator64-arm -avd Android17 -http-proxy http://127.0.0.1:8081
emulator: ERROR: Could not load OpenGLES emulation library: lib64OpenglRender.so: cannot open shared object file: No such file or directory
emulator: WARNING: Could not initialize OpenglES emulation, using software renderer.
</code></pre>

<p>Since using the Android emulator without hardware rendering would've been like
using Subversion after Git, I looked into the matter and found that I just had
to set the <code>LD_LIBRARY_PATH</code> path to the <code>tools/lib</code> subdirectory of the SDK.
Now I could intercept various TCP connections using Burp, but in case of SSL
connections, certificate mismatch caused the usual problem.</p>

<p>Luckily, Burp provides really easy ways of exporting the its root CA
certificate in the last few releases, I chose to export it into a DER file by
clicking on the <code>Certificate</code> button on the <code>Options</code> subtab of the <code>Proxy</code>
tab, and selecting the appropriate radio button as seen below.</p>

<p><img src="http://techblog.vsza.hu/images/burp-root-ca-cert-export.png" alt="Exporting root CA certificate from Burp Proxy" title="" /></p>

<p>Android 4.x stores root CA certificates in <code>system/etc/security/cacerts/</code> in
PEM format, so running the following command gives a chance to review the
certificate before adding and the output can be used directly by Android.</p>

<pre><code class="no-highlight">&#x24; openssl x509 -in burp.cer -inform DER -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1296145266 (0x4d419b72)
    Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=PortSwigger, ST=PortSwigger, L=PortSwigger, O=PortSwigger, OU=PortSwigger CA, CN=PortSwigger CA
        Validity
            Not Before: Jan 27 16:21:06 2011 GMT
            Not After : Jan 22 16:21:06 2031 GMT
        Subject: C=PortSwigger, ST=PortSwigger, L=PortSwigger, O=PortSwigger, OU=PortSwigger CA, CN=PortSwigger CA
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (1024 bit)
                Modulus:
                    00:a0:c2:98:2b:18:cf:06:42:4a:7b:a8:c9:ce:ab:
                    1d:ec:af:95:14:2a:dd:58:53:35:9d:68:18:86:a5:
                    3a:84:6e:6c:32:58:11:f3:d7:bf:b4:9e:29:d2:dc:
                    22:d2:7f:23:36:16:9d:10:c4:e5:4c:69:55:4d:95:
                    05:9f:9b:f8:33:37:8d:9f:d0:23:0f:61:d4:53:d7:
                    40:fd:da:6d:f0:04:75:2c:ef:75:77:0a:4a:8c:34:
                    f7:06:6b:4e:ea:58:af:a7:89:51:6b:33:a2:89:5c:
                    6b:64:cb:e6:31:a7:7f:cf:0a:04:59:5b:a4:9e:e3:
                    96:53:6a:01:83:81:2b:0b:11
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                FE:2F:6C:CD:EB:72:53:1E:24:33:48:35:A9:1C:DC:C7:D6:42:6F:35
            X509v3 Basic Constraints: critical
                CA:TRUE, pathl&#x65;n:0
    Signature Algorithm: sha1WithRSAEncryption
         1e:f0:92:13:bd:05:e8:03:33:27:72:3d:03:93:1e:d9:d6:cc:
         f0:bd:ae:e2:a3:8f:83:e0:65:5e:c7:03:9d:25:d4:d2:8f:6e:
         bc:3e:7d:5c:28:2d:b3:dd:c0:8b:8e:60:c5:a8:8c:26:dc:19:
         50:db:da:03:fb:39:e0:72:01:26:47:a7:ea:c4:58:f5:c9:71:
         bf:03:cd:af:16:07:6d:a5:36:72:4c:b5:8d:4f:86:4a:bc:60:
         1c:01:62:eb:e5:48:a0:83:c6:1c:ea:b9:36:d6:b1:f1:de:e6:
         19:4a:2a:76:7e:d3:d2:39:70:64:a3:63:ce:89:da:2e:7d:17:
         ff:52
-----BEGIN CERTIFICATE-----
MIICxDCCAi2gAwIBAgIETUGbcjANBgkqhkiG9w0BAQUFADCBijEUMBIGA1UEBhML
UG9ydFN3aWdnZXIxFDASBgNVBAgTC1BvcnRTd2lnZ2VyMRQwEgYDVQQHEwtQb3J0
U3dpZ2dlcjEUMBIGA1UEChMLUG9ydFN3aWdnZXIxFzAVBgNVBAsTDlBvcnRTd2ln
Z2VyIENBMRcwFQYDVQQDEw5Qb3J0U3dpZ2dlciBDQTAeFw0xMTAxMjcxNjIxMDZa
Fw0zMTAxMjIxNjIxMDZaMIGKMRQwEgYDVQQGEwtQb3J0U3dpZ2dlcjEUMBIGA1UE
CBMLUG9ydFN3aWdnZXIxFDASBgNVBAcTC1BvcnRTd2lnZ2VyMRQwEgYDVQQKEwtQ
b3J0U3dpZ2dlcjEXMBUGA1UECxMOUG9ydFN3aWdnZXIgQ0ExFzAVBgNVBAMTDlBv
cnRTd2lnZ2VyIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCgwpgrGM8G
Qkp7qMnOqx3sr5UUKt1YUzWdaBiGpTqEbmwyWBHz17+0ninS3CLSfyM2Fp0QxOVM
aVVNlQWfm/gzN42f0CMPYdRT10D92m3wBHUs73V3CkqMNPcGa07qWK+niVFrM6KJ
XGtky+Yxp3/PCgRZW6Se45ZTagGDgSsLEQIDAQABozUwMzAdBgNVHQ4EFgQU/i9s
zetyUx4kM0g1qRzcx9ZCbzUwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkqhkiG9w0B
AQUFAAOBgQAe8JITvQXoAzMncj0Dkx7Z1szwva7io4+D4GVexwOdJdTSj268Pn1c
KC2z3cCLjmDFqIwm3BlQ29oD+zngcgEmR6fqxFj1yXG/A82vFgdtpTZyTLWNT4ZK
vGAcAWLr5Uigg8Yc6rk21rHx3uYZSip2ftPSOXBko2POidoufRf/Ug==
-----END CERTIFICATE-----
</code></pre>

<p>As <a href="http://stackoverflow.com/a/12134348">rustix wrote</a>, the file name needs to be the the hash of the subject of
the certificate, in case of the above certificate, it can be calculated as the
following.</p>

<pre><code class="no-highlight">&#x24; openssl x509 -noout -subject_hash_old -inform DER -in burp.cer
9a5ba575
</code></pre>

<p>Now all we need is to upload the file using <a href="http://developer.android.com/tools/help/adb.html">adb</a>.</p>

<pre><code class="no-highlight">&#x24; adb push burp.cer /system/etc/security/cacerts/9a5ba575.0
failed to copy 'burp.cer' to '/system/etc/security/cacerts/9a5ba575.0':
    Read-only file system
</code></pre>

<p>The error message was fairly straightforward, <code>/system</code> is mounted read-only,
all we need to do is remounting it in read-write (rw) mode.</p>

<pre><code class="no-highlight">&#x24; adb shell
root@android:/ # mount -o rw,remount /system
root@android:/ # ^D
&#x24; adb push burp.cer /system/etc/security/cacerts/9a5ba575.0
failed to copy 'burp.cer' to '/system/etc/security/cacerts/9a5ba575.0':
    Out of memory
</code></pre>

<p>That's a tougher one, but easily solveable by resizing the system partition
using the emulator command line argument <code>-partition-size</code>. With this change as
well as the library path for OpenGL, the full command line looks like the
following (of course, <code>64</code> should be removed if you're using a 32-bit OS).</p>

<pre><code class="no-highlight">&#x24; LD_LIBRARY_PATH=tools/lib/ tools/emulator64-arm -avd Android17 \
    -http-proxy http://127.0.0.1:8081 -partition-size 512
</code></pre>

<p>Since restarting the emulator wiped my changes from <code>/system</code>, I had to upload
the certificate again, and finally, it appeared in the list of system
certificates.</p>

<p><img src="http://techblog.vsza.hu/images/burp-android-sys-ca.png" alt="Burp Proxy root CA in Android System CA store" title="" /></p>

<p>This being done, all applications using SSL/TLS connections (except for those
that do <a href="https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning">certificate pinning</a>) will accept the MITM of Burp, as it can
be seen below with Google as an example. The top half is the certificate
viewer of the Android web browser, stating that Portswigger issuing a
certificate for <code>www.google.com</code> is perfectly valid, while the bottom half
is the Burp Proxy window, showing the contents of the HTTPS request.</p>

<p><img src="http://techblog.vsza.hu/images/android-browser-burp-ca.png" alt="Android web browser using the Burp CA" title="" /></p>
]]></content>
	</entry>
	<entry>
		<title>MWR BSides Challenge 2013 writeup</title>
		<link rel="alternate" type="text/html" href="http://techblog.vsza.hu/posts/MWR_BSides_Challenge_2013_writeup.html"/>
		<updated>2013-04-27T12:32:48+02:00</updated>
      <id>http://techblog.vsza.hu/posts/MWR_BSides_Challenge_2013_writeup.html</id>
      <author><name>dnet</name></author>
		<category term="POSTCATEGORY" scheme="http://www.sixapart.com/ns/types#category"/>
		<content type="html" xml:lang="en" xml:base="http://techblog.vsza.hu"><![CDATA[
      <p>On 11<sup>th</sup> March 2013, MWR Labs <a href="http://labs.mwrinfosecurity.com/blog/2013/03/11/bsides-chall&#x65;nge/">announced a chall&#x65;nge</a> that involved
an Android application called Evil Planner. I got the news on 12<sup>th</sup>
March around 17:00 and by 20:30 I found two vulnerabilities in the application
and had a working malware that could extract the data protected by the app.
The app I created as a proof-of-concept is available in its
<a href="https://github.com/dnet/evil-planner-solution">GitHub repository</a>, and below are the steps I've taken to assess the
security of the application.</p>

<p>The application itself was quite simple, and seemed secure at first sight. It
required the user to use a PIN code to protect information entered. Unlike
many application it even used this PIN code to encrypt the database, so even
if the device was stol&#x65;n, the user shouldn't have worried about it.</p>

<p>After downloading the APK, I unzipped it and converted the <code>classes.dex</code> file
containing the Dalvik bytecode to a JAR file using <a href="http://code.google.com/p/dex2jar/">dex2jar</a>. I opened the
resulting JAR with <a href="http://java.decompiler.free.fr/?q=jdgui">JD-GUI</a> and saw that no obfuscation took place, so all
class, method and member names were available. For example, the <code>Login</code> class
contained the following line, revealing where the PIN code was stored:</p>

<pre><code>private final String PIN_FILE = "/creds.txt";
</code></pre>

<p>Further static code analysis revealed that the PIN code was stored in the file
using a simple method of encoding (I wouldn't dare calling it encryption).</p>

<pre><code class="java">public static String encryptPIN(String paramString,
    TelephonyManager paramTelephonyManager)
{
    String str1 = paramTelephonyManager.getDeviceId();
    String str2 = paramString.substring(0, 4);
    byte[] arrayOfByte1 = str1.getBytes();
    byte[] arrayOfByte2 = str2.getBytes();
    return Base64.encodeToString(xor(arrayOfByte1, arrayOfByte2), 2);
}
</code></pre>

<p>Although variable names are not available to JD-GUI, it's still easy to see
what happens: the <code>getDeviceId</code> method <a href="http://developer.android.com/reference/android/telephony/TelephonyManager.html#getDeviceId()">returns the IMEI of the device</a>,
and this gets XOR'd with the PIN string. The result can have weird characters,
so it's Base64 encoded before being written to <code>creds.txt</code>.</p>

<p>As you can see, this method of encoding is easily reversible, but I wouldn't
even need to go that far, since there's a <code>decryptPIN</code> method as well that
performs the reverse of the code above. Thus acquiring the PIN code protecting
the application is only a matter of accessing the <code>creds.txt</code>, which has its
permissions set correctly, so it's only accessible to the Evil Planner.</p>

<p>However, using <a href="http://code.google.com/p/android-apktool/">apktool</a> to get readable XMLs from the binary ones used in
APK files revealed that the application exposes two <a href="http://developer.android.com/guide/topics/providers/content-providers.html">content providers</a>
whose security implications <a href="http://techblog.vsza.hu/posts/Seesmic_Android_information_leak.html">I already mentioned with regard to Seesmic</a>.</p>

<pre><code>&lt;provider android:name=".content.LogFileContentProvider" 
    android:authorities="com.mwri.fileEncryptor.localfile" /&gt;
&lt;provider android:name="com.example.bsidechall&#x65;nge.content.DBContentProvider"
    android:authorities="com.example.bsideschall&#x65;nge.evilPlannerdb" /&gt;
</code></pre>

<p>Latter is more like the one used by Seesmic and would've provided some limited
access to the database, so I turned my attention to the other. Former is more
interesting since it implements the <code>openFile</code> method in a way that it just
opens a file received in a parameter without any checks, as it can be seen in
the decompiled fragment below. (I removed some unrelated lines regarding
logging to make it easier to read, but didn't change it in any other way.)</p>

<pre><code>public ParcelFileDescriptor openFile(Uri paramUri, String paramString)
    throws FileNotFoundException
{
    // removed logging from here
    String str5 = paramUri.getPath();
    return ParcelFileDescriptor.open(new File(str5), 268435456);
}
</code></pre>

<p>Since the content provider is not protected in any way, this makes it possible
to access any file with the privileges of the Evil Planner. In the
proof-of-concept code, I used the following function to wrap its functionality
into a simple method that gets a path as a parameter, and returns an
<code>InputStream</code> that can be used to access the contents of that file.</p>

<pre><code>protected InputStream openFile(String path) throws Exception {
    return getContentResolver().openInputStream(Uri.parse(
                "content://com.mwri.fileEncryptor.localfile" + path));
}
</code></pre>

<p>Having this, reading the contents of <code>creds.txt</code> only took a few lines (and
even most of those just had to do with the crappy IO handling of Java).</p>

<pre><code class="java">InputStream istr = openFile(
            "/data/data/com.example.bsidechall&#x65;nge/files/creds.txt");
InputStreamReader isr = new InputStreamReader(istr);
BufferedReader br = new BufferedReader(isr);
String creds = br.readLine();
</code></pre>

<p>Since I had access to every file that Evil Planner had, the rest was just
copy-pasting code from JD-GUI to decrypt the PIN, get the database file in
the same way, decrypt that using the PIN, and dump it on the screen. All of
the logic can be found in <a href="https://github.com/dnet/evil-planner-solution/blob/master/src/hu/vsza/bsides/malware/Main.java">Main.java</a>, and the result looks like the
following screenshot.</p>

<p><img src="http://vsza.hu/mwr-chall&#x65;nge-pin-db.png" alt="Working proof-of-concept displaying sensitive information" title="" /></p>

<p>I'd like to thank the guys at MWR for creating this chall&#x65;nge, I don't
remember any smartphone app security competitions before. Although I felt
that the communication was far from being perfect (it's not a great feeling
having the solution ready, but having no address to send it to), it was fun,
and they even told me they'll send a T-shirt for taking part in the game.
Congratulation to the winners, and let's hope this wasn't the last
chall&#x65;nge of its kind!</p>
]]></content>
	</entry>
	<entry>
		<title>Single mbox outbox vs. multiple IMAP accounts</title>
		<link rel="alternate" type="text/html" href="http://techblog.vsza.hu/posts/Single_mbox_outbox_vs._multiple_IMAP_accounts.html"/>
		<updated>2013-04-01T14:15:50+02:00</updated>
      <id>http://techblog.vsza.hu/posts/Single_mbox_outbox_vs._multiple_IMAP_accounts.html</id>
      <author><name>dnet</name></author>
		<category term="POSTCATEGORY" scheme="http://www.sixapart.com/ns/types#category"/>
		<content type="html" xml:lang="en" xml:base="http://techblog.vsza.hu"><![CDATA[
      <p>As <a href="http://techblog.vsza.hu/posts/Four_free_software_I_started_using_in_2012.html">I've mentioned in February 2013</a>, I started using mutt in December 2012
and as a transitional state, I've been using my three IMAP accounts in on-line
mode, like I did with KMail. All outgoing mail got recorded in an <a href="https://en.wikipedia.org/wiki/Mbox">mbox</a>
file called <code>~/Mail/Sent</code> for all three accounts, which was not intentional,
but a configuration glitch at first. But now I realized that it has two
positive side effects when I'm using cellular Internet connection. Since this
way, the MUA doesn't upload the message using IMAP to the <code>Sent</code> folder,
resulting in 50% less data sent, which makes sending mail faster and saves
precious megabytes in my mobile data plan.</p>

<p>However, I still prefer having my sent mail present in the <code>Sent</code> folder of my
IMAP accounts, so I needed a solution to transfer the contents of an mbox file
to IMAP folders based on the <code>From</code> field. I preferred Python for the task as
the standard library had support for both <a href="http://docs.python.org/library/imaplib.html">IMAP</a> and <a href="http://docs.python.org/library/mailbox.html">mbox</a> out of the
box, and I've already had <a href="https://github.com/dnet/dashboard/blob/master/imapflag.py">good experience with the former</a>. Many solutions
I found used Python as well, but none of them had support for multiple IMAP
accounts and many used deprecated classes, or treated the process as a one-shot
operation, while I planned to use this to upload my mbox regularly to IMAP.</p>

<p>So I decided to write a simple script, which I completed in about an hour or
two that did exactly what I need, and still had no dependencies to anything
that's not part of the standard library. The script has support for invocation
from other modules and the command line as well, core functionality was
implemented in the <code>process_mbox</code> method of the <code>OutboxSyncer</code> class.
The method gets the <code>Mailbox</code> object and a reference for a database as
parameters, latter is used to ensure that all messages are uploaded exactly
once, even in case of exceptions or parallel invocations.</p>

<pre><code class="python">for key, msg in mbox.iteritems():
    account, date_time = msg.get_from().split(' ', 1)
    contents = mbox.get_string(key)
    msg_hash = HASH_ALGO(contents).hexdigest()
    params = (msg_hash, account)
</code></pre>

<p>The built-in iterator of the mailbox is used to iterate through messages in a
memory-efficient way. Both <code>key</code> and <code>msg</code> are needed as former is needed to
obtain the raw message as a byte string (<code>contents</code>), while latter makes
parsed data, such as the sender (<code>account</code>) and the timestamp (<code>date_time</code>)
accessible. The contents of the message is hashed (currently using SHA-256)
to get a unique identifier for database storage. In the last line, params is
instantiated for later usage in parameterized database queries.</p>

<pre><code class="python">with db:
    cur.execute(
        'SELECT COUNT(*) FROM messages WHERE hash = ? AND account = ?',
        params)
    ((count,),) = cur.fetchall()
    if count == 0:
        cur.execute('INSERT INTO messages (hash, account) VALUES (?, ?)',
            params)
    else:
        continue
</code></pre>

<p>By using the context manager of the database object, checking whether the
message free for processing and locking it is done in a single transaction,
resulting in a <code>ROLLBACK</code> in case an exception gets thrown and in a <code>COMMIT</code>
otherwise. Assigning the variable <code>count</code> was done this way to assert that
the result has a single row with a single column. If the message is locked
or has already been uploaded, the mailbox iterator is advanced without
further processing using <code>continue</code>.</p>

<pre><code>try:
    acc_cfg = accounts[account]
    imap = self.get_imap_connection(account, acc_cfg)
    response, _ = imap.append(acc_cfg['folder'], r'\Seen',
            parsedate(date_time), contents)
    assert response == 'OK'
</code></pre>

<p>After the message is locked for processing, it gets uploaded to the IMAP
account into the folder specified in the configuration. The class has
a <code>get_imap_connection</code> method that calls the appropriate <code>imaplib</code>
constructors and takes care of connection pooling to avoid connection and
disconnection for every message processed. The return value of the IMAP
server is checked to avoid sil&#x65;nt fail.</p>

<pre><code class="python">except:
    with db:
        cur.execute('DELETE FROM messages WHERE hash = ? AND account = ?',
            params)
    raise
else:
    print('Appended', msg_hash, 'to', account)
    with db:
        cur.execute(
            'UPDATE messages SET success = 1 WHERE hash = ? AND account = ?',
            params)
</code></pre>

<p>In case of errors, the message lock gets released and the exception is
re-raised to stop the process. Otherwise, the <code>success</code> flag is set to <code>1</code>,
and processing continues with the next message. Source code is available in
<a href="https://github.com/dnet/outbox-sync">my GitHub repository</a> under MIT license, feel free to fork and send pull
requests or comment on the code there.</p>
]]></content>
	</entry>
	<entry>
		<title>Two tools to aid protocol reverse engineering</title>
		<link rel="alternate" type="text/html" href="http://techblog.vsza.hu/posts/Two_tools_to_aid_protocol_reverse_engineering.html"/>
		<updated>2013-03-14T16:49:50+01:00</updated>
      <id>http://techblog.vsza.hu/posts/Two_tools_to_aid_protocol_reverse_engineering.html</id>
      <author><name>dnet</name></author>
		<category term="POSTCATEGORY" scheme="http://www.sixapart.com/ns/types#category"/>
		<content type="html" xml:lang="en" xml:base="http://techblog.vsza.hu"><![CDATA[
      <p>Lately I analyzed a closed-source proprietary thick client application that
rolled its own cryptography, including the one used for the network layer.
To aid the protocol analysis, I needed two tools with a shared input. The
input was the flow of packets sent and received by the application, which I
first tried to extract using the hex output of <a href="http://www.wireshark.org/docs/man-pages/tshark.html">tshark</a>, but I realized
that it displayed data from layers above TCP I didn't need, and on the
other hand, it didn't perform TCP reassembly, which I didn't want to do
by hand or reinventing the wheel.</p>

<p>So I decided to use the output of the <a href="http://www.wireshark.org/docs/wsug_html_chunked/ChAdvFollowTCPSection.html">Follow TCP stream function of
Wireshark</a>, in hex mode to be precise. It can be saved to a plain text
file with a single click, and it just had what I needed: offsets and easily
parseable hex data. I've written a simple parser based on regular expressions
that could read such file, starting by defining the actual expressions. The
first one matches a single line, starting with whitespace in case of packets
<em>sent</em>, and nothing if <em>received</em> (group 1). This is followed by a hex offset
of the row (group 2), the row data encoded in 1 to 16 hex bytes (group 3),
and the ASCII dump of the row data. Latter is padded, so by limiting group 3
to 49 characters, it could be ignored effectively. I used the <code>re.I</code> flag so
I didn't have to write <code>a-fA-F</code> everywhere instead of <code>a-f</code> explicitly.</p>

<pre><code>import re

FLOW_ROW_RE = re.compile(r'^(\s*)([0-9a-f]+)\s+([0-9a-f\s]{1,49})', re.I)
NON_HEX_RE = re.compile(r'[^0-9a-f]', re.I)
</code></pre>

<p>The <code>Flow</code> class itself is a list of entries, so I made the class inherit
from <code>list</code> and added a custom constructor. I also added an inner class called
<code>Entry</code> for the entries and two constants to indicate packet directions.
I used a <a href="http://docs.python.org/2/library/collections.html#collections.namedtuple">namedtuple</a> to provide some formality over using a <code>dict</code>.
The constructor expects the name of a file from Wireshark, opens it and
populates the list using the parent constructor and a generator function
called <code>load_flow</code>.</p>

<pre><code class="python">from collections import namedtuple

class Flow(list):
    Entry = namedtuple('Entry', ['direction', 'data', 'offset'])
    SENT = 'sent'
    RECEIVED = 'received'
    DIRECTIONS = [SENT, RECEIVED]

    def __init__(self, fil&#x65;name):
        with file(fil&#x65;name, 'r') as flow_file:
            list.__init__(self, load_flow(flow_file))
</code></pre>

<p>This <code>load_flow</code> got a file object, which it used as an iterator, returning
each line of the input file. It got mapped using <code>imap</code> to regular expression
match objects, and filtered using <code>ifilter</code> to ignore rows that didn't match.
In the body of the loop, all three match groups are parsed, and sanity checks
are performed on the offset to make sure to bytes were lost during parsing.
For this purpose, a <code>dict</code> is used, initialized to zeros before the loop,
and incremented after each row to measure the number of bytes read in both
directions.</p>

<pre><code class="python">from binascii import unhexlify
from itertools import imap, ifilter

def load_flow(flow_file):
    offset_cache = {Flow.SENT: 0, Flow.RECEIVED: 0}
    for m in ifilter(None, imap(FLOW_ROW_RE.match, flow_file)):
        direction = Flow.SENT if m.group(1) == '' else Flow.RECEIVED
        offset = int(m.group(2), 16)
        data = unhexlify(NON_HEX_RE.sub('', m.group(3)))
        last_offset = offset_cache[direction]
        assert last_offset == offset
        offset_cache[direction] = last_offset + l&#x65;n(data)
</code></pre>

<p>The rest of the function is some code that (as of 14 March 2013) needs some
cleaning, and handles yielding <code>Flow.Entry</code> objects properly, squashing
entries spanning multiple rows at the same time.</p>

<p>As I mentioned in the beginning, there were two kinds of functionality I
needed, both of which use these <code>Flow</code> objects as an input. The first one
is a fake client/server that makes it possible to generate network traffic
quickly by using previously captured flows, called <code>flowfake</code>. It simply
replays flows from a selected viewpoint using plain sockets, either as
a client or a server.</p>

<p>The second one is more interesting and complex (at least for me) as it makes
possible to view the differences (or similarities, depending on the use-case)
between 2 to 4 flows (latter being an ad-hoc limit based on the colors
defined) using simple algorithms and colors to aid visual analysis. For better
understanding, see the screenshot below to understand how it works on four
flows. The whole project is available under MIT license in a <a href="https://github.com/dnet/flowtools">GitHub repo</a>.</p>

<p><img src="http://techblog.vsza.hu/images/flowdiff-screenshot.png" alt="Screenshot of flowdiff" title="" /></p>
]]></content>
	</entry>
	<entry>
		<title>Generating XSRF PoC from Burp with Python</title>
		<link rel="alternate" type="text/html" href="http://techblog.vsza.hu/posts/Generating_XSRF_PoC_from_Burp_with_Python.html"/>
		<updated>2013-02-20T17:23:30+01:00</updated>
      <id>http://techblog.vsza.hu/posts/Generating_XSRF_PoC_from_Burp_with_Python.html</id>
      <author><name>dnet</name></author>
		<category term="POSTCATEGORY" scheme="http://www.sixapart.com/ns/types#category"/>
		<content type="html" xml:lang="en" xml:base="http://techblog.vsza.hu"><![CDATA[
      <p><a href="http://portswigger.net/burp/">Burp Suite</a> is the tool I'd feel lost without when testing web applications,
we even bought the pro version, since it's a great tool with a low price tag.
One of its great features is <a href="http://portswigger.net/burp/help/suite_functions_csrfpoc.html">generating proof-of-concept HTML forms</a>
for <a href="https://en.wikipedia.org/wiki/Cross-site_request_forgery">Cross-Site Request Forgery</a> (CSRF or XSRF) testing, and it usually
just works out of the box. As it works using HTTP POST data, it has no
information about the character-level encoding of the data, so when it comes
to applications with accented characters (not a rare thing in Hungary), it
just generates garbage, which needs to be fixed manually, but it's not a big
problem.</p>

<p>However, today, I met another limitation; when testing an ASP.NET application
with quite a big <a href="https://en.wikipedia.org/wiki/ASP.NET#View_state">ViewState</a> (the HTTP post request was around 150 KB),
Burp outputs only the first 4096 byte or so, and then continues to build the
next field, even without closing the <code>&lt;input&gt;</code> tag or its <code>value</code> attribute.
(It's also obvious from this that it uses string manipulation to serialize
data into HTML, which sounds odd from a security-related software product.)</p>

<p>Since I really needed a working solution, I created a simple Python script
to parse the XML export of a HTTP request from Burp and create an HTML page
with a form that have values sent in the request preset. I used <a href="http://docs.python.org/2/library/urlparse.html">LXML</a> to
both parse the input XML and serialize the HTML output to avoid the pitfalls
Burp met, and first, I loaded the Burp XML request file. XPath was used to
get the first item (such exports can store more than one), and to extract
the method, URL and request information. Using the single-element tuple
assignment syntax asserts that the right-hand side of the assignment contains
one and only one element, asserting the sanity of the input.</p>

<pre><code class="python">from lxml import etree

root = etree.parse(input_file).getroot()
item = root.xpath("/items/item")[0]
(method,) = item.xpath("method/text()")
if method.lower() != "post":
    raise ValueError("Only POST requests are supported")
(url,) = item.xpath("url/text()")
(request,) = item.xpath("request")
</code></pre>

<p>Burp can encode the request body using Base64, so it should be checked for and
decoded if necessary. The resulting body contains the HTTP headers and the
encoded POST data, separated by an empty line, so splitting it is pretty
straightforward. The second parameter of the <code>split</code> method stops after the
first split, and naming the first result with an underscore makes it apparent
for both humans and machines that we don't care about that piece of data.</p>

<pre><code class="python">from base64 import b64decode

contents = request.text
if request.get("base64"):
    contents = b64decode(contents)
_, body = contents.split("\r\n\r\n", 1)
</code></pre>

<p>I wrote a small generator function that yields the names and values of each
form field as tuples of Unicode objects. I initially used string manipulation,
then discovered that Python had me covered with <a href="http://docs.python.org/2/library/urlparse.html">urlparse</a>.</p>

<pre><code class="python">from urlparse import parse_qsl

def decode_form_url&#x65;ncoded_values(request_body, encoding):
    for pair in parse_qsl(request_body, keep_blank_values=True):
        yield tuple(i.decode(encoding) for i in pair)
</code></pre>

<p>With this done, I just had to build the resulting HTML. I used LXML's
<a href="http://lxml.de/lxmlhtml.html#creating-html-with-the-e-factory">E-Factory</a> and Python's <a href="http://docs.python.org/2/tutorial/controlflow.html#unpacking-argument-lists">argument list unpacking</a> to make it happen in
a more or less readable way.</p>

<pre><code class="python">from lxml.html import builder as E
import codecs

output = E.HTML(
    E.HEAD(E.META(**{'http-equiv': 'Content-type',
        'content': 'text/html; charset=' + encoding})),
    E.BODY(
        E.FORM(
            E.INPUT(type="submit"),
            *(E.INPUT(type="hidden", name=name, value=value) for name, value
                in decode_form_url&#x65;ncoded_values(body, encoding)),
            action=url, method=method
            )
        )
    )
with codecs.open(output_file, 'wb', encoding) as html_output:
    html_output.write(html.tostring(output, encoding=unicode))
</code></pre>

<p>The complete and working script can be downloaded from
<a href="https://github.com/dnet/burp-scripts/blob/master/burp-csrf.py">my GitHub repository</a>, and in case you've been wondering if it was worth
it; yes, the PoC proved that the target application with the 150 KB ViewState
was indeed vulnerable to XSRF.</p>
]]></content>
	</entry>
	<entry>
		<title>LibreOffice 4.0 workaround for read-only FS</title>
		<link rel="alternate" type="text/html" href="http://techblog.vsza.hu/posts/LibreOffice_4.0_workaround_for_read-only_FS.html"/>
		<updated>2013-02-10T14:53:52+01:00</updated>
      <id>http://techblog.vsza.hu/posts/LibreOffice_4.0_workaround_for_read-only_FS.html</id>
      <author><name>dnet</name></author>
		<category term="POSTCATEGORY" scheme="http://www.sixapart.com/ns/types#category"/>
		<content type="html" xml:lang="en" xml:base="http://techblog.vsza.hu"><![CDATA[
      <p><a href="http://www.libreoffice.org/download/4-0-new-features-and-fixes/">LibreOffice 4.0</a> got released on 7<sup>th</sup> February, and since it
offered improved OOXML interoperability, I immediately downloaded and
installed it on my laptop. It worked quite well, but after the next boot, it
just flashed the window for a tenth of a second, and displayed the following
output on the console.</p>

<pre><code>Fatal Python error: Py_Initialize: Unable to get the locale encoding
Traceback (most recent call last):
  File "&lt;frozen importlib._bootstrap&gt;", line 1558, in _find_and_load
  File "&lt;frozen importlib._bootstrap&gt;", line 1525, in _find_and_load_unlocked
  File "&lt;frozen importlib._bootstrap&gt;", line 586, in _check_name_wrapper
  File "&lt;frozen importlib._bootstrap&gt;", line 1023, in load_module
  File "&lt;frozen importlib._bootstrap&gt;", line 1004, in load_module
  File "&lt;frozen importlib._bootstrap&gt;", line 562, in module_for_loader_wrapper
  File "&lt;frozen importlib._bootstrap&gt;", line 854, in _load_module
  File "&lt;frozen importlib._bootstrap&gt;", line 990, in get_code
  File "&lt;frozen importlib._bootstrap&gt;", line 1051, in _cache_bytecode
  File "&lt;frozen importlib._bootstrap&gt;", line 1065, in set_data
OSError: [Errno 30] Read-only file system: '/usr/local/opt/libreoffice4.0/program/../program/python-core-3.3.0/lib/encodings/__pycache__'
</code></pre>

<p>I symlinked <code>/opt</code> to <code>/usr/local/opt</code>, and for many reasons (including
faster boot, storing <code>/usr</code> on an SSD) I mount <code>/usr</code> in read-only mode by
default, and use the following snippet in <code>/etc/apt/apt.conf.d/12remount</code>
to do the magic upon system upgrade and software installs.</p>

<pre><code>DPkg
{
    Pre-Invoke {"mount -o remount,rw /usr &amp;&amp; mount -o remount,exec /var &amp;&amp; mount -o remount,exec /tmp";};
    Post-Invoke {"mount -o remount,ro /usr ; mount -o remount,noexec /var &amp;&amp; mount -o remount,noexec /tmp";};
}
</code></pre>

<p>It seems that LibreOffice 4.0 tries to put compiled Python objects into a
persistent cache, and since it resides on a read-only filesystem, it cannot
even create the <code>__pycache__</code> directories needed for that. My workaround is
the following shell script that needs to be ran just once, and works quite
well by letting LibreOffice put its cached <code>pyc</code> files into <code>/tmp</code>.</p>

<pre><code>#!/bin/sh
mount /usr -o rw,remount
find /opt/libreoffice4.0/program/python-core-3.3.0/lib -type d \
    -exec ln -s /tmp {}/__pycache__ \;
mount /usr -o ro,remount
</code></pre>
]]></content>
	</entry>
	<entry>
		<title>Four free software I started using in 2012</title>
		<link rel="alternate" type="text/html" href="http://techblog.vsza.hu/posts/Four_free_software_I_started_using_in_2012.html"/>
		<updated>2013-02-02T00:11:06+01:00</updated>
      <id>http://techblog.vsza.hu/posts/Four_free_software_I_started_using_in_2012.html</id>
      <author><name>dnet</name></author>
		<category term="POSTCATEGORY" scheme="http://www.sixapart.com/ns/types#category"/>
		<content type="html" xml:lang="en" xml:base="http://techblog.vsza.hu"><![CDATA[
      <p>At the end of 2012, I realized that two of the software I started using in that
year started with the letter 'm', and later, I remembered two other as well, so
here's this post to document what I used in 2013.</p>

<h4>mcabber (console XMPP a.k.a. Jabber client with built-in OTR support)</h4>

<p>In the last ten years, I always preferred IRC to XMPP/MSN Messenger/Skype since
although all of them has both the option to one-to-one and many-to-many chat,
latter is the common use-case for IRC while former is with all the others.
That's when <a href="https://www.ctrlc.hu/~stef/blog/">Stefan</a> showed me <a href="http://www.cypherpunks.ca/otr/">OTR</a> (Off-the-Record) messaging, which
provided strong autentication and encryption along with deniability afterwards.
We started experimenting with version 1 on IRC using <a href="http://irssi-otr.tuxfamily.org/">irssi-otr</a>, but found
it to be quite unstable, and another big problem was that I prefer to run irssi
on a remote server, which defies the whole purpose of the end-to-end security
OTR aims to provide.</p>

<p>So I decided to give it a try with XMPP, especially since
<a href="http://hsbp.org/">H.A.C.K.</a> has its own server – with registration available to anyone – at
<code>xmpp.hsbp.org</code>. Stefan recommended me <a href="http://mcabber.com/">mcabber</a> as a client, and although
it has its limitations (for example, it cannot connect to multiple servers and
I had to use <a href="http://pidgin.im/">Pidgin</a> for registration), I found it perfect for my
use-cases, as it has built-in support for OTR up to version 2, and has a nice
console UI.</p>

<p><img src="http://techblog.vsza.hu/images/mcabber-shot.png" alt="mcabber in action" title="" /></p>

<h4>minidlna (lightweight DLNA/UPnP media server)</h4>

<p>I didn't know what DLNA was before I got my hands on a device that actually
supported it, then I started using <a href="http://www.serviio.org/">Serviio</a>, but it had its limitations.
It required Java, updated the local repository really slow, had an awful and
complicated GUI – and had I mentioned it ran on Java? After a week, I started
looking for alternatives, I naïvely typed <code>apt-cache search dlna</code> and
that's how I <del>met</del> found <a href="http://sourceforge.net/projects/minidlna/">minidlna</a>, which was quite the opposite
of Serviio.</p>

<p>It consisted of a single native executable, a config file
and some docs, and since it's targeted at embedded systems, it ran quite fast
on my dual i3 notebook. The Debian version runs as an unprivileged user by
default, and I added my user to the <code>minidlna</code> group, so I can just drop/link
files into the <code>/var/lib/minidlna</code> directory, and they just become accessible
for any DLNA consumer. In case of content from Bittorrent, I can even
download it to a remote server, mount it with <a href="http://fuse.sourceforge.net/sshfs.html">sshfs</a> (also one of my
favorite solutions), symlink it into the directory, and the TV magically plays
the file from the remote server via my notebook over the home Wi-Fi, which
works suprisingly well even in case of HD contents. Also, on Debian, the DLNA
icon is a Debian swirl logo, so it even looks great in the TV menu. :)</p>

<p><img src="http://techblog.vsza.hu/images/minidlna-allshare.jpg" alt="minidlna in action" title="" /></p>

<h4>mosh (SSH <del>replacement</del> extension for roaming clients and laggy connections)</h4>

<p>I think SSH is one of those software that demonstrate the power of “the Unix
way” the best. I use it for lots of purposes, but at the same time, I've found it
really hard to use in case of laggy connections. I cannot even decide, which
one I hate better, both cellular data connections (GPRS, EDGE, 3G, etc.) and
suboptimal Wi-Fi networks can make me want to smash the keyboard. After using
<a href="http://mosh.mit.edu/">mosh</a> while uploading huge videos over a consumer-grade asymmetric uplink,
I also found that networks without QoS can also make the interactive SSH
experience turn into a text-based RPG.</p>

<p>I installed mosh on the two boxes I
most regularly log into via SSH, and found it really useful, especially since
<a href="http://dan.drown.org/android/mosh/">Daniel Drown patched mosh support into ConnectBot</a>, an Android terminal
emulator and SSH client, which makes sense, since handheld devices have the
most chance to be connected to networks matching the description above. Although
some say it breaks interactive applications like VIM, I had no problems with
version 1.2.3 I downloaded and compiled almost two months ago, so if you also
find yourself connected to laggy networks, give it a try!</p>

<p><img src="http://vsza.hu/mosh-android.png" alt="mosh in action on Android" title="" /></p>

<h4>mutt (the mail user agent that sucks less)</h4>

<p>I've been a <a href="http://userbase.kde.org/KMail">KMail</a> user since around 2007 and although I saw many of my
friends using <a href="http://www.mutt.org/">mutt</a> with server-side magic, I used it just like my
window manager and my shell – a tool, which I used until it worked without
a hassle. When it <a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=588979">misbehaved</a> or <a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=590124">crashed</a> (it did so <a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=622986">quite a</a>
<a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=687382">few times</a>), I sent bugreports, partly to make myself feel better, partly
to evade “and have you reported it” questions, but I also hoped that they'll
fix these properly. Then one day, during an IMAP mass move operation, KMail
crashed, and did so even after restart. I've had quite an experience in
bruteforcing KMail into a working state from the past, but when I couldn't
change the situation in half an hour, I decided that it's time to change.</p>

<p>I had three mailboxes on two IMAPS servers with two distinct SMTPSA MTAs to
send mails through, and I also used client-side filtering extensively.
I migrated latter functionality to <a href="http://www.procmail.org/">procmail</a> on one of the servers,
and as of February 2013, I use a transitional setup with on-line IMAP
mailboxes and a local header cache. In the near future, I plan to migrate
online IMAP access to a solution based on <a href="http://offlineimap.org/">offlineimap</a> and run a
local MTA that forwards mail to the appropriate SMTP server, preferably
through a tunnel/VPN to avoid password authentication and my endpoint IP
address appearing in the MIME envelope.</p>

<p>I only had one problem so far, it
seems that the online IMAP functionality is not so well-tested in mutt, so
even though I use Debian testing, it crashed in around 30% of the cases
when changing IMAP directories, but I managed to solve it by compiling
Mutt from source, including the <a href="http://www.lunar-linux.org/mutt-sidebar/">folder sidebar patch</a>. Here's how it
looks with the current config, displaying the Python SOAP mailing list.</p>

<p><img src="http://techblog.vsza.hu/images/mutt-shot.png" alt="mosh in action on Android" title="" /></p>
]]></content>
	</entry>
	<entry>
		<title>FFmpeg recipes for workshop videos</title>
		<link rel="alternate" type="text/html" href="http://techblog.vsza.hu/posts/FFmpeg_recipes_for_workshop_videos.html"/>
		<updated>2013-01-23T16:47:33+01:00</updated>
      <id>http://techblog.vsza.hu/posts/FFmpeg_recipes_for_workshop_videos.html</id>
      <author><name>dnet</name></author>
		<category term="POSTCATEGORY" scheme="http://www.sixapart.com/ns/types#category"/>
		<content type="html" xml:lang="en" xml:base="http://techblog.vsza.hu"><![CDATA[
      <p>In November 2012, I started doing <a href="http://hsbp.org/arduino#Arduino_workshop">Arduino workshops</a> in <a href="http://hackerspaces.org/wiki/Hackerspace_Budapest">H.A.C.K.</a>
and after I announced it on some local channels, some people <a href="http://hup.hu/node/119014#comment-1527012">asked if it
could be recorded and published</a>. At first, it seemed that recording
video would require the least effort to publish what we've done, and while
I though otherwise after the first one, now we have a collection of simple
and robust tools and snippets that glue them together that can be reused
for all future workshops.</p>

<p>The recording part was simple, I won't write about it outside this paragraph,
but although the following thoughts might seem trivial, important things
cannot be repeated enough times. Although the built-in microphones are great
for lots of purposes, unless you're sitting in a sil&#x65;nt room (no noise from
machines nor people) or you already use a microphone with an amplifier,
a microphone closer to the speaker should be used. We already got a cheap
lavalier microphone with a preamplifier and 5 meters of cable, so we used
that. It also helps if the camera operator has a headphone, so the volume
level can be checked, and you won't freak out after importing the video to
the PC that either the level is so low that it has lots of noise or it's so
high that it becomes distorted.</p>

<p>I used a DV camera, so running <code>dvgrab</code> resulted in <code>dvgrab-*.dv</code> files.
Although the automatic splitting is sometimes desireable (not just because of
crippled file systems, but it makes it possible to transfer each file after
it's closed, lowering the amount of drive space needed), if not, it can be
disabled by setting the split size to zero using <code>-size 0</code>. It's also handy
to enable automatic splitting upon new recordings with <code>-autosplit</code>. Finally,
<code>-timestamp</code> gives meaningful names to the files by using the metadata
recorded on the tape, including the exact date and time.</p>

<p>The camera I used had a stereo microphone and a matching stereo connector, but
the microphone was mono, with a connector that shorted the right channel and
the ground of the input jack, the audio track had a left channel carrying the
sound, and a right one with total sil&#x65;nce. My problem was that most software
handled channel reduction by calculating an average, so the amplitude of the
resulting mono track was half of the original. Fortunately, I found that
<a href="http://ffmpeg.org/">ffmpeg</a> is <a href="http://stackoverflow.com/a/10483086">capable of powerful audio panning</a>, so the following
parameter takes a stereo audio track, discards the right channel, and uses
the left audio channel as a mono output.</p>

<pre><code>-filter_complex "pan=1:c0=c0"
</code></pre>

<p>I also wanted to have a little watermark in the corner to inform viewers about
the web page of our hackerspace, so I created an image with matching resolution
in GIMP, wrote the domain name in the corner, and made it semi-transparent.
I used this method with Mencoder too, but FFmpeg can handle PNGs with 8-bit
alpha channels out-of-the-box. The following, combined command line adds the
watermark, fixes the audio track, and encodes the output using <a href="https://en.wikipedia.org/wiki/H.264/MPEG-4_AVC">H.264</a>
into an MKV container.</p>

<pre><code class="no-highlight">&#x24; ffmpeg -i input.dv -i watermark.png -filter_complex "pan=1:c0=c0" \
    -filter_complex 'overlay' -vcodec libx264 output.mkv
</code></pre>

<p>A cropped sample frame of the output can be seen below, with the zoomed
watermark opened in GIMP in the corner.</p>

<p><img src="http://techblog.vsza.hu/images/hsbp.org-watermark.png" alt="hsbp.org watermark" title="" /></p>

<p>I chose MKV (<a href="https://en.wikipedia.org/wiki/Matroska">Matroska</a>) because of the great tools provided by
<a href="http://www.bunkus.org/videotools/mkvtoolnix/">MKVToolNix</a> (packaged under the same name in lowercase for Debian and
Ubuntu) that make it possible to merge files later in a safe way. Merging
was needed in my case for two reasons.</p>

<ul>
<li>If I had to work with split <code>.dv</code> files, I converted them to <code>.mkv</code> files
 one by one, and merged them in the end.</li>
<li>I wanted to add a title to the beginning, which also required a merge with
 the recorded material.</li>
</ul>

<p>I tried putting the title screen together from scratch, but I found it much
easier to take the first 8 seconds of an already done MKV using <code>mkvmerge</code>,
then placed a fully opaque title image of matching size using the overlay I
wrote about above, and finally replace the sound with sil&#x65;nce. In terms of
shell commands, it's like the following.</p>

<pre><code>ffmpeg -i input.mkv -i title.png -filter_complex 'overlay' -an \
    -vcodec libx264 title-img.mkv
mkvmerge -o title-img-8s.mkv --split timecodes:00:00:08 title-img.mkv
rm -f title-img-8s-002.mkv
ffmpeg -i title-img-8s-001.mkv -f lavfi -i "aevalsrc=0::s=48000" \
    -shortest -c:v copy title.mkv
rm -f title-img-8s-001.mkv
</code></pre>

<p>The first FFmpeg invocation disables audio using the <code>-an</code> switch, and produces
<code>title-img.mkv</code> that contains our PNG image in the video track, and has no
audio. Then <code>mkvmerge</code> splits it into two files, an 8 seconds long
<code>title-img-8s-001.mkv</code>, and the rest as <code>title-img-8s-002.mkv</code>. Latter gets
discarded right away, and a second FFmpeg invocation adds an audio track
containing nothing but sil&#x65;nce with a frequency (48 kHz) matching that of the
recording. The <code>-c:v copy</code> parameter ensures that no video recompression is
done, and <code>-shortest</code> discourages FFmpeg from trying to read as long as at
least one input has data, since <code>aevalsrc</code> would generate sil&#x65;nce forever.</p>

<p>Finally, the title(s) and recording(s) can be joined together by using
<code>mkvmerge</code> for the purpose its name suggest at last. If you're lucky, the
command line is as simple as the following:</p>

<pre><code class="no-highlight">&#x24; mkvmerge -o workshop.mkv title.mkv + rec1.mkv + rec2.mkv
</code></pre>

<p>If you produced your input files using the methods described above, if it
displays an error message, it's almost certainly the following (since all
resolution/codec/etc. parameters should match, right?).</p>

<pre><code class="no-highlight">No append mapping was given for the file no. 1 ('rec1.mkv'). A default
mapping of 1:0:0:0,1:1:0:1 will be used instead. Please keep that in mind
if mkvmerge aborts with an error message regarding invalid '--append-to'
options.
Error: The track number 0 from the file 'dvgrab-001.mkv' cannot be
appended to the track number 0 from the file 'title.mkv'. The formats do
not match.
</code></pre>

<p>As the error message suggests, the order of the tracks can differ between MKV
files, so an explicit mapping must be provided to <code>mkvmerge</code> for matching the
tracks befor concatenation. The mapping for the most common case (a single audio
and a single video track) is the following.</p>

<pre><code class="no-highlight">&#x24; mkvmerge -o workshop.mkv t.mkv --append-to '1:0:0:1,1:1:0:0' + r1.mkv
</code></pre>

<p>I've had a pretty good experience with H.264-encoded MKV files, the size stayed
reasonable, and most players had no problem with it. It also supports subtitles,
and since YouTube and other video sharing sites accept it as well, with these
tips, I hope it gets used more in recording and publishing workshops.</p>
]]></content>
	</entry>
	<entry>
		<title>Complementing Python GPGME with M2Crypto</title>
		<link rel="alternate" type="text/html" href="http://techblog.vsza.hu/posts/Complementing_Python_GPGME_with_M2Crypto.html"/>
		<updated>2012-12-31T20:00:59+01:00</updated>
      <id>http://techblog.vsza.hu/posts/Complementing_Python_GPGME_with_M2Crypto.html</id>
      <author><name>dnet</name></author>
		<category term="POSTCATEGORY" scheme="http://www.sixapart.com/ns/types#category"/>
		<content type="html" xml:lang="en" xml:base="http://techblog.vsza.hu"><![CDATA[
      <p>While the <a href="http://www.gnupg.org/related_software/gpgme/">GPGME</a> Python bindings provide interface to most of the
functionality provided by <a href="http://www.gnupg.org/">GnuPG</a>, so I could generate keys and perform
encryption and decryption using them, I found that it wasn't possible to
list, which public keys can decrypt a PGP encrypted file. Of course, it's
always a possibility to invoke the <code>gpg</code> binary, but I wanted to avoid
spawning processes if possible.</p>

<p>As <a href="http://stackoverflow.com/a/1042139">Heikki Toivonen mentioned in a Stack Overflow thread</a>, the
<a href="http://chandlerproject.org/Projects/MeTooCrypto">M2Crypto</a> library had a PGP module, and based on a <a href="http://svn.osafoundation.org/m2crypto/trunk/demo/pgp/pgpstep.py">demo code</a>, it
seemed to be able to parse OpenPGP files into meaningful structures, including
<code>pke_packet</code> that contains an attribute called <code>keyid</code>. I installed the module
from the Debian package <code>python-m2crypto</code>, tried calling the PGP parser
functionality, and found that</p>

<ul>
<li>the <code>keyid</code> attribute is called <code>_keyid</code> now, and</li>
<li>after returning the <code>pke_packet</code> instances, it raises an <code>XXXError</code> in
 case of OpenPGP output generated by GnuPG 1.4.12.</li>
</ul>

<p>It's also important to note that the M2Crypto keyid is an 8 bytes long raw
byte string, while GPGME uses 16 characters long uppercase hex strings for the
same purpose. I chose to convert the former to the latter format, resulting in
a <code>set</code> of hexadecimal key IDs. Later, I could check, which keys available in
the current keyring are able to decrypt the file. The <code>get_acl</code> function thus
returns a <code>dict</code> mapping e-mail addresses to a boolean value that indicates
the key's ability to decrypt the file specified in the <code>fil&#x65;name</code> parameter.</p>

<pre><code>from M2Crypto import PGP
from contextlib import closing
from binascii import hexlify
import gpgme

def get_acl(fil&#x65;name):
    with file(fil&#x65;name, 'rb') as stream:
        with closing(PGP.packet_stream(stream)) as ps:
            own_pk = set(packet_stream2hexkeys(ps))
    return dict(
            (k.uids[0].email, any(s.keyid in own_pk for s in k.subkeys))
            for k in gpgme.Context().keylist())

def packet_stream2hexkeys(ps):
    try:
        while True:
            pkt = ps.read()
            if pkt is None:
                break
            elif pkt and isinstance(pkt, PGP.pke_packet):
                yield hexlify(pkt._keyid).upper()
    except:
        pass
</code></pre>
]]></content>
	</entry>
	<entry>
		<title>Connecting Baofeng UV-5R to a Linux box</title>
		<link rel="alternate" type="text/html" href="http://techblog.vsza.hu/posts/Connecting_Baofeng_UV-5R_to_a_Linux_box.html"/>
		<updated>2012-12-23T00:52:15+01:00</updated>
      <id>http://techblog.vsza.hu/posts/Connecting_Baofeng_UV-5R_to_a_Linux_box.html</id>
      <author><name>dnet</name></author>
		<category term="POSTCATEGORY" scheme="http://www.sixapart.com/ns/types#category"/>
		<content type="html" xml:lang="en" xml:base="http://techblog.vsza.hu"><![CDATA[
      <p>Ever since I bought my <a href="http://www.universal-radio.com/catalog/ht/0205.html">Baofeng UV-5R</a> handheld VHF/UHF FM transceiver, I
wanted to hook it up to my notebook – partly to populate the channel list
without fighting the crippled UI, partly out of curiosity. First, I had to
build a cable, since I didn't receive one in the package, and it would've cost
at least around 20 bucks to get my hands on one – plus the delay involved in
postal delivery. In a <a href="http://groups.yahoo.com/group/baofeng_uv5r/message/7184">Yahoo! group, jwheatleyus mentioned</a> the following
pinout:</p>

<ul>
<li>3.5mm Plug Programming Pins
<ul>
<li>Sleeve: Mic – (and PTT) Rx Data</li>
<li>Ring: Mic +</li>
<li>Tip: +V</li>
</ul></li>
<li>2.5mm Plug
<ul>
<li>Sleeve: Speaker – (and PTT) Data GND</li>
<li>Ring: Tx Data</li>
<li>Tip: Speaker +</li>
</ul></li>
<li>Connect Sleeve to Sleeve for PTT</li>
</ul>

<p>I took apart the headset bundled with the gear, and verified this pinout in
case of the Mic/Speaker/PTT lines with a multimeter, so I only had to connect
these pins to the notebook. Since I already had an <a href="http://www.ftdichip.com/Products/Cables/USBTTLSerial.htm">FTDI TTL-232R-5V</a> cable
lying around for use with my <a href="http://www.evilmadscientist.com/2010/diavolino/">Diavolino</a> (actually, I won both of them on
the <a href="http://events.ccc.de/congress/2010/wiki/Hardware_Hacking_Area#LoL_Shield_Contest">LoL shield contest at 27C3</a>), I created a breakout board that can be
connected to the radio, and had pin headers just in the right order for the
FTDI cable and two others for speaker and mic lines. The schematic and the
resulting hardware can be seen below.</p>

<p><img src="http://techblog.vsza.hu/images/baofeng_breakout.png" alt="Baofeng UV-5R breakout board" title="" /></p>

<p>With the physical layer ready, I only had to find some way to manipulate the
radio using software running on the notebook. While many software available
for this radio is either closed and/or available for Windows only, I found
<a href="http://chirp.danplanet.com">Chirp</a>, a FLOSS solution written in Python (thus available for all sane
platforms) which – as of this writing – could access Baofeng UV-5R in the
experimental <a href="http://chirp.danplanet.com/projects/chirp/wiki/Download#Development-builds">daily builds</a>. Like most Python software, Chirp doesn't
require any install procedures either, downloading and extracting the
tarball led to a functional and minimalistic GUI. First, I set the second
tuner to display the name of the channel, and uploaded a channel list with
the <a href="http://www.ha5kdr.hu/projektek/sstv">Hármashatár-hegy SSTV relay</a> (thus the name HHHSSTV) at position 2,
with the following results.</p>

<p><img src="http://techblog.vsza.hu/images/hhhsstv.jpg" alt="HHHSSTV channel stored on Baofeng UV-5R" title="" /></p>

<p>I could also access an interesting tab named <em>other settings</em> that made it
possible to edit the message displayed upon startup and limit the frequency
range in both bands.</p>

<p><img src="http://techblog.vsza.hu/images/baofeng-bootmsg.png" alt="Other settings and their effect on Baofeng UV-5R" title="" /></p>

<p>Although Chirp states that the driver for UV-5R is still experimental, I
didn't have any problems with it, and as it's written in Python, its code is
readable and extensible, while avoiding cryptic dependencies. It's definitely
worth a try, and if lack of PC connectivity without proprietary software was
a reason for you to avoid this radio, then I have good news for you.</p>
]]></content>
	</entry>
	<entry>
		<title>Restricting SSH access to rsync for Android</title>
		<link rel="alternate" type="text/html" href="http://techblog.vsza.hu/posts/Restricting_SSH_access_to_rsync_for_Android.html"/>
		<updated>2012-11-30T12:10:59+01:00</updated>
      <id>http://techblog.vsza.hu/posts/Restricting_SSH_access_to_rsync_for_Android.html</id>
      <author><name>dnet</name></author>
		<category term="POSTCATEGORY" scheme="http://www.sixapart.com/ns/types#category"/>
		<content type="html" xml:lang="en" xml:base="http://techblog.vsza.hu"><![CDATA[
      <p>I like to synchronize photos taken with my Android phone with my notebook, and
since I dislike centralized solutions (mostly for reasons of privacy), I
installed <a href="https://play.google.com/store/apps/details?id=eu.kowalczuk.rsync4android">rsync for Android</a>, which is easy to install from Play Store,
and <a href="http://android.kowalczuk.eu/rsync4android/">with SSH public key authentication</a>, syncing the images is easy and
secure at the same time.</p>

<p>My problem was that still hadn't collected enough information to trust my phone
with powerful public keys (even though I use <a href="http://thialfihar.org/projects/apg/">APG</a>, I only added public keys
so far), and having a key on my phone that could allow anyone to log into my
notebook through SSH was unacceptable for me, even though I set up a separate
user account, and SSH wasn't set up to start at boot.</p>

<p>To solve this problem, I logged what command the application started upon
connecting via SSH, and added the following line to the <code>authorized_keys</code> file
in the <code>.ssh</code> subdirectory of the home directory of the dedicated user (<code>foo</code>).
The lines are split only for easier readability, there should be no line break
or whitespace between <code>no-port-forwarding,</code> and <code>no-agent-forwarding</code>.</p>

<pre><code>command="rsync --server -vlHDtre.i . /home/foo/images",no-port-forwarding,
    no-agent-forwarding,no-X11-forwarding,no-pty ssh-dss AAAA...
</code></pre>

<p>This way, the private key on the phone can only be used for rsyncing a specific
directory, and cannot be used to</p>

<ul>
<li>open a shell or start any other program, or</li>
<li>forward TCP ports, SSH agent or X11 connections from/to my notebook.</li>
</ul>

<p>Thanks to <a href="https://rhapsodhy.hu/">rhapsodhy</a> for <a href="http://pastebin.com/ivrxjnwC">the inspiration</a>.</p>
]]></content>
	</entry>
	<entry>
		<title>Seesmic Android information leak</title>
		<link rel="alternate" type="text/html" href="http://techblog.vsza.hu/posts/Seesmic_Android_information_leak.html"/>
		<updated>2012-11-13T23:38:08+01:00</updated>
      <id>http://techblog.vsza.hu/posts/Seesmic_Android_information_leak.html</id>
      <author><name>dnet</name></author>
		<category term="POSTCATEGORY" scheme="http://www.sixapart.com/ns/types#category"/>
		<content type="html" xml:lang="en" xml:base="http://techblog.vsza.hu"><![CDATA[
      <p>In the August 2012 <a href="http://hekkcamp.net/">hekkcamp</a> I hunted for security vulnerabilities in
several Android applications and <a href="https://play.google.com/store/apps/details?id=com.seesmic">Seesmic Android</a> happened to be one
of them. I originally heard about it from <a href="https://rhapsodhy.hu/">rhapsodhy</a>, and it's one of
those multi-platform social network clients, this one having the advantage of
not requesting crazy privileges, unlike the official Twitter and Facebook apps.
<a href="http://0x90.freeblog.hu/">Zsombor</a> told me about <a href="http://labs.mwrinfosecurity.com/tools/2012/03/16/mercury/">Mercury</a>, a FLOSS Android vulnerability
assessment tool, so I checked out the latest development version from
<a href="https://github.com/mwrlabs/mercury">their GitHub repo</a> since 1.0.0, the only version available then happened
to be incompatible with recent Android releases.</p>

<p>Using Mercury, I found that Seesmic offers several <a href="http://developer.android.com/guide/topics/providers/content-providers.html">content providers</a> that
not only had interesting names and fields, but were available for reading to
any other application running on the device. As Android separates applications
pretty strictly, these providers are the favorable way of sharing structured
information between apps, and although <a href="http://developer.android.com/guide/topics/providers/content-provider-creating.html#Permissions">they can be protected</a> with
application-specific permissions, many developers tend to forget about such
things. In case of Seesmic, I used the <code>finduri</code> command of Mercury in the
<code>provider</code> module.</p>

<pre><code class="no-highlight">*mercury#provider&gt; finduri com.seesmic

/data/app/com.seesmic-2.apk:
content://cal&#x65;ndar/cal&#x65;ndars
content://cal&#x65;ndar/events
content://cal&#x65;ndar/reminders
content://com.android.cal&#x65;ndar/cal&#x65;ndars
content://com.android.cal&#x65;ndar/events
content://com.android.cal&#x65;ndar/reminders
content://com.google.plus.platform/ads
content://com.google.plus.platform/token
content://com.seesmic.aggregate/aggregate_authors
content://com.seesmic.aggregate/aggregate_timelines
content://com.seesmic.facebook/facebook_authors
content://com.seesmic.facebook/facebook_feeds
content://com.seesmic.facebook/facebook_friendlists
content://com.seesmic.facebook/facebook_page_profiles
content://com.seesmic.facebook/facebook_people
content://com.seesmic.facebook/facebook_profiles
content://com.seesmic.facebook/facebook_updates
content://com.seesmic.twitter/accounts
content://com.seesmic.twitter/attachs
content://com.seesmic.twitter/authors
content://com.seesmic.twitter/dm
content://com.seesmic.twitter/list_info
content://com.seesmic.twitter/lists
content://com.seesmic.twitter/mute
content://com.seesmic.twitter/search_results
content://com.seesmic.twitter/searches
content://com.seesmic.twitter/timelines
content://com.seesmic.twitter/topics
content://com.seesmic.twitter/tweets
content://com.seesmic.twitter/userlists
content://com.seesmic.twitter/users
</code></pre>

<p>In order to inspect the extracted data and provide a nice and simple
proof-of-concept, I developed a small application called CoProLeak
(CoPro = Content Provider) that could show the two of the most problematic
leaks in the Seesmic application. It's worth noting that the application
doesn't require any permissions – as it can be seen on the left frame of the
screenshot below – so it could lurk inside any kind of application or game.</p>

<ul>
<li>The <code>content://com.seesmic.facebook/facebook_people</code> provider made all the Facebook friends of the user available with name, Facebook ID and full contact information. This can be seen in the middle frame of the screenshot below, clicking on a person's name displayed his/her photo using the Facebook graph API in a browser window.</li>
<li>The <code>content://com.seesmic.twitter/accounts</code> provider made all the accounts configured in the application available with username and password or OAuth token and secret. This can be seen in the right frame of the screenshot below, these credentials are enough for anyone to impersonate the user account.</li>
</ul>

<p><img src="http://techblog.vsza.hu/images/cpl-poc.png" alt="Working proof-of-concept displaying sensitive information" title="" /></p>

<p>For example, displaying the list of friends required the following snippet.
(The <code>relationship_type</code> filter was necessary to exclude liked pages that
were also available from the content provider.)</p>

<pre><code>final Uri SEESMIC_FB_PEOPLE_URI = Uri.parse(
        "content://com.seesmic.facebook/facebook_people");
final String[] projection = { "_id", "full_name" };
final String selection = "relationship_type = ?";
final String[] selectionArgs = { "1" };
final String sortOrder = "full_name";

final Cursor cur = getContentResolver().query(SEESMIC_FB_PEOPLE_URI,
        projection, selection, selectionArgs, sortOrder);

final String[] from = { "full_name" };
final int[] to = { android.R.id.text1 };
setListAdapter(new SimpleCursorAdapter(this,
            android.R.layout.simple_list_item_1, cur, from, to));
</code></pre>

<p>As it turned out, contacting a social media related company with such delicate
matter wasn't trivial. For purposes of feedback, they had a public forum,
which was obviously not the place to describe vulnerabilities in detail. On
their <a href="https://seesmic.com/about/">about site</a>, I found the e-mail address <em>ContactUs at Seesmic dot com</em>,
and sent them a mail right after the proof-of-concept worked. I waited for a
month, then tried contacting them on <a href="https://www.facebook.com/SeesmicPage">their Facebook page</a>, where they
replied 5 days later, and said to <a href="https://seesmic.zendesk.com/tickets/new/">open a ticket in their Zendesk system</a>.</p>

<p>After I did so, they replied that they'll “let [their] Dev Team know about this
as [they]'ll review the issue”. I waited for another two months, and then one
day, I just opened the notification on my Android phone that a new version of
Seesmic was available, that contains “security improvements”. Since they
haven't released an update through the Play Store since summer, I immediately
tried CoProLeak and I was pleased to found that both functions of the
proof-of-concept application crashed with permission problems.</p>

<p><img src="http://techblog.vsza.hu/images/cpl-update.png" alt="Updated version notification and crashing proof-of-concept" title="" /></p>

<p>To be sure, I checked the logs with ADB, and it's pretty clear that the
application gets terminated because of (unhandled) permission denial.</p>

<pre><code>I/ActivityManager(  246): START {cmp=hu.sil&#x65;ntsignal.android.coproleak/.SeesmicAccountsList u=0} from pid 8388
W/ActivityManager(  246): Permission denied: checkComponentPermission() owningUid=10073
W/ActivityManager(  246): Permission Denial: opening provider com.seesmic.data.DbProvider from ProcessRecord{422e6d78 8388:hu.sil&#x65;ntsignal.android.coproleak/u0a46} (pid=8388, uid=10046) that is not exported from uid 10073
D/AndroidRuntime( 8388): Shutting down VM
W/dalvikvm( 8388): threadid=1: thread exiting with uncaught exception (group=0x414dc300)
E/AndroidRuntime( 8388): FATAL EXCEPTION: main
E/AndroidRuntime( 8388): java.lang.RuntimeException: Unable to start activity ComponentInfo{hu.sil&#x65;ntsignal.android.coproleak/hu.sil&#x65;ntsignal.android.coproleak.SeesmicAccountsList}: java.lang.SecurityException: Permission Denial: opening provider com.seesmic.data.DbProvider from ProcessRecord{422e6d78 8388:hu.sil&#x65;ntsignal.android.coproleak/u0a46} (pid=8388, uid=10046) that is not exported from uid 10073
E/AndroidRuntime( 8388): Caused by: java.lang.SecurityException: Permission Denial: opening provider com.seesmic.data.DbProvider from ProcessRecord{422e6d78 8388:hu.sil&#x65;ntsignal.android.coproleak/u0a46} (pid=8388, uid=10046) that is not exported from uid 10073
E/AndroidRuntime( 8388):        at android.os.Parcel.readException(Parcel.java:1425)
E/AndroidRuntime( 8388):        at android.os.Parcel.readException(Parcel.java:1379)
E/AndroidRuntime( 8388):        at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:2354)
E/AndroidRuntime( 8388):        at android.app.ActivityThread.acquireProvider(ActivityThread.java:4219)
E/AndroidRuntime( 8388):        at android.app.ContextImpl&#x24;ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:1703)
E/AndroidRuntime( 8388):        at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1099)
E/AndroidRuntime( 8388):        at android.content.ContentResolver.query(ContentResolver.java:354)
E/AndroidRuntime( 8388):        at android.content.ContentResolver.query(ContentResolver.java:313)
E/AndroidRuntime( 8388):        at hu.sil&#x65;ntsignal.android.coproleak.SeesmicAccountsList.onCreate(SeesmicAccountsList.java:38)
E/AndroidRuntime( 8388):        at android.app.Activity.performCreate(Activity.java:5008)
E/AndroidRuntime( 8388):        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
E/AndroidRuntime( 8388):        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
E/AndroidRuntime( 8388):        ... 11 more
W/ActivityManager(  246):   Force finishing activity hu.sil&#x65;ntsignal.android.coproleak/.SeesmicAccountsList
W/ActivityManager(  246):   Force finishing activity hu.sil&#x65;ntsignal.android.coproleak/.Main
</code></pre>
]]></content>
	</entry>
	<entry>
		<title>Leaking data using DIY USB HID device</title>
		<link rel="alternate" type="text/html" href="http://techblog.vsza.hu/posts/Leaking_data_using_DIY_USB_HID_device.html"/>
		<updated>2012-10-29T19:09:01+01:00</updated>
      <id>http://techblog.vsza.hu/posts/Leaking_data_using_DIY_USB_HID_device.html</id>
      <author><name>dnet</name></author>
		<category term="POSTCATEGORY" scheme="http://www.sixapart.com/ns/types#category"/>
		<content type="html" xml:lang="en" xml:base="http://techblog.vsza.hu"><![CDATA[
      <p>Years ago, there was a competition, where contestants had to extract date out
of a system that was protected by a state-of-the-art anti-leaking solution.
Such chall&#x65;nges are based on the fact that private information should be
available for use on a protected computer, but it must stay within the physical
boundaries of the system. Obvious methods like networking and removable storage
devices are usually covered by these mechanisms, but as with DRM, it's
difficult – if not impossible – to think of every possibility. For example,
in the aforementioned chall&#x65;nge, some guys used the audio output to get a
file off the box – and when I heard about the <a href="http://littlewire.cc/">Little Wire</a> project, I
started thinking about a new vector.</p>

<p>The requirements for my solution was to be able to extract data out of a</p>

<ul>
<li>Windows 7 box</li>
<li>with no additional software installed</li>
<li>logged in as non-administrative account</li>
<li>that only allows a display, a keyboard and a mouse to be connected.</li>
</ul>

<p>My idea was to use a USB HID device, since these can be connected to such
system without additional drivers or special privileges. I've already built
such a device for <a href="http://hsbp.org/fuji">interfacing JTAG</a> using an Arduino clone and <a href="http://www.obdev.at/products/vusb/">V-USB</a>,
so I could reuse both hardware and experience, but avoid using an external
programmer. The V-USB library made it possible for me to create an USB device
without buying purpose-built hardware, by bit-banging the USB protocol with
the general-purpose input and output pins of an AVR ATmega328 microcontroller.
When used correctly, the AVR device shows up as a regular keyboard in the
Windows 7 devices dialog.</p>

<p><img src="http://techblog.vsza.hu/images/usbpwn-win7.png" alt="USBpwn in the Windows 7 devices dialog" title="" /></p>

<p>Keyboard was a logical choice for data extraction, since it was the only part
of the HID specification that has a three bit wide output channel that's
controllable without drivers and/or administrative privileges: the NUM, CAPS
and SCROLL lock status LEDs. I've crafted a simple protocol that used NUM and
CAPS as two data bits and SCROLL as a clock signal. When the SCROLL LED was
on, the other two LEDs could be sampled for data. The newline (that could be
achieved by “pressing” the Enter/Return key, since we're already “keyboards”)
was the acknowledgement signal, making the protocol fully synchronous.
For example, the bits <code>1101</code> could be sent in the following way:</p>

<pre><code>            __________________________________
   NUM ____/
                               _______________
  CAPS _______________________/
                ______            ______
SCROLL ________/      \__________/      \_____

                  01                11
</code></pre>

<p>On the Windows host, an extractor agent was needed, that performed the transfer
using the following code snippet:</p>

<pre><code class="cpp">set_lock(NUM,  (frame &amp; 0x01) == 0x01);
set_lock(CAPS, (frame &amp; 0x02) == 0x02);
set_lock(SCROLL, 1);
getchar();
toggle_key(SCROLL);
</code></pre>

<p>Bits were sent from LSB to MSB, n bytes were sent from 0 to n-1, stored at the
nth position in the EEPROM. I tried using an SD card to store the data received,
but it <a href="http://electronics.stackexchange.com/questions/43401/how-can-v-usb-screw-up-the-built-in-spi-of-an-atmega328p">conflicted with the V-USB library</a>, so I had to use the built-in
EEPROM – the MCU I used was the ATmega328, which had 1 kbyte of it, which
limited the size of the largest file that could be extracted.</p>

<p>Of course, the aforementoned agent had to be placed on the Windows box before
transmitting file contents. The problem was similar to using dumb bindshell
shellcodes to upload binary content, and most people solved it by using
<code>debug.com</code>. Although it's there on most versions of Windows, it has its
limitations: the output file can be 64 kilobytes at maximum, and it requires
data to be typed using hexadecimal characters, which requires at least two
characters per byte.</p>

<p>In contrast, base64 requires only 4 characters per 3 bytes (33% overhead
instead of 100%), and there's a way to do it on recent Windows systems using
a good old friend of ours: Visual Basic. I created a <a href="https://github.com/dnet/base64-vbs.py/blob/master/base64.vbs">simple VBS skeleton</a>
that decodes base64 strings and saves the binary output to a file, and
another <a href="https://github.com/dnet/base64-vbs.py/blob/master/b64vbs.py">simple Python script</a> that fills the skeleton base64-encoded
content, and also compresses it (like JS and CSS minifiers on the web).
The output of the minified version is something like the one below.</p>

<pre><code class="vbscript">Dim a,b
Set a=CreateObject("Msxml2.DOMDocument.3.0").CreateElement("base64")
a.dataType="bin.base64"
a.text="TVpQAAIAAAAEAA8A//8AALgAAAAAAAAAQAAaAAAAAAAAAAAAAAAAAA..."
Set b=CreateObject("ADODB.Stream")
b.Type=1
b.Open
b.Write a.nodeTypedValue
b.SaveToFile "foo.exe",2
</code></pre>

<p>The result is such a solution that makes it possible to carry a Windows agent
(a simple <code>exe</code> program) that can be typed in from the Flash memory of the AVR,
which, when executed, can leak any file using the LEDs. I successfully
demonstrated these abilities at <a href="https://hacktivity.com/en/hacktivity-2012/programs/usb-universal-security-bug1/">Hacktivity 2012</a>, my slideshow is available
for download <a href="http://sil&#x65;ntsignal.hu/docs/S2_VSzA_Hacktivity2012.pdf">on the Sil&#x65;nt Signal homepage</a>, videos should be posted soon.
The hardware itself can be seen below, the self-made USB interface shield is
the same as <a href="http://vusb.wikidot.com/hardware#toc3">the one in the V-USB wiki hardware page</a>.</p>

<p><img src="http://techblog.vsza.hu/images/usbpwn-parts.jpg" alt="USBpwn hardware" title="" /></p>

<p>The hardware itself is bulky, and I won't try to make it smaller and faster
any time soon, since I've already heard enough people considering it
weaponized. Anyway, the proof-of-concept hardware and software solution</p>

<ul>
<li>can type in 13 characters per seconds from the flash memory of the AVR,</li>
<li>which results in 10 bytes per seconds (considering base64 encoding),</li>
<li>and after deploying the agent, it can read LEDs with 1.24 effective bytes per second.</li>
</ul>

<p>All the code is available in my GitHub repositories:</p>

<ul>
<li>the <a href="https://github.com/dnet/usbpwn-device">code running on the device</a>, written in C, released under OBDEV license,</li>
<li>the <a href="https://github.com/dnet/usbpwn-host">Windows agent</a>, also written in C, but released under MIT license, and</li>
<li>the <a href="https://github.com/dnet/base64-vbs.py">base64 VBS encoder</a>, written in Python, also released under MIT license.</li>
</ul>
]]></content>
	</entry>
</feed>
