---
description: Universal Asynchronous Receiver / Transmitter
---

# UART

## Baud rates

| Bauds         | Bits/s            | Bit duration   |
| ------------- | ----------------- | -------------- |
| 1200 Bd       | 1200 bits/s       | 833.333 μs     |
| 1800 Bd       | 1800 bits/s       | 555.556 μs     |
| 2400 Bd       | 2400 bits/s       | 416.667 μs     |
| 4800 Bd       | 4800 bits/s       | 208.333 μs     |
| **9600 Bd**   | **9600 bits/s**   | **104.167 μs** |
| 19200 Bd      | 19200 bits/s      | 52.083 μs      |
| 28800 Bd      | 28800 bits/s      | 34.722 μs      |
| 38400 Bd      | 38400 bits/s      | 26.042 μs      |
| 57600 Bd      | 57600 bits/s      | 17.361 μs      |
| 76800 Bd      | 76800 bits/s      | 13.021 μs      |
| **115200 Bd** | **115200 bits/s** | **8.681 μs**   |
| 230400 Bd     | 230400 bits/s     | 4.340 μs       |
| 460800 Bd     | 460800 bits/s     | 2.170 μs       |

### **Calculate Baud**&#x20;

<figure><img src="https://2314265932-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLZ9hPT4FtAP57VrTApYv%2Fuploads%2FaCegRzRO3BPdLAhqmiMz%2Fimage.png?alt=media&#x26;token=3274d9f8-b438-4748-aca2-2ae301daac47" alt=""><figcaption></figcaption></figure>

Hover the mouse over the two fastest bits and we find the time between each bit, in the example output it's 8.7 μs (microseconds) per bit. Usually modern software will calculate the baud rate for us, but if that's not the case this is how you do that.&#x20;

To calculate correct baud we want to find bits per second (not μs per bit), flip the problem.\
1 bit per 8.7 μs, or 1 bit / 8.7 \* 10^-6 s.

$$
\frac{1}{8.7 * 10^{-6}} ≈ 0.115 * 10^6 = 115000 bits / second
$$

The baud rate is most likely **115200**.

## Identify unknown pins

**Ground**

* You can easily identify ground by looking on the PCB. A pin **without** a darker circle around it means it's not connected, it is ground.
* Do a continuity test with a multimeter

**Power**

* Do a voltmeter test with a multimeter
  * Constant value, non-changing

**Data**

* Analyze **data pins** with a logic analyzer
* Analyze **analog pins** with a oscilloscope

## Logic analyzer

Bitmagic Logic Analyzer - use `PulseView`, the graphical frontend to the Sigrok logic analyzer suite of tools. Install it with `sudo apt install sigrok`

Assign **protocol analyzer** accordingly in the top right, yellow and green button. Press the protocol, UART in this example, to configure RX/TX lines, Baud rate and Data format.&#x20;

<figure><img src="https://2314265932-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLZ9hPT4FtAP57VrTApYv%2Fuploads%2FRUCq1CKJiHXgfaDwNQNQ%2Fimage.png?alt=media&#x26;token=28f2d725-d821-45dc-9bbb-392e6f61a039" alt=""><figcaption><p>UART data from a booting router. Initial U-boot process.</p></figcaption></figure>

## Bypass Login / Escalate Privileges

### Boot loader bypass

* Connect to the device using `screen /dev/ttyUSB0 115200`, `putty` or `minicom`
* Spam **`e`** or other assigned key to enter _edit bootloader mode_
* Edit boot image from `ro` to `rw`
* Add `\ init=/bin/bash` at the end of the boot string
* Save and exit, if it works you might get a root shell

### Recovery mode

* Connect to the device and enter recovery mode
* Type `mount -o remount,rw /` to get a shell
* Change password of root user: `passwd root Passw0rd!`

### U-BOOT boot argument

* Connect to the device and enter U-BOOT
* Set the boot argument environment variable by typing the following line: \
  `setenv bootargs console=ttyS0,115200 rootfstype=squashfs,jffs2 1`
* From the bootlog, identify the address at which the kernel is loaded from

<figure><img src="https://2314265932-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLZ9hPT4FtAP57VrTApYv%2Fuploads%2FTjlq8LAguVVXHzq7XTow%2Fimage.png?alt=media&#x26;token=d0851526-83fe-4ab6-bd2c-36f6e590aeef" alt="" width="375"><figcaption><p>Kernel address <strong>bc050000</strong></p></figcaption></figure>

* Boot the kernel using `bootm <kernel address>`
* Check the command line the kernel booted with using `cat /proc/cmdline`, usually works on older systems

### Failsafe mode

Some systems have a failsafe built-in to give the user an opportunity to interrupt the boot process. Easiest way to identify if a system has a built-in is by looking for _"failsafe"_ in the boot logs.&#x20;

In this example we find the failsafe script located at `/lib/preinit/30_failsafe_wait` on the target system. At the very end of the script we can see that the user is prompted to press the non-presentational ascii character � - how do we do that?&#x20;

We can accomplish this in several ways:

1. Copy + Paste, doesn't have to be more complicated then that
2. Write a program to mirror all data received&#x20;
3. Brute force

```bash
#!/bin/sh
# Copyright (C) 2006-2010 OpenWrt.org
# Copyright (C) 2010 Vertical Communications

[ ... snip ... ]

failsafe_wait() {
	FAILSAFE=
	grep -q 'failsafe=' /proc/cmdline && FAILSAFE=true && export FAILSAFE
	if [ "$FAILSAFE" != "true" ]; then
		pi_failsafe_net_message=true
		preinit_net_echo "Please press button now to enter failsafe"
		pi_failsafe_net_message=false
		fs_wait_for_key � 'to enter failsafe mode' $fs_failsafe_wait_timeout && FAILSAFE=true
		[ -f "/tmp/failsafe_button" ] && FAILSAFE=true && echo "- failsafe button "`cat /tmp/failsafe_button`" was pressed -"
		[ "$FAILSAFE" = "true" ] && export FAILSAFE && touch /tmp/failsafe
	fi
}

boot_hook_add preinit_main failsafe_wait
```
