applied security research
Wesley Neelen - 06 aug 2020

Hacking the traffic light of the future

Nowadays we are connecting everything we can think of to the internet. Usually to make our lives easier or more comfortable. Some of the new upcoming innovations are related to making our traffic smart with the goal to improve safety, comfort and the traffic flow. We dived into this technology to analyze the inner workings and identify potential security risks.

TLDR: watch our DEFCON talk on YouTube.

Recently we stumbled upon videos and information that got our attention. In the Netherlands, a project was launched to connect traffic lights to the internet. There were multiple initiatives to do so, started by different vendors in various cities. A use case would be to turn the lights green faster as a vehicle or cyclist approaches. Or allowing emergency vehicles instantly green if their blue light is turned on.

This is already done for decades using physical solutions on the road (“loops”) or by using short range communication (e.g. radio, microwave, infrared), but by incorporating the internet allows for a range of new opportunities and flexibility.  The overall idea of the innovation is to improve the accessibility, traffic flow, traffic safety and quality of life on the road network through real-time information exchange.

When we saw the project for the first time, instantly the question popped up: how does this work and what happens if this would be manipulated by a malicious actor?

After diving into the subject, it appeared that multiple traffic lights, located in the Netherlands, were already connected to the internet. These traffic lights recognize cyclists running a specific app on their phone. After detecting an approaching cyclist, the Traffic Light Controller on the intersection will decrease the time to green if possible.

There are different apps to cover several types of road users, for example:

  • Pedestrians
  • Cyclists
  • Trucks

We decided to continue our research with the cyclist apps because in that domain multiple apps were already publicly accessible to us.

Important note for the people outside of the Netherlands: in the Netherlands we do have a lot cycling infrastructure (about 35.000 kilometres) and about 22.8 million bicycles (which is more than citizens). This results in almost every intersection having traffic lights that are specificly placed for cyclists, which we’ve learned is not so common in other countries. If you’ve ever been to Amsterdam you know cyclists are everywhere: an (environmental) blessing in (chaotic) disguise.

Diving into the first application

One of the first “smart” traffic lights we found was clearly a proof of concept environment: there was even a separate indicative “Cyclist Seen” light showing whether a cyclist with active app was recognized by the system.

We started off by downloading and unpacking the Android application to get insights into the code of the application. The first interesting thing we saw in the application was code indicating that MQTT (Message Queueing Telemetry Transport) was being used. We discovered a server MQTT IP-address, username and password were hardcoded in the apps. So, we concluded MQTT was the protocol our app used to communicate with the traffic lights.

MQTT is a protocol that is widely used in the Internet-of-Things. In a nutshell: it is a lightweight protocol that consists of channels. The MQTT Clients can subscribe and/or publish to these channels, to read or share messages on the channels. For instance, a user of the app would share a message to a certain channel, which a traffic light would be subscribed to and triggered a workflow. We decided to do more in-depth investigation.

ETSI CAM objects

After a while we found the next rabbit-hole: Cooperative Awareness Message (CAM) objects, which were distributed using the MQTT protocol. CAM objects were introduced as part of a standard developed by ETSI to improve data exchange among technology providers.

The CAM standard was specifically developed to share traffic related information. A CAM-object contains a wide range of information about a vehicle, such as:

  • longitude / latitude (GPS location)
  • vehicle type
  • speed
  • lane position
  • siren / light bar status

The CAM objects were sent to the backend system over MQTT. This allows a vehicle to report, in a very detailed way, the properties of itself while passing the traffic light. The nature of CAM objects got us excited: we might be onto something here. The openness of CAM objects allowed us to manipulate a lot of properties describing a vehicle. If the backend system would accept our manipulated CAM objects, unexpected behaviour might occur.

Manipulating the CAM object station type

