Managing a code audit
At work, I had the pleasure to manage a code audit. This means we contracted Trail of Bits to audit our code! 
 Read more about it here . 
 If down, read here .
Recent content on Max Ammann
At work, I had the pleasure to manage a code audit. This means we contracted Trail of Bits to audit our code! 
 Read more about it here . 
 If down, read here .
These are notes from one evening of checking how the Midea Portasplit communicates and how its electronics are structured. 
 Existing work on smart home integration 
 The following repositories already reverse-engineered the protocol between a Midea Portasplit and some Chinese cloud services.
Just published a new blog post about some vulnerabilities I discoverd in some cloud CAD application. It’s published at zoo.dev’s blog ( archive ). It’s also available on GitHub .
At work I had some fun taking apart a random startup’s CAD product Zoo blog . 
 If down, read here .

 A machine-translated German version is available below. 
 
 Late one night in February I was planning some weekend trips around Freiburg. The Badische Zeitung has an excellent app called “BZ-Lieblingsplätze”.
It shows lovely places nearby that are worth visiting.
The app does not have a web view that I knew of, so I wanted to check which API was running in the…
I’m a technical guy and by no means an expert on compliance. However, in 2025 I learned the benefits and the absurdities of GRC in a company. 
 My learnings are documented on the Zoo blog .
The Kingrinder K6 is a popular manual coffee grinder known for its consistent grind quality and durability. However, after only 6 months of use with the Ross Droplet Technique (RDT), my K6’s bearings failed prematurely due to rust damage. The small amount of water I was adding to coffee beans (0.5-1g) to reduce static created moisture that found its way to the internal bearings, causing…

 I got myself a Dreame vacuum robot with the goal of – cleaning. Yes, I did not have the goal originally to root my vacuum.
However, in case I ever want to sideload software onto the robot, I picked one that is reliably rootable.
The Dreame X40 looked decent, and Dennis Giese did awesome work on getting root access to it back in 2021 .
This turned out to be a good decision…
The Tür an Tür Digitalfabrik and I are publicly disclosing several security and privacy issues in the iOS and Android NRW Ehrenamtskarten-App . We found 1 high-severity and 1 informational security issue, as well as 5 additional privacy and legal issues.
This post was release on the Trail of Bits blog .
This post was release on the Trail of Bits blog .
This post was release on the Trail of Bits blog .
This post was release on the Trail of Bits blog .
This post was release on the Trail of Bits blog .
This post was release on the Trail of Bits blog .
Generating QR codes is supported by various high quality libraries. Generating PDF using JavaScript in browsers is also very well-supported nowadays.
In this post I want to present a method which has the following features:
TL;DR: Just tell me what to use! 
 Mounting file systems over a network can be very helpful. For example if you have a NAS (Network Attached Storage) and want to make the remote files available locally. That way applications running on a laptop can transparently access remote files.
There is no need for application level support. Files are made available locally that any program in the…
RFC 7464 defines a text file format based on the popular JSON format. Its intention is to write JSON texts as a sequence delimited by some character. This can be especially helpful for structured logging using JSON. If you want to write JSON objects instead of plain text with each log entry, then you need some streaming file format.
This means instead of overwriting a log file over and over…
Stencil testing refers to a technique in computer graphics programming which allows conditional processing of fragments. Stencil testing is closely related to depth testing which is used to determine which fragment precedence based on its depth within the scene.
In fact both tests are handled through the very same interface in WebGPU. The tests are handled through the Depth/Stencil State .
Background 
 With Android 11 the method for connecting to Android phones via ADB over the network has changed . Unfortunately, the new method requires to know the port on which the ADB service on the phone is running.
For our tlspuffin fuzzer we use Rust to implement the testing harness. The harness is statically linked to OpenSSL via the openssl-sys and
 openssl-src crates, where the latter just provides a Rust Build Script . openssl-sys runs the script, then looks at the build artifacts and statically links against them.
While trying to reproduce the implementation bug CVE-2021-3449 , I had to implement secure renegotiation as specified in RFC 5746 . Often it is unclear which RFC is responsible for specific protocol behavior. With the abundance of extensions, messages and protocol versions it is not trivial to find and also verify whether you found the correct specification.
TLS, like most cryptographic protocols, depend on random numbers to generate keying material. These numbers should come from a trusted and truly random source.
While this is necessary for production use, for testing purposes it is beneficial to use a pseudorandom number generator (PRNG). By seeding the generator with a static and not-random number, each execution of the protocol yields the…
Traditionally, fuzzing mutates bits and bytes. That means that the semantics of the protocol are not directly used to mutate the fuzzing input. Symbolic-model Guided Fuzzers fuzz on a more abstract level. It uses a symbolic model to create inputs. Therefore, there are two main approaches bit-level fuzzing and model-guided fuzzing (also called generation-based fuzzing) 1 . This is also called…
TLS is a beast of a protocol with at least 50 extensions and over 20 years of history. This indicates that implementing can be challenging and that it is important to take a close look at its security.
TLS drives the web of today. The web can not exist without it anymore. Not only that secrecy and authentication is a must-have today, it is also required by specifications like getUserMedia for…
Research in Fuzzing has gained a lot of traction in the last decade. A lot of open source fuzzers have been implemented and are available on Github. Everyone who already developed any application knows the pain of naming things. It is very difficult to have a common understanding of the terms used in a project. A standard software engineering practice is to use a glossary. This usually only scaled…
Sometimes you want to have a ScrollView which scrolls from right to left or from bottom. This can be handy when you use calendar views which often to from present to past.
Keeping a secret like GPG keys safe is not a trivial task. It gets even more complicated if you want to backup it and have access in the more distant future. Having your key on a HSM has the goal of keeping it secret. Keeping a secret safe means that it is not easy to lose your key.
Link to the project: github.com/maxammann/ndove 
 Sometimes you want to expose a port running on localhost to the internet. This can be challenging because of multiple reasons: 
 
 Your internet provider does not provide you with a unique IPv4 address 
 There is a firewall between you and the internet through which you can not poke holes 
 You do not want to modify your system…
