Writing Code for the ATtiny10

I previously wrote about the hardware aspects of getting your code into an ATtiny10 some 7 years ago (wow that was realllyy a long time ago!).

Now, avrdude is at version 6.3 and the TPI bitbang implementation has already been integrated in. The upstream avr-gcc (and avr-libc) also have proper support for ATtiny10s now. These software components are bundled with most distributions, including the Arduino IDE, making it easily accessible for anyone. Previously a fully integrated and working toolchain only came from Atmel and it was behind a registration page.

The price of the ATtiny10 has also dropped by a lot. When I first bought this microcontroller in 2010, element14 carried it for $1.85 in single quantities. Now, they are only $0.56 each.

I thought I’d write up a short post about writing and compiling code for it.

ATtiny10 on a prototyping board

Continue reading


Framework for Writing Flexible Bruteforcers

When writing a bruteforcer, it’s easiest to think of it as mapping some kind of output to a monotonically-increasing number.

Like for one of the solved PlaidCTF question, the answer string was composed from the eight letters “plaidctf”, which conveniently is a power of 2, meaning each output character can be represented with 3 bits. To write a bruteforcer for a string composed of these characters, you might imagine generating a 3-bit number (i.e. from 0 to 7) then mapping it to the character set for one output character, or a 30-bit number if the output string was 10 characters. Unsurprisingly, this was exactly what I did for my solver script. The output string was generated from a BitVector of 171 * 3 bits.

But what if the output was composed of several different pieces that cannot be represented uniformly as a set of bits?

One solution might be to emulate such a behaviour using an array of integers, like how I modified my solver script in version 2 to handle a character set of arbitrary length.

In this post, I will walk-through writing a basic, but flexible, bruteforcer with accompanying code snippets in Go.

Keeping State

Continuing on the CTF puzzle, the BitVector was replaced with an array of Ints. Each Int will represent one character of the output string. We can thus represent the state like so (for simplicity, let’s limit the output string to 2 characters):

