This is just a quick blog on how you can quickly stitch together a video file of a presentation and the corresponding talk slides using Open Broadcaster Software (OBS). First time I did this I had to fiddle a little bit around, so this also serves as a mini tutorial for future me. Feel free to leave tips & tricks in the comments.
Continue reading “OBS: Presentation & slides side by side”Category: general
news and random posts
Parsing atop files with python dissect.cstruct
Like you’ve probably read, Fox-IT released their incident response framework called dissect, but before that they released the cstruct part of their framework. Ever since they released it publicly I’ve been wanting to find an excuse to play with it on public projects. I witnissed the birth of cstruct back when I was still working at Fox-IT and am very happy to see it all has finally been made public, it sure has evolved since I had a look at the very first version! Special thanks to Erik Schamper (@Schamperr) for answering late night questions about some of the inner workings of dissect.cstruct.
This is one of those things that you can encounter during your incident response assignment and for which life is a bit easier if you can just parse the binary file format with python. Since with incident response you never know in which format exactly you want to receive the data for analysis or what you are looking for it really helps to work with tools that can be rapidly adjusted. python is an ideal environment to achieve this. An added benefit of parsing the structures ourselves with python is that we can avoid string parsing and thus avoid confusion and mistakes.
The atop tool is a performance monitoring tool that can write the output into a binary file format. The creator explains it way better than I do:
Atop is an ASCII full-screen performance monitor for Linux that is capable of reporting the activity of all processes (even if processes have finished during the interval), daily logging of system and process activity for long-term analysis, highlighting overloaded system resources by using colors, etc. At regular intervals, it shows system-level activity related to the CPU, memory, swap, disks (including LVM) and network layers, and for every process (and thread) it shows e.g. the CPU utilization, memory growth, disk utilization, priority, username, state, and exit code.
The atop tool website
In combination with the optional kernel module netatop, it even shows network activity per process/thread.
Like you can imagine, having the above information is of course a nice treasure throve to find during an incident response, even if it is based on a pre-set interval. For the most basic information, you can at least extract process executions with their respective commandlines and the corresponding timestamp.
Since this is an open source tool we can just look at the structure definitions in C and lift them right into cstruct to start parsing. The atop tool itself offers the ability to parse written binary files as well, for example using this commend:
atop -PPRG -r <file>
For the rest of this blog entry we will look at parsing atop binary log files with python and dissect.cstruct. Mostly intended as a walkthrough of the thought process as well.
You can also skip reading the rest of this blog entry and jump to the code if you are impatient or familiar with similar thought processes.
Continue reading “Parsing atop files with python dissect.cstruct”Baby steps into MITRE Stix/Taxii, Pandas, Graphs & Jupyter notebooks
So there I was preparing a presentation with some pretty pictures and then I thought…after I give this presentation: How will the audience play with the data and see for themselves how these pictures were brought into existence?
Finally I had a nice use-case to play around with some kind of environment to rapidly prototype data visualization in a manner that allows for repeatable further exploration and analyses, hopefully with the ability to draw some kind of conclusion. For now I settled to just learn the basics and get used to all these nifty tools that really make these types of jobs a breeze. You can skip this post and directly go the jupyter notebook if you just want to dive into the data/visualizations. The rest of the blog post is about the choices made and technologies used, mostly intended as a future reference for myself.