This probably happens to every analog photographer sooner or later. You finished developing your black and white film and you don’t remember in which container the used developer and in which the fixer is. You want to reuse the fixer but you don’t want to put your film into used developer in the next session.
If is possible to flash a new firmware from Linux or BSD on an APU embedded system. If the system no longer boots because the board war bricked during a firmware upgrade then you have to flash the flash memory directly over SPI . In my case I had to flash an MX25L1606E on an APU1D .
It is very convenient to switch between different monitor layouts when using a laptop with multiple external monitors.
A very good guide can be found on GitHub Gist by seanf .
This post should contain the necessary information for getting it to work on a ThinkPad Thunderbolt Dock.
A docker setup can be very helpful when trying to separate services if they are not packaged otherwise.
We don’t only want to separate configuration in this post, but also the network configuration.
VueScan for the Nikon LS-2000 offers a future proof way of using old scanners over the legacy SCSI standard. The not that small Small Computer System Interface is not easy to setup in 2020. Three things are required in order to use it:
We are going to visualize the timestamps of messages in the Telegram database. This also includes encrypted chats as we analyze the SQLite database of the app. 
 Obtaining the database 
 We pull the database of Telegram using the ADB tool. You can read here how this tool works and how to set it up. Make sure your phone is rooted and you set Root access to ADB only . Then you can restart…
The documentation about setting up Tiny Core Linux to flash a new coreboot version on APU boards is quite outdated. If you are interested in flashing the APU using a Raspberry PI then head over to this post .
This guide is tested on Armbian 20.8 
 The default Armbian images do not offer an encrypted root partition. Unfortunately it is requied to build the image yourself inorder to use LUKS on your root partition.
The firmware and drivers for the Fingerprint Reader for Linux are finally ready as promised a few months ago . I’m not sure whether this was an accomplishment of Lenovo of the open-source community ¯_(ツ)_/¯.
I suggest to wait until the firmware reached a stable state. But if you are feeling adventurous you can get it working right now!
I recently got my hands on a Nikon Coolscan 2000 (LS-2000) scanner.
The drivers and the scanning software VueScan is distributed by Hamrick Software . The original software Nikon Scan is discontinued. There maybe are ways to get it working on Windows 10 but I did not further investigate it after the first try.
I received a free Yubikey from an untrusted source on the CCCamp 2019 .
Therefore I looked for a way to verify its authenticity. The device appeared physically to be an original and not tampered with.
A check whether the key was manufactured by Yubico seems like a sufficient way to make sure that the security key is an original.
I had problem to connect a InfluxDB from the pfSense because of a invalid certificate chain. The main problem here is that if you are configuring Telegraf with the pfSense UI then you are not using the system certificate chain (on FreeBSD that is /etc/ssl/cert.pem ). In fact the generated Telegraf config is using: /usr/local/etc/telegraf.ca 
The pfSense is generating that chain from your…
If you previously converted a raw image using qemu-img convert to a qcow2 image you maybe want to mount it to retrieve and modify data: 
 1 modprobe nbd max_part = 8 
 2 qemu-nbd --connect = /dev/nbd0 db1_old.qcow2
 Now you can mount partitions in the image using:
Disclaimer: This is probably not a step by step guide because there are a lot of dependencies involved. I tried to cover all the important aspects of cross-compiling ROS or actually any other software for Raspbian and ARMv6. This is at least a proof-of-concept that compiling ROS Melodic works for ARMv6.
This post represents a slow way to compile ROS. In a new post I show how to crosscompile ROS. 
 This post should guide you through the process of compiling ROS on a virtualized Raspberry PI Zero.
Sometimes it makes sense to connect to the PI Zero by using the g_ether kernel module. This
connection is way more reliable than the WiFi connection in certain environments. 
 The setup is quite simple. dnsmasq will provide a local DHCP and DNS server.
Writing a slack bot which pushes content to a workspace is quite simple and fast to do.
So if there is an updating piece of information in the internet from which your teams needs regular updates
this is an easy. In my case this is the weekly food plan.
I created a updated guide here ! 
 Sometimes you want to expose a port running on localhost to the internet. The use of NAT with IPv4
or firewalls make it difficult to expose a port. Sometimes you also lack the permission to do so. So
maybe your IT will not like this ;)
At the company I work at we sometimes throw a party to celebrate the day!
Unfortunately we have very different tastes of music. So solve that I setup a Raspberry PI so
everyone can vote for their music. What could go wrong? :P
I did the orw challange on pwnable.tw yesterday. It is very streight forward.
You just have to send some x86 shellcode to stdin and the orw binary will execute it. 
 But I spend a few hours with getting this to work with gdb as the instructions in gdb were quite
weird.
In case you migrated from Jira Cloud to the self-hosted version your server id probably got
corrupted. You can revert this by searching your Jira logs for the ID and manually change it in the
database.