type state struct {
    digit [2]int

In order to increment each digit, we can write a function that increments state.digit until a certain number, then resets it to zero.

To make it generic, we will write a function that returns another function that manipulates a digit position, so we don’t have to copy & paste the code for each digit position:

// returns a function that manipulates the digit at given pos
func digitManipulator(pos int) func(*state) bool {
    return func(s *state) bool {
        if s.digit[pos] == MAX_NUMBER {
            s.digit[pos] = 0
            return true
        return false

We will talk more about the boolean return value later.

Continue reading

LabyREnth 2017 Write-up: “EzDroid”

Mobile track #1 – EzDroid

Provided is an Android app package EzDroid.apk.

I typically use an Android emulator for testing, it’s free and easy to install on all major platforms, so it’s pretty much a no brainer.

After installation, it looks like it maanges to start but exits shortly after, for some unknown reason. Looks like it is time to inspect the code.

I like looking at high-level languages, so let’s start with that first.

My preferred method is to use dex2jar for decompilation, then using JD-GUI to explore the produced JAR file. You should have something that looks like the following screen:

JD-GUI app, exploring the decompiled JAR file

There’s only 2 packages, one of which is the Support Library, so the package with app code is likely com.labyrenth.manykeys.manykeys, with 4 classes inside:

  • BuildConfig
  • EZMain
  • R
  • onoes

BuildConfig and R are compile-time Android-generated classes, so ignore those.

EZMain looks to be the main Activity class. If you are unfamiliar with Android, that’s where the action happens.

Continue reading

Making USBasp Chinese Clones Usable

I don’t have any dedicated programmers. I have been programming Atmel chips using the USB-to-serial bitbang method.

Recently, I thought I’d get one because doing a re-programming cycle is taking quite a bit of time (a disadvantage of serial port bitbanging).

A popular one on Aliexpress seems to be this “USB ISP” one, so I bought one. I chose this one because it has a nice aluminium case, and a pinout diagram imprinted on the case, which is handy. After having so many one-off projects with bare PCBs collecting dust, I now appreciate the importance of having projects in their own box or case.

USB ISP programmer with aluminium case

While it has “USBasp” in the item name, it turns out that this was not a USBasp device, and getting it to work like one takes some effort.

It identifies itself as a zhifengsoft HID device when I plug it into Linux:

usb 3-1: new low-speed USB device number 3 using ohci-platform
usb 3-1: New USB device found, idVendor=03eb, idProduct=c8b4
usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
usb 3-1: Product: USBHID
usb 3-1: Manufacturer: zhifengsoft

avrdude does not recognize the device, even after creating an entry with the corresponding vendor/product ID. This particular device was designed to work with their Windows-based UI called ProgISP and will not work with avrdude.

And apparently you can’t just take the USBasp firmware and flash it into this device, because the circuit is somewhat different.

After some research based on the PCB markings, I found these sites that talk about them:


Disassembling the device is simple. While grabbing the side of the case, firmly push the USB connector inwards and the board should slide out the other end. You can then gently pull the board out by the IDC connector.

Disassembly how-to photo

The programmer seems to be based off of the popular USBasp programmer, but modified somewhat (to what end I’m not sure). It lacks some features offered by other USBasp programmers, like the ability to control the target’s clock, or to use 3.3V for certain targets. But at $2 with a nice aluminium case, what more can you ask for?

It’s powered by an ATmega88 (I read that older versions were based on ATmega8). The markings on the board indicate that this is a MX-USBISP-V4.00. You can ignore tHe date because it was never updated; the older V3.02 also has the same date. While the GreenPhotons blog was talking about V3.00, I have verified that this version suffers from the same issue.

USBISP programmer, with aluminium case


Note that there are provisions on the PCB to add a voltage regulator, and the PCB link marked “C” can be cut to separate USB power from the rest of the system. Link “D” can be cut if you wish to disable target power. However, none of these options were used.

The crucial difference with this clone is that the USB D- pin is additionally connected to PD3, shown here highlighted in blue:

Clone difference in schematic view

However, in the USBasp’s main() function, PORTD‘s data direction register was initialized like so:

  /* all outputs except PD2 = INT0 */
  DDRD = ~(1 << 2);

This causes the USB D- line to be actively driven from PD3, thereby impeding communication to/from the USB host.

The rest of this post will talk about (1) correcting this problem in USBasp, and (2) uploading the firmware into your zhifengsoft programmer.

Continue reading

Replacing a Linux RAID Drive

NAS drives

I have been running a software RAID array at home for some time now. It’s a single network storage where I consolidate all my files. I manage this array manually using the mdadm command. Some people choose to buy a NAS storage box which hides all of the implementation details behind a nice Web GUI, but it’s essentially the same thing under the hood.

It operates with 4 drives using Linux software RAID 5, which means it can tolerate a single drive failure, but failures don’t always take out an entire drive. They usually manifest as bad sectors in a drive. As an illustration, the RAID 5 array below can still operate properly (meaning no data loss, yet) with bad sectors on two of its drives:

RAID 5 array with damaged blocks

As long as the other drives in the array doesn’t develop bad sectors in the same stripe, the data can still be reconstructed from the remaining good blocks. This means that you can somewhat leave the drive as it is for a period without replacement, but of course you are taking a risk.

I thought I’d share my experiences with drive replacements thus far.

Detecting Drive Problems

Most Linux distributions provide the raid-check script for periodic RAID scrubbing. This is basically a background cron job that tells the kernel to start checking the RAID array. For RHEL/CentOS systems, this should occur every weekend.

During this scrubbing process, all drives within the array are read and their parity blocks are computed, to ensure that everything tallies.

It is during this verification process that sometimes causes hard drive errors to show up. Typically when a drive encounters a problem during read, the hardware returns an error, which will then be logged by Linux. They can look like these:

ata3.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
ata3.00: irq_stat 0x40000001
ata3.00: failed command: READ DMA EXT
ata3.00: cmd 25/00:00:d8:10:27/00:02:05:00:00/e0 tag 8 dma 262144 in
         res 51/40:1f:b8:12:27/00:00:05:00:00/e0 Emask 0x9 (media error)
ata3.00: status: { DRDY ERR }
ata3.00: error: { UNC }
ata3.00: configured for UDMA/133
ata3: EH complete
 . (repeats)
sd 2:0:0:0: [sdc]  Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
sd 2:0:0:0: [sdc]  Sense Key : Medium Error [current] [descriptor]
Descriptor sense data with sense descriptors (in hex):
        72 03 11 04 00 00 00 0c 00 0a 80 00 00 00 00 00
        05 27 12 b8
sd 2:0:0:0: [sdc]  Add. Sense: Unrecovered read error - auto reallocate failed
sd 2:0:0:0: [sdc] CDB: Read(10): 28 00 05 27 10 d8 00 02 00 00
end_request: I/O error, dev sdc, sector 86446776

Continue reading