Lockbit’s bounty: consequences matter
Apparantly sometimes you only grasp it when it really is in your face, even though you are continuously surrounded by it. The following tweet, made me realize that real consequences to vulnerabilities matter a lot! Oh and this blog is mostly some ponderings and opinions, for the people wondering if they should read it or not :)
What this tweet made me realize is that for Lockbit the consequence of the bug is directly tied to their income. No indirect damages, no additional bugs, no excuses. If the bug isn’t fixed people don’t need to pay them. How many type of companies and bugs do we know that have the same 1-to-1 relation between the bug and the direct consequence to survival?
This made me wonder if we are approaching the rating & fixing of vulnerabilities within regular companies in a less than optimal manner? Would be interesting if we could learn something from groups that operate on continuous innovation and the severe threat of real life consequences like jail time or worse. In this blog I’ll talk about:
- Analysing the Lockbit bug bounty
- Applying the lessons learned to regular companies
TL;DR Bloodhound showed us that graphs are powerful for the analysis and elimination towards domain admin privileges. The same concept should be applied to vulnerablities company wide. Regular companies don’t have the same severe consequences that ransomware groups have, should they?
Continue reading “Lockbit’s bounty: consequences matter”Generating network connection information for experimentation purposes
In one of my last blogs I talked about visualizing firewall data for the purpose of analyzing the configuration and potentially identify security issues. As usual you can skip directly to the tool on my github, or keep on reading.
I wanted to continue playing with this approach to see how it could be improved from a fairly static tool, to a more graph database like approach. However, it turns out that it is somewhat difficult to obtain public firewall configuration files to play with. This is a similar problem to people doing machine learning in cybersecurity where obtaining datasets is still a bit of a challenge.
I decided to write a tool to generate this connection information and at the same time play as well as learn some things which I usually never bother with during development of proof-of-concept projects. So this time I decided to actually document my code, use type annotation and type hints as well as write some unit tests using pytest and actually figure out how argparse sub-commands work.
The tool intends to eventually offer the following options, but for now it only offers the plain
option:
python generator_cli.py
usage: generator_cli.py [-h] [--debug] [--verbose] [--config CONFIG] [--mode {inner,outer,all}] {plain,time,apps,full} ...
Generate network connection with a varying level of metadata
options:
-h, --help show this help message and exit
--debug set debug level
--verbose set informational level
--config CONFIG Configuration file
--mode {inner,outer,all}
Generate only inner vlan, outer vlan or all connections
Available sub-commands:
{plain,time,apps,full}
Generate connection dataset with different levels of metadata
plain Only ip,src,ports
time Adds timestamp within desired range
apps Adds application details per connection
full Generates connections with timestamps & application information
Thanks for giving this a try! --DiabloHorn
The plain
option generates the bare minimum of connection information:
{'srchost': '219.64.120.76', 'dsthost': '68.206.89.177', 'srcport': 64878, 'dstport': 3389}
{'srchost': '219.64.120.13', 'dsthost': '68.206.89.162', 'srcport': 63219, 'dstport': 3389}
{'srchost': '92.9.15.58', 'dsthost': '118.220.234.59', 'srcport': 49842, 'dstport': 3389}
{'srchost': '92.9.15.62', 'dsthost': '118.220.234.216', 'srcport': 57969, 'dstport': 445}
The main concept of the tool is that you can define VLAN names and some options and based on that information inner and outer connections for those VLANs are then generated. The --mode
parameter controls which type of connections it will generate. The inner
mode will only generate connections within the VLAN, the outer
mode will generate only connections from the VLAN to other VLANs and the all
mode will generate both.
I hope, but don’t promise, to eventually implement the other subcommands time
for the generation of connection info within a defined time range (each connection being timestamped) and apps
to generate connection info linked to applications like chrome, spotify, etc.
The following set of commands illustrate how you can use this tool to generate pretty pictures with yED
python generator_cli.py plain | jq '[.srchost,.dsthost,.dstport] | join(",")'
Which will output something along the lines of this, which after converting to an Excel document you can import with yED:
139.75.237.238,127.17.254.69,389
139.75.237.123,127.17.254.147,389
139.75.237.243,127.17.254.192,80
139.75.237.100,127.17.254.149,389
The featured image of this blogs shows all of the generated nodes, the following image provides details of one of those generated collection of nodes:

Three ways to hack an ATM
Please note: This is a mirrored post from a blog I wrote for one of my employers. The goal is to avoid the content being lost, since corporate websites are restructured and changed frequently.
Keyboard attacks, disk attacks and network attacks
Hacking ATMs, also known as Jackpotting, is an activity that speaks to our imagination, conjuring up visions of ATMs that spit out money into the street for everyone to pick up. The three attacks that we describe in this article are the result and recurring theme of numerous assessments that we have performed over the years for many of our customers. These are the (digital) attacks that we believe matter most and that require a serious look from anyone protecting an ATM.
Please note that hacking of ATM’s is an illegal action. Fox-IT’s security experts have performed these attacks with the permission of the ATM’s owners.
Continue reading “Three ways to hack an ATM”Writing a zero findings pentest report
Recently I came across a tweet by @CristiVlad25 asking about what you should write in a pentest report, when there are no findings? I did a quick quote tweet with the first thoughts that came to mind:
Which got me thinking, why not write a bit more about this situation? There are multiple resources on writing pentest reports that all highlight different aspects of the general structure and approach of a pentest report, so I won’t get into that, you can find multiple references, including sample reports at the end of this blog post.
Instead I want to only focus on the situation that you have 0, zero, nothing, nil findings. What do you do then?
Continue reading “Writing a zero findings pentest report”Firewall analysis: A portable graph based approach
Sometimes you are asked to perform a firewall analysis to determine if the configuration can be improved upon to reduce the ability for an attacker to move laterally through the network or identify attack paths that have been missed due to the many firewall changes.
You can perform this analysis using many tools and approaches, ranging from manually reviewing every rule, to using an automated tool like nipper or my personal favourite using a graph based approach (also works for log data). The reference section of this post contains papers that go in-depth on this approach.
With the graph based approach you can visualize the ruleset to identify nodes that have a lot of incoming and/or outgoing connections, but you can also trace paths through the network to understand if they should be removed. When combined with bloodhound data and neo4j you can query the data and have the graph database answer questions like “Is there a path from the workstation to the finance server?”. This requires some fair amount of knowledge, as well as supporting software to get it all setup, which in turn complicates the transfer of knowledge to network engineer or firewall administrators to be able to perform these analysis themselves, for the sake of better understanding if their changes impacted the security of the network.
Bottom line for me with these type of analysis is: How can I transfer security knowledge in an easy and understandable manner, to the people that have to deal with maintaining the environment on a daily basis?
Continue reading “Firewall analysis: A portable graph based approach”More doing, less cyber
A nice and rainy sunday evening, at least from the perspective of the couch that I was on about 10 minutes ago. I have now gotten up and walked to my laptop to rant, rant about cyber and rant about the many excuses that companies use to not become more resilient against attacks. Funnily enough, those excuses have now become the excuses of the cyber people as well. This post won’t really solve anything, it will however allow me to refill my glass of wine and bring me a warm fuzzy feeling of having shared my opinion online, without any goal or intended audience.
If you just want to have a drink (non-alcohol included) and read some chaotic ranting, do continue. Hope you get at the very least a laugh out of it, since your pool of tears has probably dried up a long time ago if you work in cyber security. Oh and if you strongly disagree with this post or it gets you angry or frustrated, just remember that I wrote this to relax, enjoy some wine, rant and then on monday start all over again with attempting to make the reality in which I operate just a little bit more resilient, if possible.
Continue reading “More doing, less cyber”CSAW 2021, binary ninja & a haystack
Getting to know the cloud version of Binary Ninja by reversing the CSAW 2021 haystack challenge.
This is a quick post on our adventures with binary ninja and the haySTACK challenge from this year’s CSAW 2021. On a lost evening @donnymaasland & @nebukatnetsar were playing around and said: Well this looks fun, let’s try it out with Binary Ninja.
I had totally forgotten about Binary Ninja, but boy oh boy do I still like it! Not that I forgot because I use other tools, mostly I forgot because I hardly do technical stuff nowadays. If you are not familiar with it, it is a reversing tool / framework which has a rich API if you use the native client.