At this stage we wanted to manipulate the CAM objects and verify whether the backend performs any checks to prevent manipulation. Initially we were trying to connect to the MQTT channel ourselves and craft our own CAM object. However, CAM objects were very specific to the automotive sector and quite exotic (at least unknown to us). We ended up in a rabbit hole, trying to re-use code used by the original app for Android. Our goal was to figure out how to craft CAM objects and encode them in the correct way (protobuf and ASN encoding). It was a terrible experience ;-)…

So, after a while we decided to take another approach. We figured to use the functionality in the app itself to manipulate the CAM objects from there. A great tool to accomplish this is Frida, an incredible powerful tool to hook into (Android) applications. It basically allowed us to hook into the application at a specific point, modify some values and let the application handle the rest.

It was the first time for us using Frida, so it was a great learning adventure. The first attempt we performed was to hook into the application at the correct function in order to view the CAM objects that are being sent by the application. After some trial and error, we successfully hooked into the correct function to print out the current CAM object just before it was sent onto the MQTT channel:

CAM-object content snippet

value basicContainer ::= {
  stationType cyclist,
  referencePosition {
    latitude 51xx,
    longitude 50xx,
    positionConfidenceEllipse {
      semiMajorConfidence unavailable,
      semiMinorConfidence unavailable,
      semiMajorOrientation unavailable
    altitude {
      altitudeValue 4000,
      altitudeConfidence unavailable

We got insights into the CAM object contents. Is it possible to manipulate these contents? We succeeded in writing a script that calls a function that modifies the stationType (which contains the type of road user sending the message), to whatever value we want. For example, in the following CAM object we were able to modify the stationType from our CAM objects from ‘cyclist’ to ‘tram’ just before publishing the CAM object:

Modified the CAM-object

value basicContainer ::= {
  stationType tram,
  referencePosition {
    latitude 515623160,
    longitude 50737430,
    positionConfidenceEllipse {
      semiMajorConfidence unavailable,
      semiMinorConfidence unavailable,
      semiMajorOrientation unavailable
    altitude {
      altitudeValue 4000,
      altitudeConfidence unavailable

So, it was possible to modify the CAM object properties before sending it onto the MQTT channel.

Manipulating the CAM object GPS coordinates

The CAM object contains so many properties to manipulate. One of them which should be easier to debug are the GPS-coordinate properties. After all: the separate “cyclist seen” light we mentioned earlier, could be used to confirm whether the system responded to our input. We created a Frida script that modifies the following properties in the CAM object:

  • longitude
  • latitude
  • speed
  • bearing
  • accuracy
  • altitude

The script keeps on repeating two different GPS coordinates to fake a cyclist that is continuously passing the traffic light.

Two coordinates are required in order to look like a legit cyclist. The system will only respond if a cyclist is actually cycling. By running this script, the cyclist-seen-light turns on one-time, which proofs that the system sees our fake cyclist as a legit one. However, we wanted to trigger as much green as possible, to determine how far we could manipulate the light.

In order to do so, we created another script. During the research we discovered that every new MQTT connection was identified as a new cyclist. So, we created a new script: that just reconnects every time just before publishing our CAM object :-). We were hoping that the backend would see the following behaviour:

At the traffic light location, we could verify that the thing we expected occurred 🙂

By running both scripts, we emulate a continuously ongoing flow of cyclist passing the traffic light. This results in the actual traffic light controller to decrease the waiting time to green as much as it is allowed to. The behaviour that we trigger can be compared with a person pushing the physical button located at the traffic light all the time. The safety systems stay intact. So if the cyclists light turns green, the other lights (e.g. car lights), will be red and vice versa.

Diving into the second application

Later we found another project with traffic lights connected in 10 municipalities. An application was publicly available, so we were able to download and investigate it. This application was easier to investigate: we were able to configure an Android phone with the application proxying all of its request through our Burp proxy. This allowed us to see all the HTTPS connections that were sent to a cloud service.

We found out that the actual requests being sent by the application were quite simple. Information was sent to the cloud service using a POST-request. The POST-request contained data similar to this:

POST-request example


As seen in above POST data, the application sends information such as speed, heading and GPS-coordinates to the cloud server. After debugging at a actual connected traffic light, we discovered the following:

  • Just one HTTP request was enough to influence the traffic light;
  • No authentication was required;
  • No way to distinguish different cyclists from each other was available (a unique identifier or something like that).

We were able to convert our findings in an exploit, a Python scripts that sends one POST request to the cloud service. By running the script, the following behaviour occurs at the traffic light:

  • if there is other traffic at the intersection: it decreases time to green of the cyclists light
  • if there is no traffic at the intersection: it instantly turns green

In order to show above situations, we recorded two demo’s:


We found something interesting in both implementations. Both platforms are not really able to distinguish the cyclists from each other. One application is seeing every MQTT connection as a new cyclist, the other one is seeing every new HTTP connection as a new cyclist.

That is an interesting fact: this allows us to imitate a lot of cyclist at once. Imagine: just request all the cycling traffic lights in a city to turn green continuously in a loop. That would result in the cyclist light turning green as much as the local traffic light system / configuration allows it to. Whenever the cyclist light is turned green, the other traffic will get a red light. This will be quite annoying for the other road users.

In order to show how this could look like while attacking many traffic lights in a city, we created the following fictional visualization:

Luckily that’s the current impact: annoying. Two lights will never turn green simultaneously. The built-in security system prevents this to happen. On the other hand we can influence the traffic flow (one of the goals of smart traffic) in a negative way, letting a lot of people wait for nothing. Or let them stop all the time for no reason. And by talking to people involved we did understand that annoyed road users are dangerous road users, so there does seem to be an indirect safety impact.


Our proof of concepts allow us to remotely influence the affected traffic light systems. From any remote location, we can simulate cyclists approaching, causing the system to decrease the time to green (or even get instant green). Currently, this attack could be performed on traffic lights in about 10 municipalities.

The current findings are limited to the cycling traffic lights. This does have an effect on the car lights, it will turn them red whenever the cyclist light goes green, but we cannot do it the other way around yet with the current implementations.

We investigated the standards being used. These standards describe and support security measurements to prevent our findings. For example, the CAM standard supports signing. In the real life implementations we investigated, these standards are not or not used correctly.

The consequences of these kinds of attack would be bigger if an attacker succeeds to use the same trick to influence the car traffic lights or even simulate emergency vehicles (instant green). This would have a much greater impact on the regular traffic flow: just consider how car drivers respond now to an ambulance approaching.

It is a really cool innovation that’s going on. Smart traffic lights to increase the usability of the traffic light system. However, we really have to build these systems with security in mind. These systems can directly impact people’s lives. At Zolder we get excited by these kinds of innovations. We believe the innovations are both important as well as inevitable. We just need to figure out how to do this safely. We performed this investigation to create some awareness on this topic. However, finding the correct solution is not that easy, because in the end we do have to trust input from road participants.

At Zolder we believe these innovations are on one hand generally beneficial to society and on the other hand simply unavoidable and that the amount will rapidly increase the upcoming years. We reported our findings to both developers so they could fix the issues in their implementations. With sharing our findings at the DEF CON conference we hope to inspire others to contribute to a safer smart traffic future.


Breda Robotics

Erik Remmelzwaal - 10 mei 2021
Zolder BV is toegetreden tot het netwerk van Breda Robotics. Deze vereniging brengt organisaties bij elkaar die actief zijn rondom robotisering in de regio West-Brabant. Voor Zolder geeft Breda Robotics de mogelijkheid om samen te werken met de robotiseringsindustrie. Te begrijpen hoe die sector precies werk en op welke vlakken cybersecurity kennis kan worden ingezet […] Lees verder

27% .nl domeinen slecht beschermd tegen spoofing

Erik Remmelzwaal - 29 apr 2021
TLDR: We scanden de DNS records van 1,6 miljoen .nl domeinen en vonden uit: 9% is rechtstreeks gekoppeld aan Microsoft 365, daarmee is Microsoft veruit de grootste Google is nr2 en heeft 4% van de domeinen aan zich verbonden, nagenoeg gelijk aan een aantal andere spelers. Van alle mail-enabled domeinen heeft 27% geen SPF record […] Lees verder

Zolder biedt MKB betaalbare en eenvoudige security-app

Zolder B.V. - 12 apr 2021
“Attic voorkomt dat security een luchtbel wordt” Security is bij mkb-bedrijven vaak het ondergeschoven kindje. Ze hebben er de mensen en het budget niet voor. Dat maakt deze doelgroep een aantrekkelijk doelwit voor cybercriminelen. Voor de vier doorgewinterde cybersecurity-experts van start-up Zolder reden om Attic te introduceren. Deze eenvoudige, goedkope en toekomstbestendige app maakt mkb’ers […] Lees verder

Nieuwe Themesong voor Zoldersessions

Erik Remmelzwaal - 13 mrt 2021
Ik vond het tijd worden voor een nieuw liedje voor onze Zoldersessions. Tot nu toe hadden we er een rechtenvrij liedje onder staan, namelijk EVA_失望した, maar wilden toch iets meer 'eigens'. Daar schakelden we Bjørgen van Essen voor in met dit eindresultaat. Dit is hoe dat tot stand kwam. Lees verder

Zolder.App Open Beta

Zolder B.V. - 02 feb 2021
We launched the final beta release to the Google and Apple appstores. Any business running on Microsoft 365 is more than welcome to join. As a beta-tester you will receive a free subscription to the Zolder.App Premium Plan for the remainder of the beta phase, which is scheduled to run through April 30th 2021. Zolder.App […] Lees verder

GGD data is topje van ijsberg

Erik Remmelzwaal - 26 jan 2021
Maandag kwam RTL Nieuws, na onderzoek van Daniël Verlaan, naar buiten met het nieuws dat gestolen data van de GGD online wordt verhandeld door criminelen. Het gaat om data die onderdeel uitmaakt van het bron- en contactonderzoek dat de GGD uitvoert als onderdeel van de bestrijding van Corona/COVID-19. De data bevat gevoelige persoonsgegevens en criminelen […] Lees verder

#CES2021 - We Are Ready!

Erik Remmelzwaal - 06 jan 2021
We are very excited to be part of the #CES2021NL mission! Meet us at CES (Januari 11-14) in our online booth 10609 and see how we solve global challenges with NLTech. Erik Remmelzwaal, Co-Founder & CEO Yes I indeed think we are ready for CES. At this virtual event we will showcase Zolder.App. I am […] Lees verder

Zolder.App Blog 3 - Feedback

Erik Remmelzwaal - 27 nov 2020
Bij het ontwikkelen van een nieuwe dienst, zeker als dit Software-as-a-Service betreft, is feedback vanuit (potentiële) afnemers cruciaal. In het geval van Zolder.App is de doelgroep het MKB. We zijn al gelijk na lancering van het merk Zolder gestart met het vinden van MKB-ers die als tester wilden helpen. Oproep 19-apr-2020 Dit leidde tot best […] Lees verder

Azure App Consent Policies

Rik van Duijn - 11 nov 2020
OAuth consent phishing has been on the rise for a while now. Unsurprisingly, Microsoft has gradually introduced measures to protect from this type of attack. Latest: Risk-Based Step-Up Consent. Lees verder

Honeytokens using Azure Keyvaults

Rik van Duijn - 15 okt 2020
In 2017 Wesley and I gave a presentation at SHA2017 about honey/pot/tokens. We actually planned on building a fully fledged platform. But never came further then the POC phase of that project. This week we got a product demo from the guys at Thinkst, i’ve always loved this way of thinking: let the attacker come […] Lees verder

Zolder.App Blog 2 - Probleem & Oplossing

Zolder B.V. - 08 okt 2020
Het is best een goed idee om voordat je begint met het bouwen van een product of dienst, te weten welk probleem je ermee gaat oplossen. Voor Zolder.App: we lossen het probleem dat MKB-ers slecht beveiligd zijn op door enterprise-niveau security voor hen toegankelijk te maken. In feite zijn er een aantal problemen die we […] Lees verder

Risk of exposed home automation services

Wesley Neelen - 24 sep 2020
At home, I am automating many things for fun. Currently I am using Home Assistant, an incredibly powerful piece of software for automating your home. Regularly I am combining the home automation experiences with security. Home automation is often related to physical things such as changing lights, moving curtains, opening door locks or turning the […] Lees verder

Zoldersessions Studio Setup

Zolder B.V. - 27 aug 2020
Here is the kitlist which we end up with to record our Zoldersessions 🙂 Audio Input 4x Rode Procaster microphone 4x Triton Audio FetHead Microphone PreAmp 4x YellowTec m!ka Mic Boom Focusrite Scarlett 18i8 3rd gen Audio Output 4x Shure SRH840 Headphone ART HeadAmp 4 headphone amplifier Video Input 2x Sony Handycam main cameras Logitech […] Lees verder

Zolder.App blog 1 - het idee

Erik Remmelzwaal - 27 aug 2020
Op Zolder bouwen wij aan een mobiele app die MKB’ers op een baanbrekende manier moet helpen digitaal weerbaar te zijn. We verwachten in het vierde kwartaal van 2020 de app te kunnen lanceren. In deze blogreeks neem ik je mee in de ontwikkeling van Zolder.App. Eigenlijk was er niet 1 idee, maar is Zolder.App het […] Lees verder

Hacking the traffic light of the future

Wesley Neelen - 06 aug 2020
Nowadays we are connecting everything we can think of to the internet. Usually to make our lives easier or more comfortable. Some of the new upcoming innovations are related to making our traffic smart with the goal to improve safety, comfort and the traffic flow. We dived into this technology to analyze the inner workings and identify potential security risks. Lees verder

Detect lateral movement with Azure Sentinel

Wesley Neelen - 01 jul 2020
Lately we have been setting up a the production network for our Zolder.App service. The network consists of multiple segments separated by a firewall. As an addition we wanted to add monitoring features into the network. If an attacker is in our network, we would like to get a notification. Lees verder

CSBN 2020

Erik Remmelzwaal - 01 jul 2020
Het jaarlijks CSBN is weer beschikbaar. Het Cybersecurity Beeld Nederland, opgemaakt door onze overheid in de hoedanigheid van de NCTV. Aan afkortingen geen gebrek. Dat maakt het gelijk ook heel taaie kost: ingewikkeld om te doorgronden. Je gaat haast denken dat het ook de bedoeling is dat we er niet teveel aandacht aan besteden. Of […] Lees verder

Detecting BEC fraud using Azure Sentinel

Rik van Duijn - 17 jun 2020
Business Email Compromise (BEC) Fraud inflicts the most damage of all types of cybercrime, according to the FBI. How to detect such attacks using Azure Sentinel? Rik shares some actual possibilities. Lees verder

Security-by-design. Zo makkelijk is dat niet

Wesley Neelen - 16 jun 2020
Wesley beschrijft de complexiteit bij het bouwen van een netwerk infrastructuur: kies je voor veiligheid of werkbaarheid? Of is er een optimale mix? Lees verder

Phishing aftercare

Rik van Duijn - 26 mei 2020
This blog is part of our Office 365 attack & defense series. We also maintain a Github page where we share our Office 365 tools and queries. We often get sent phishing emails by family and friends. Not to phish us but because we ask family and friends to forward them to us. Sometimes they […] Lees verder