The binja cloud version
The nice part is that it also include what they call “High Level IL” which basically is a decompiler that shows you ASM converted to pretty readable C like representation. The even more awesome part is that collaborating on the same binary is a breeze. You can work with multiple people in the same binary without needing to setup anything yourself, just need to make sure everyone has an account on https://cloud.binary.ninja
Let’s get started with the challenge, or more specific getting to know the cloud version of Binary Ninja by playing around with this challenge. We’ll cover some things like:
- Renaming variables
- Creating & applying enums
- Creating & applying structs
- Inviting others to collaborate
- Understanding the thought process
Pentesting: What I should have done
If had the luxury of talking to my past self, these are things I whished I would have done differently during the years that I performed pentesting. Some of these I eventually learned before I finished pentesting, others well, let’s just say they are much more recent. If I think of more items I’ll attempt to update the blog.
If you are a pentester and you are reading this, I hope you can benefit from them. Just make sure you evaluate if they are applicable to your situation and adjust them as required. If you are in a rush, here is the list, details can be found in the rest of this article:
- Don’t be afraid of talking to clients
- Always ask for equivalent access
- Avoid blackbox tests
- Write the report while you pentest
- Images, images & images
- Provide detection advice & POCs
- Provide reproducible POCs for your attacks (security regression tests)
- Provide scripts to fix the issue (when possible)
- Publish more
- Grasp the bigger picture
- Include what you didn’t do
- Don’t be afraid to say something was good
I’ve also included some crazy fantasies of mine, which I’ll always be wondering if they would’ve made a difference.
- Re-use reports and label them as such
- Provide the report upfront
Into the void: ramblings and thoughts
Lately I’ve been shifting from offensive red team type of activities towards management and then towards blue team type of activities. During these transitions I’ve been more and more asking myself is infosec making a difference? I have to admit I got no clue what the answer to that question is, not even remotely. So I’ve decided to put my thoughts and ramblings into a blog post. Any particular reason? I’ve read multiple time that writing out thoughts, helps to organise them and also I just needed to orden my thoughts, maybe in doing so it will help me answer the question for my own specific context. If you continue reading you might experience a decent amount of emotions telling you ‘the guy that wrote this blog is WRONG!’, that’s ok. Feel free to correct me in the comments, it will aid me in finding new perspectives. I’ll try to stick to technical content next time ;)
Continue reading “Into the void: ramblings and thoughts”[Part 2] Interactive and transferrable code risk visualization
In the previous blog post you could read about my experiment with using Microsoft Application Inspector as a tool to:
-
- Scan a code base
- Identify technology components
- Visualize & determine risk
What we learned was that using a pretty coarse tool to establish a guesstimate of risk seems to be doable. We also learned that the output format lends itself very well to transfer knowledge about a code base.
But, how do we go from “seems doable” to “I’ve got a transferrable guesstimate on code risk”? My first idea was to just continue with merging the previous kibana visualizations into a nice interactive one and be done.
After some playing around I noticed that it wasn’t that easy! Further experimentation revealed, that the main reason I was struggling to visualize risk is the fact that I had no clue what I really meant by ‘code risk’. Sure, I know how to spot vulnerabilities in code and reason about it, but is that really a risk? I asked other pentesters and it was interesting that finding the vuln was easy, defining the risk was not. For example, a code base with clearly observable vulnerabilities is often viewed as a risk. What if those vulnerabilities are fixed, just enough, do we then still consider that the risk is present? If you are wondering what ‘just enough’ means, here is an example:
Vulnerability: SQL injection in ID parameter of an URL
Root cause: Untrusted user input used in a non-parametrized SQL query
Fix: Regex to only allow numbers
So, would this after implementing the fix: a) Be a vulnerability? b) Could we consider this a risk? I think that at the very least the query should also be rewritten to be parametrized. Why do we still hammer on changing the code if the vulnerability has been fixed? Because, speaking for myself, the used function or implementation of the functionality is flawed by design. So even if the exploitable vulnerability has been fixed, I still consider this risky code.
Yes, you could argue that it is the use of the function and not the function itself that carries the risk. For this blog and the purpose of this experiment, I’m not going to dive into those semantics.
For now, let’s dive a bit deeper into understanding risk then defining risk and hopefully visualizing risk in an interactive manner. The transferrable aspect is, of course, the fact that the knowledge is bundled into easy and structured file formats. The github for the POC files can be found here.
Continue reading “[Part 2] Interactive and transferrable code risk visualization”[Part 1] Experimenting with visualizations and code risk overview
The benefits of being exposed to new subjects are that you tinker with them and start experimenting. Hopefully, this blog leads to some new ideas or at best revisits some established ideas and attempt to show that a less perfect approach might just work. Also keep in mind I’m by no means an expert in advanced automatic code / data flow analysis.
So at my current company, one of our units is doing some pretty cool work with ensuring that security operates at agile speeds, instead of being slow and blocking. One of their areas of focus is the automation of code reviews augmented with human expertise. One of my former colleagues Remco and I got chatting about the subject and he brought me up to speed on the subject. The promising developments in this area (as far as I understood it) concerns the ability to grasp, understand, process the language structure (AST), but also the ability to follow code flows, data types and values and of course lately the practical application of machine learning to these subjects. In a way mimicking how code-reviewers go through code, but using data flow techniques to for example track untrusted (external) input.
What is it good for? That was my first question. Turns out that if you have the above-described ability, you can more easily and precisely spot potential security flaws in an automated manner. It also enables you to create repeatable queries that enable you to quickly weed out security vulnerabilities and detect them if they or variants somehow creep back into the source.
Because just as with regular ‘user security awareness’, an automated and fool-proof process will beat ‘awareness’ every time. Having security aware developers is not bad, but having automated processes and process-failure detection is even better.
However, the above is pretty complex, so I decided to tinker with a less optimal and perfect solution and see what I could do with it. My main goal was to achieve the following:
Enable a guesstimate on what part of a code base could be considered ‘risky’ security wise. Capture the code reviewers knowledge and improve the guesstimate of ‘risky’ parts of a code base.
The above would result in an improved ability to process codebases according to a more risk-based approach, without continuously needing expensive experts. It would however not be fully precise, generation of false positives. The lack of precision I accept in return for the ability to at least have a guesstimate on where to spend focus and effort.
If you are still interested, keep on reading. Just don’t forget that I’m a big fan of: better to progress a bit than no progress at all.
Perfect is the enemy of good
Continue reading “[Part 1] Experimenting with visualizations and code risk overview”
The fallacy of ‘manual work’ being faster
Like many people, due to recent events, I’ve had more time to reflect on myself and on some of my mistakes. I’ve always been a fan of sharing knowledge, that includes failures and the things you learn from them. So here is one of those failure from which upon self reflecting I’ve learned to change that behavior.
Sometimes you already knew something was true, but you just kept lying to yourself. This is even worse when you have recommended other people to do what you still refuse to do yourself, because you keep lying to yourself. The recommendation is good, the part where you don’t follow your own recommendation, that’s where it all goes down the drain. If you are wondering what I’m talking about, I’m talking about:
Doing all kinds of tasks manually, because in that precise moment it was the ‘quick’ option
The above is what I’ve been doing for the last couple of years, mainly because during my day job my work is less technical. This is the wrong approach, even if I told myself otherwise. The interesting part is that during this time I coached and advised people around me to:
- stick to (further) learning programming languages
- Learn devops
- Take the time to automate and learn how to automate
- Don’t worry about being slow now, it will pay off
So why then, did I not follow my own advise? Because besides the reason of it being quicker to do manually, I also told myself that by doing it manually it would be easier to retain technical knowledge.
Now this blog has turned up two fallacies:
- Thinking that doing it manually is quicker
- Thinking that by doing it manually you retain knowledge
Both of them are incorrect, that much is obvious, but why?
The first one is incorrect because the moments that warrant that ‘quickness’ in that precise moment are not as many as you’ve been telling yourself. My experience is that in a lot of cases it was perfectly fine to grab a couple of hours or a day or two to automate it. I actually experienced this, since other people with the exact same problem took the advise and automated it. They could later indeed benefit from their work and the more often that they automated tasks, the faster they could do it.
The second one is incorrect, because in a sense you are training yourself to:
Re-learn the same knowledge over and over again
Instead of learning something, documenting it and being able to go back to it. You are learning something, doing it by hand and then forgetting it. Yes you might retain some of it, but eventually it will fade. So if you need to do it again, you need to re-learn it again instead of referencing it and building upon your previous knowledge. I knew this all along, since I often went back to older scripts and code I wrote. I just never took the time to keep doing that when my day job diminished the amount of time I spent on technical problems. Somehow the reward of doing something fast in that precise moment, was bigger than automating it and reaping the benefits. The illusions and tricks the mind plays on you are truly magical.
To get myself going again, I decided to automate a thing I’ve been doing manually for the last couple of years, which is configuring a newly installed Ubuntu VM. The ansible setup is not perfect, but at least I’ve begun to automate it:
https://github.com/DiabloHorn/env-automata
I hope that other people in similar situations benefit from this self reflection and that they don’t fall for the same fallacy.