directory writeup
This commit is contained in:
		
							parent
							
								
									38b0ff2fb5
								
							
						
					
					
						commit
						80e5c93e25
					
				| 
						 | 
				
			
			@ -3,3 +3,4 @@ templates/blog/*
 | 
			
		|||
flask_run.sh
 | 
			
		||||
poetry.lock
 | 
			
		||||
build
 | 
			
		||||
venv
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
3.11.0
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,95 @@
 | 
			
		|||
2025-07-20
 | 
			
		||||
 | 
			
		||||
# Directory Writeup — TryHackMe
 | 
			
		||||
 | 
			
		||||
This blog post is a writeup of the
 | 
			
		||||
[Directory](https://tryhackme.com/room/directorydfirroom) challenge on
 | 
			
		||||
[TryHackMe](https://tryhackme.com)
 | 
			
		||||
 | 
			
		||||
**What ports did the threat actor initially find open? Format: from lowest to
 | 
			
		||||
highest, separated by a comma.**
 | 
			
		||||
 | 
			
		||||
We can see that the attacker is scanning ports on the target system. If there
 | 
			
		||||
would be an open port on the target system, the answer would include SYN/ACK,
 | 
			
		||||
which is a flag of `0x12`.
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
tshark -r ./traffic-1725627206938.pcap \
 | 
			
		||||
-T fields -Y tcp.flags == 0x12 \
 | 
			
		||||
-e tcp.srcport -e ip.dst_host \
 | 
			
		||||
| sort -n | uniq | sort -rn
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
**The threat actor found four valid usernames, but only one username allowed
 | 
			
		||||
the attacker to achieve a foothold on the server. What was the username?
 | 
			
		||||
Format: Domain.TLD\username**
 | 
			
		||||
 | 
			
		||||
After extracting all HTTP files, the result shows that there are some potential usernames
 | 
			
		||||
to be crafted from the names of the people mentioned on the page, which the
 | 
			
		||||
adversary
 | 
			
		||||
could try to login.
 | 
			
		||||
 | 
			
		||||
Filtering for Kerberos packages, it is clearly visible that the attacker tried
 | 
			
		||||
to bruteforce the usernames
 | 
			
		||||
 | 
			
		||||
<p><img alt="Wireshark, listing kerberos packages"
 | 
			
		||||
src="../../static/images/usernames-kerberos.jpg"  title="SureStore DAT40"
 | 
			
		||||
/></p>
 | 
			
		||||
 | 
			
		||||
Only two requests did not end up in an error as a response. These contain the username
 | 
			
		||||
we are looking for.
 | 
			
		||||
 | 
			
		||||
We need the `CNameString` as well as the `SNameString` in combination to get
 | 
			
		||||
the correct login name.
 | 
			
		||||
 | 
			
		||||
**The threat actor captured a hash from the user in question 2. What are the
 | 
			
		||||
last 30 characters of that hash?**
 | 
			
		||||
 | 
			
		||||
The same `AS-REP` response package from the previous question contains an
 | 
			
		||||
encrypted part, which contains the hash as a cipher of type
 | 
			
		||||
`eType-ARFOUR-HMAC-MD5 (23)`. This is the hash we are looking for.
 | 
			
		||||
 | 
			
		||||
**What is the user's password?**
 | 
			
		||||
 | 
			
		||||
We can use
 | 
			
		||||
[Krb5RoastParser](https://github.com/jalvarezz13/Krb5RoastParser.git) to
 | 
			
		||||
extract the AS-REP hash and crack it.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$krb5asrep$23$larry.doe@DIRECTORY.THM:f8716efbaa984508ddde606756441480$805ab8be8cfb018a282718f7c040cd43924c6f9afeb6171230bbd3dccc79294dcf2f877a44c1a0981aadb7bb7a9510dd52d8dda4039ef4dcb444f18c9902be1623035e10aebf16ce4bdf5f7064f480e67e96ec2eb32bad95c5a1247bd7a241273fe80e281f4e6a99926f7969fcf803190c7096b947a33407f8578d4c0fb8b52d2aa8d0405a44b72bd21e014563cb71e82aee0e12538d0d440c930b98abf766e18ddc99a964e6e812ecf8dc8994a912a02074d40e5e6906915c1d216653d45df88636b51656f2c37de2020a2fd86ee7ecf6f0afe3f509fd31144e1573f9587155616532b664cd0b50cda8d4ba469f
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Use john or hashcat to decrypt the password.
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
john --wordlist=/usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt ../kerb.hash
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
**What were the second and third commands that the threat actor executed on the
 | 
			
		||||
system? Format: command1,command2**
 | 
			
		||||
 | 
			
		||||
There is a script to decrypt winrm traffic  on [jborean93's github
 | 
			
		||||
page](https://gist.github.com/jborean93/d6ff5e87f8a9f5cb215cd49826523045/).
 | 
			
		||||
Using the password we aquired before, the traffic can be decoded.
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
python winrm_decrypt.py ./traffic-1725627206938.pcap --password '********' > winrm.output
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The parts we are interested in are the Powershell commands. We need to decode
 | 
			
		||||
the commands, since these are b64 encoded.
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
grep "AAAAAA" winrm.output | cut -d '>' -f2 | cut -d '<' -f1 | base64 -d >> decoded.out
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Now we can take e look at the commands using less or some other tool.
 | 
			
		||||
 | 
			
		||||
**What is the flag?**
 | 
			
		||||
 | 
			
		||||
We already decoded the commands in the previous step, just do a search for the
 | 
			
		||||
flag structure in the already decoded output.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
THM{***************}
 | 
			
		||||
```
 | 
			
		||||
| 
						 | 
				
			
			@ -9,7 +9,7 @@
 | 
			
		|||
        <title>Hello, this is my </title>
 | 
			
		||||
        <meta name="viewport" content="width=device-width, initial-scale=1">
 | 
			
		||||
    <div class="menu">
 | 
			
		||||
    <a href="/" style="text-decoration:none">Stefan Friese's Website</a>
 | 
			
		||||
    <a href="/" style="text-decoration:none">Stefan Etringer's Website</a>
 | 
			
		||||
    </div>
 | 
			
		||||
    <style>
 | 
			
		||||
        /* Stylesheet 1 */
 | 
			
		||||
| 
						 | 
				
			
			@ -41,14 +41,14 @@
 | 
			
		|||
    </head>
 | 
			
		||||
    <body>
 | 
			
		||||
        <div lang="en" class="content">
 | 
			
		||||
My name is Stefan Friese. I am fascinated by computers since I first saw my Dad working on the ZX Spectrumn. For me, the greatest thing is to learn something new. I like music, engineering, art, design and security CTFs. I write blog entries on my journey, so I’ll be able to look stuff up, remember and share it with you and students at work.<p></p><div class="contact";><script  src="https://tryhackme.com/badge/502760"></script><p></p></div>
 | 
			
		||||
My name is Stefan Etringer. I am fascinated by computers since I first saw my Dad working on the ZX Spectrumn. For me, the greatest thing is to learn something new. I like music, engineering, art, design and security CTFs. I write blog entries on my journey, so I’ll be able to look stuff up, remember and share it with you and students at work.<p></p><div class="contact";><script  src="https://tryhackme.com/badge/502760"></script><p></p></div>
 | 
			
		||||
</div>
 | 
			
		||||
        <div id="footer">
 | 
			
		||||
            
 | 
			
		||||
    <hr/>
 | 
			
		||||
<p></p>
 | 
			
		||||
    <center>
 | 
			
		||||
            © Stefan Friese
 | 
			
		||||
            © Stefan Etringer
 | 
			
		||||
    </center>
 | 
			
		||||
            
 | 
			
		||||
        </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,7 +9,7 @@
 | 
			
		|||
        <title>Stefan's Blog</title>
 | 
			
		||||
        <meta name="viewport" content="width=device-width, initial-scale=1">
 | 
			
		||||
    <div class="menu">
 | 
			
		||||
    <a href="/" style="text-decoration:none">Stefan Friese's Website</a>
 | 
			
		||||
    <a href="/" style="text-decoration:none">Stefan Etringer's Website</a>
 | 
			
		||||
    </div>
 | 
			
		||||
    <style>
 | 
			
		||||
        /* Stylesheet 1 */
 | 
			
		||||
| 
						 | 
				
			
			@ -67,6 +67,7 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left:
 | 
			
		|||
.codehilite .cs { color: #7F848E } /* Comment.Special */
 | 
			
		||||
.codehilite .gd { color: #ABB2BF } /* Generic.Deleted */
 | 
			
		||||
.codehilite .ge { color: #ABB2BF } /* Generic.Emph */
 | 
			
		||||
.codehilite .ges { color: #ABB2BF } /* Generic.EmphStrong */
 | 
			
		||||
.codehilite .gr { color: #ABB2BF } /* Generic.Error */
 | 
			
		||||
.codehilite .gh { color: #ABB2BF } /* Generic.Heading */
 | 
			
		||||
.codehilite .gi { color: #ABB2BF } /* Generic.Inserted */
 | 
			
		||||
| 
						 | 
				
			
			@ -228,7 +229,7 @@ the following snippet. After the dictionary is sorted by date,
 | 
			
		|||
returns a string. The result will be interpreted by the browser in
 | 
			
		||||
HTML/CSS format.</p>
 | 
			
		||||
<div class="codehilite"><pre><span></span><code>    <span class="nd">@app</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s1">'/'</span><span class="p">)</span>
 | 
			
		||||
    <span class="k">def</span> <span class="nf">index</span><span class="p">(</span><span class="n">_paths</span><span class="o">=</span><span class="n">meta_data</span><span class="p">):</span>
 | 
			
		||||
    <span class="k">def</span><span class="w"> </span><span class="nf">index</span><span class="p">(</span><span class="n">_paths</span><span class="o">=</span><span class="n">meta_data</span><span class="p">):</span>
 | 
			
		||||
        <span class="n">sorted_meta_data</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">meta_data</span><span class="o">.</span><span class="n">items</span><span class="p">(),</span> <span class="n">reverse</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">item</span> <span class="p">:</span> <span class="n">item</span><span class="p">[</span><span class="mi">1</span><span class="p">]))</span>
 | 
			
		||||
        <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s2">"index.html"</span><span class="p">,</span> <span class="n">_paths</span><span class="o">=</span><span class="n">sorted_meta_data</span><span class="p">)</span>
 | 
			
		||||
</code></pre></div>
 | 
			
		||||
| 
						 | 
				
			
			@ -256,7 +257,7 @@ returns the articles if you want to visit the site. It handles URL
 | 
			
		|||
encoding as well. This is pretty neat since there are spaces in the
 | 
			
		||||
names.</p>
 | 
			
		||||
<div class="codehilite"><pre><span></span><code>    <span class="nd">@app</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s1">'/blog/<blog_item>/index.html'</span><span class="p">)</span>
 | 
			
		||||
    <span class="k">def</span> <span class="nf">blog</span><span class="p">(</span><span class="n">blog_item</span><span class="p">,</span> <span class="n">_date</span><span class="o">=</span><span class="n">meta_data</span><span class="p">):</span>
 | 
			
		||||
    <span class="k">def</span><span class="w"> </span><span class="nf">blog</span><span class="p">(</span><span class="n">blog_item</span><span class="p">,</span> <span class="n">_date</span><span class="o">=</span><span class="n">meta_data</span><span class="p">):</span>
 | 
			
		||||
        <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="sa">f</span><span class="s2">"blog/</span><span class="si">{</span><span class="n">blog_item</span><span class="si">}</span><span class="s2">/index.html"</span><span class="p">,</span> <span class="n">_date</span><span class="o">=</span><span class="n">meta_data</span><span class="p">[</span><span class="n">blog_item</span><span class="p">])</span>
 | 
			
		||||
</code></pre></div>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -284,7 +285,7 @@ ISBN:9780465051366</a><br />
 | 
			
		|||
    <hr/>
 | 
			
		||||
<p></p>
 | 
			
		||||
    <center>
 | 
			
		||||
            © Stefan Friese
 | 
			
		||||
            © Stefan Etringer
 | 
			
		||||
    </center>
 | 
			
		||||
            
 | 
			
		||||
        </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,7 +9,7 @@
 | 
			
		|||
        <title>Stefan's Blog</title>
 | 
			
		||||
        <meta name="viewport" content="width=device-width, initial-scale=1">
 | 
			
		||||
    <div class="menu">
 | 
			
		||||
    <a href="/" style="text-decoration:none">Stefan Friese's Website</a>
 | 
			
		||||
    <a href="/" style="text-decoration:none">Stefan Etringer's Website</a>
 | 
			
		||||
    </div>
 | 
			
		||||
    <style>
 | 
			
		||||
        /* Stylesheet 1 */
 | 
			
		||||
| 
						 | 
				
			
			@ -67,6 +67,7 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left:
 | 
			
		|||
.codehilite .cs { color: #7F848E } /* Comment.Special */
 | 
			
		||||
.codehilite .gd { color: #ABB2BF } /* Generic.Deleted */
 | 
			
		||||
.codehilite .ge { color: #ABB2BF } /* Generic.Emph */
 | 
			
		||||
.codehilite .ges { color: #ABB2BF } /* Generic.EmphStrong */
 | 
			
		||||
.codehilite .gr { color: #ABB2BF } /* Generic.Error */
 | 
			
		||||
.codehilite .gh { color: #ABB2BF } /* Generic.Heading */
 | 
			
		||||
.codehilite .gi { color: #ABB2BF } /* Generic.Inserted */
 | 
			
		||||
| 
						 | 
				
			
			@ -256,7 +257,7 @@ ISBN:9780131429017</a></p>
 | 
			
		|||
    <hr/>
 | 
			
		||||
<p></p>
 | 
			
		||||
    <center>
 | 
			
		||||
            © Stefan Friese
 | 
			
		||||
            © Stefan Etringer
 | 
			
		||||
    </center>
 | 
			
		||||
            
 | 
			
		||||
        </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,7 +9,7 @@
 | 
			
		|||
        <title>Hello, this is my </title>
 | 
			
		||||
        <meta name="viewport" content="width=device-width, initial-scale=1">
 | 
			
		||||
    <div class="menu">
 | 
			
		||||
    <a href="/" style="text-decoration:none">Stefan Friese's Website</a>
 | 
			
		||||
    <a href="/" style="text-decoration:none">Stefan Etringer's Website</a>
 | 
			
		||||
    </div>
 | 
			
		||||
    <style>
 | 
			
		||||
        /* Stylesheet 1 */
 | 
			
		||||
| 
						 | 
				
			
			@ -51,7 +51,7 @@
 | 
			
		|||
    <hr/>
 | 
			
		||||
<p></p>
 | 
			
		||||
    <center>
 | 
			
		||||
            © Stefan Friese
 | 
			
		||||
            © Stefan Etringer
 | 
			
		||||
    </center>
 | 
			
		||||
            
 | 
			
		||||
        </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,7 +9,7 @@
 | 
			
		|||
        <title>Stefan's Blog</title>
 | 
			
		||||
        <meta name="viewport" content="width=device-width, initial-scale=1">
 | 
			
		||||
    <div class="menu">
 | 
			
		||||
    <a href="/" style="text-decoration:none">Stefan Friese's Website</a>
 | 
			
		||||
    <a href="/" style="text-decoration:none">Stefan Etringer's Website</a>
 | 
			
		||||
    </div>
 | 
			
		||||
    <style>
 | 
			
		||||
        /* Stylesheet 1 */
 | 
			
		||||
| 
						 | 
				
			
			@ -44,6 +44,8 @@
 | 
			
		|||
       <p>Welcome to my website</p>
 | 
			
		||||
       <span class="index">
 | 
			
		||||
       
 | 
			
		||||
       <p><a href="/blog/Directory%20Writeup%20%E2%80%94%20TryHackMe/index.html">2025-07-20  Directory Writeup — TryHackMe</a></p>
 | 
			
		||||
       
 | 
			
		||||
       <p><a href="/blog/Restoring%20(NT)Backups%20From%20a%20SCSI%20Tape%20Drive/index.html">2023-09-27  Restoring (NT)Backups From a SCSI Tape Drive</a></p>
 | 
			
		||||
       
 | 
			
		||||
       <p><a href="/blog/The%20Joy%20of%20One-Liners/index.html">2022-05-29  The Joy of One-Liners</a></p>
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +59,7 @@
 | 
			
		|||
    <hr/>
 | 
			
		||||
<p></p>
 | 
			
		||||
    <center>
 | 
			
		||||
            © Stefan Friese
 | 
			
		||||
            © Stefan Etringer
 | 
			
		||||
    </center>
 | 
			
		||||
            
 | 
			
		||||
        </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,2 +1,2 @@
 | 
			
		|||
<?xml version='1.0' encoding='UTF-8'?>
 | 
			
		||||
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"><channel><title>Website of Stefan Friese</title><link>https://stefan.works</link><description>test</description><atom:link href="https://stefan.works" rel="self"/><docs>http://www.rssboard.org/rss-specification</docs><generator>python-feedgen</generator><language>en-us</language><lastBuildDate>Wed, 11 Oct 2023 19:32:42 +0000</lastBuildDate><item><title>Restoring (NT)Backups From a SCSI Tape Drive</title><link>https://stefan.works/blog/Restoring (NT)Backups From a SCSI Tape Drive/index.html</link><guid isPermaLink="false">https://stefan.works/blog/Restoring (NT)Backups From a SCSI Tape Drive/index.html</guid><pubDate>Wed, 27 Sep 2023 00:00:00 +0200</pubDate></item><item><title>The Joy of One-Liners</title><link>https://stefan.works/blog/The Joy of One-Liners/index.html</link><guid isPermaLink="false">https://stefan.works/blog/The Joy of One-Liners/index.html</guid><pubDate>Sun, 29 May 2022 00:00:00 +0200</pubDate></item><item><title>Keep It Simple</title><link>https://stefan.works/blog/Keep It Simple/index.html</link><guid isPermaLink="false">https://stefan.works/blog/Keep It Simple/index.html</guid><pubDate>Tue, 01 Jun 2021 00:00:00 +0200</pubDate></item></channel></rss>
 | 
			
		||||
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"><channel><title>Website of Stefan Friese</title><link>https://stefan.works</link><description>test</description><atom:link href="https://stefan.works" rel="self"/><docs>http://www.rssboard.org/rss-specification</docs><generator>python-feedgen</generator><language>en-us</language><lastBuildDate>Sun, 20 Jul 2025 22:08:29 +0000</lastBuildDate><item><title>Directory Writeup — TryHackMe</title><link>https://stefan.works/blog/Directory Writeup — TryHackMe/index.html</link><guid isPermaLink="false">https://stefan.works/blog/Directory Writeup — TryHackMe/index.html</guid><pubDate>Sun, 20 Jul 2025 00:00:00 +0200</pubDate></item><item><title>Restoring (NT)Backups From a SCSI Tape Drive</title><link>https://stefan.works/blog/Restoring (NT)Backups From a SCSI Tape Drive/index.html</link><guid isPermaLink="false">https://stefan.works/blog/Restoring (NT)Backups From a SCSI Tape Drive/index.html</guid><pubDate>Wed, 27 Sep 2023 00:00:00 +0200</pubDate></item><item><title>The Joy of One-Liners</title><link>https://stefan.works/blog/The Joy of One-Liners/index.html</link><guid isPermaLink="false">https://stefan.works/blog/The Joy of One-Liners/index.html</guid><pubDate>Sun, 29 May 2022 00:00:00 +0200</pubDate></item><item><title>Keep It Simple</title><link>https://stefan.works/blog/Keep It Simple/index.html</link><guid isPermaLink="false">https://stefan.works/blog/Keep It Simple/index.html</guid><pubDate>Tue, 01 Jun 2021 00:00:00 +0200</pubDate></item></channel></rss>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,2 +1,2 @@
 | 
			
		|||
<?xml version='1.0' encoding='UTF-8'?>
 | 
			
		||||
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"><channel><title>Website of Stefan Friese</title><link>https://stefan.works</link><description>test</description><atom:link href="https://stefan.works" rel="self"/><docs>http://www.rssboard.org/rss-specification</docs><generator>python-feedgen</generator><language>en-us</language><lastBuildDate>Sat, 15 Jul 2023 21:28:59 +0000</lastBuildDate><item><title>The Joy of One-Liners</title><link>https://stefan.works/blog/The Joy of One-Liners/index.html</link><guid isPermaLink="false">https://stefan.works/blog/The Joy of One-Liners/index.html</guid><pubDate>Sun, 29 May 2022 00:00:00 +0200</pubDate></item><item><title>Keep It Simple</title><link>https://stefan.works/blog/Keep It Simple/index.html</link><guid isPermaLink="false">https://stefan.works/blog/Keep It Simple/index.html</guid><pubDate>Tue, 01 Jun 2021 00:00:00 +0200</pubDate></item></channel></rss>
 | 
			
		||||
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"><channel><title>Website of Stefan Friese</title><link>https://stefan.works</link><description>test</description><atom:link href="https://stefan.works" rel="self"/><docs>http://www.rssboard.org/rss-specification</docs><generator>python-feedgen</generator><language>en-us</language><lastBuildDate>Wed, 11 Oct 2023 19:32:42 +0000</lastBuildDate><item><title>Restoring (NT)Backups From a SCSI Tape Drive</title><link>https://stefan.works/blog/Restoring (NT)Backups From a SCSI Tape Drive/index.html</link><guid isPermaLink="false">https://stefan.works/blog/Restoring (NT)Backups From a SCSI Tape Drive/index.html</guid><pubDate>Wed, 27 Sep 2023 00:00:00 +0200</pubDate></item><item><title>The Joy of One-Liners</title><link>https://stefan.works/blog/The Joy of One-Liners/index.html</link><guid isPermaLink="false">https://stefan.works/blog/The Joy of One-Liners/index.html</guid><pubDate>Sun, 29 May 2022 00:00:00 +0200</pubDate></item><item><title>Keep It Simple</title><link>https://stefan.works/blog/Keep It Simple/index.html</link><guid isPermaLink="false">https://stefan.works/blog/Keep It Simple/index.html</guid><pubDate>Tue, 01 Jun 2021 00:00:00 +0200</pubDate></item></channel></rss>
 | 
			
		||||
							
								
								
									
										107
									
								
								start_site.py
								
								
								
								
							
							
						
						
									
										107
									
								
								start_site.py
								
								
								
								
							| 
						 | 
				
			
			@ -19,14 +19,16 @@ app = Flask(__name__)
 | 
			
		|||
Markdown(app)
 | 
			
		||||
 | 
			
		||||
meta_data = {
 | 
			
		||||
    root[len("./blog/"):]: datetime.strptime(
 | 
			
		||||
        open(os.path.join(root, "index.md"), encoding='UTF-8')
 | 
			
		||||
        .readline().rstrip(),
 | 
			
		||||
        "%Y-%m-%d"
 | 
			
		||||
    root[len("./blog/") :]: datetime.strptime(
 | 
			
		||||
        open(os.path.join(root, "index.md"), encoding="UTF-8").readline().rstrip(),
 | 
			
		||||
        "%Y-%m-%d",
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    for root, dirs, files in os.walk("./blog")
 | 
			
		||||
 | 
			
		||||
    if "index.md" in files
 | 
			
		||||
        }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
app.config["blog"] = toml.load("settings.toml")
 | 
			
		||||
content_path = app.config["blog"]["content"]["path"]
 | 
			
		||||
| 
						 | 
				
			
			@ -40,59 +42,47 @@ app.config["blog"]["style"] = toml.load("style.toml")
 | 
			
		|||
colors = app.config["blog"]["style"][highlight_style]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.route('/')
 | 
			
		||||
@app.route("/")
 | 
			
		||||
def index(_paths=meta_data):
 | 
			
		||||
    ''' Main Site.
 | 
			
		||||
    '''
 | 
			
		||||
    """Main Site."""
 | 
			
		||||
    sorted_meta_data = dict(
 | 
			
		||||
        sorted(
 | 
			
		||||
            meta_data.items(),
 | 
			
		||||
            reverse=True,
 | 
			
		||||
            key=lambda item: item[1]
 | 
			
		||||
            )
 | 
			
		||||
        sorted(meta_data.items(), reverse=True, key=lambda item: item[1])
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    return render_template("index.html", colors=colors, _paths=sorted_meta_data)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.route('/blog/<blog_item>/index.html')
 | 
			
		||||
@app.route("/blog/<blog_item>/index.html")
 | 
			
		||||
def blog(blog_item, _date=meta_data):
 | 
			
		||||
    ''' Blog Pages.
 | 
			
		||||
    '''
 | 
			
		||||
    """Blog Pages."""
 | 
			
		||||
    md_file_path = os.path.join(f"blog/{blog_item}/index.md")
 | 
			
		||||
    with open(md_file_path, "r") as _f:
 | 
			
		||||
        md_file = _f.read()
 | 
			
		||||
    md_extensions = [
 | 
			
		||||
        'toc',
 | 
			
		||||
        "toc",
 | 
			
		||||
        TocExtension(toc_class="", title=""),
 | 
			
		||||
        "fenced_code",
 | 
			
		||||
        "codehilite",
 | 
			
		||||
        "tables",
 | 
			
		||||
        "mdx_math"
 | 
			
		||||
        "mdx_math",
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    md_configs = {"mdx_math": {"enable_dollar_delimiter": True}}
 | 
			
		||||
    md = markdown.Markdown(
 | 
			
		||||
        extensions=md_extensions,
 | 
			
		||||
        extension_configs=md_configs
 | 
			
		||||
        )
 | 
			
		||||
    md = markdown.Markdown(extensions=md_extensions, extension_configs=md_configs)
 | 
			
		||||
 | 
			
		||||
    html = md.convert(md_file)
 | 
			
		||||
 | 
			
		||||
    formatter = HtmlFormatter(
 | 
			
		||||
        style=highlight_style,
 | 
			
		||||
        full=True,
 | 
			
		||||
        cssclass="codehilite"
 | 
			
		||||
        )
 | 
			
		||||
    formatter = HtmlFormatter(style=highlight_style, full=True, cssclass="codehilite")
 | 
			
		||||
    css_string = formatter.get_style_defs()
 | 
			
		||||
    md_css_string = "<style>" + css_string + "</style>"
 | 
			
		||||
    md_template = md_css_string + html
 | 
			
		||||
    res = render_template(
 | 
			
		||||
        "blog.html",
 | 
			
		||||
        #toc=md.toc,
 | 
			
		||||
        # toc=md.toc,
 | 
			
		||||
        md_doc=md_template,
 | 
			
		||||
        colors=colors,
 | 
			
		||||
        stylesheet=STYLESHEET,
 | 
			
		||||
        #stylesheet_auto_complete=STYLESHEET_AUTO_COMPLETE,
 | 
			
		||||
        # stylesheet_auto_complete=STYLESHEET_AUTO_COMPLETE,
 | 
			
		||||
        project_name=project_name,
 | 
			
		||||
        project_title=project_title,
 | 
			
		||||
        # tree=cut_path_tree(
 | 
			
		||||
| 
						 | 
				
			
			@ -100,12 +90,12 @@ def blog(blog_item, _date=meta_data):
 | 
			
		|||
        #     make_tree(content_path),
 | 
			
		||||
        #     content_path,
 | 
			
		||||
        #     ".md" #     )
 | 
			
		||||
        _date=meta_data[blog_item]
 | 
			
		||||
        _date=meta_data[blog_item],
 | 
			
		||||
    )
 | 
			
		||||
    response = make_response(res)
 | 
			
		||||
    response.headers["Content-Type"] = "text/html; charset=utf-8"
 | 
			
		||||
    return response
 | 
			
		||||
 | 
			
		||||
    return response
 | 
			
		||||
 | 
			
		||||
    # return render_template(
 | 
			
		||||
    #     f"blog/{blog_item}/index.html",
 | 
			
		||||
| 
						 | 
				
			
			@ -115,31 +105,32 @@ def blog(blog_item, _date=meta_data):
 | 
			
		|||
 | 
			
		||||
@app.route("/about.html")
 | 
			
		||||
def about():
 | 
			
		||||
    ''' About Page.
 | 
			
		||||
    '''
 | 
			
		||||
    """About Page."""
 | 
			
		||||
 | 
			
		||||
    return render_template("about.html", colors=colors)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.route("/contact.html")
 | 
			
		||||
def contact():
 | 
			
		||||
    ''' Contact Page.
 | 
			
		||||
    '''
 | 
			
		||||
    """Contact Page."""
 | 
			
		||||
 | 
			
		||||
    return render_template("contact.html", colors=colors)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.route("/rss.xml")
 | 
			
		||||
def rss(_items=meta_data):
 | 
			
		||||
    ''' RSS Feed.
 | 
			
		||||
    """RSS Feed.
 | 
			
		||||
    Generates RSS feed as XML
 | 
			
		||||
    '''
 | 
			
		||||
    """
 | 
			
		||||
    # rss_feed = []
 | 
			
		||||
    _tz = pytz.timezone('Europe/Berlin')
 | 
			
		||||
    _tz = pytz.timezone("Europe/Berlin")
 | 
			
		||||
    _fg = FeedGenerator()
 | 
			
		||||
    _fg.title("Website of Stefan Friese")
 | 
			
		||||
    _fg.description("test")
 | 
			
		||||
    _fg.language("en-us")
 | 
			
		||||
    # _fg.author({'name': "Stefan Friese", 'email': 'stefan@stefan.works'})
 | 
			
		||||
    _fg.link(href="https://stefan.works", rel="self")
 | 
			
		||||
 | 
			
		||||
    for key in meta_data.keys():
 | 
			
		||||
        _fe = _fg.add_entry()
 | 
			
		||||
        _fe.id(f"https://stefan.works/blog/{key}/index.html")
 | 
			
		||||
| 
						 | 
				
			
			@ -149,50 +140,42 @@ def rss(_items=meta_data):
 | 
			
		|||
        _fe.link(href=f"https://stefan.works/blog/{key}/index.html")
 | 
			
		||||
        _fe.pubDate(pubDate=_tz.localize(meta_data[key]))
 | 
			
		||||
    _fg.rss_str(pretty=True)
 | 
			
		||||
    _fg.rss_file('./static/rss.xml')
 | 
			
		||||
    return send_from_directory(
 | 
			
		||||
        os.path.join(
 | 
			
		||||
            app.root_path,
 | 
			
		||||
            'static'
 | 
			
		||||
            ),
 | 
			
		||||
        'rss.xml'
 | 
			
		||||
        )
 | 
			
		||||
    _fg.rss_file("./static/rss.xml")
 | 
			
		||||
 | 
			
		||||
    return send_from_directory(os.path.join(app.root_path, "static"), "rss.xml")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.route('/favicon.ico')
 | 
			
		||||
@app.route("/favicon.ico")
 | 
			
		||||
def favicon():
 | 
			
		||||
    ''' Provides favicon.
 | 
			
		||||
    '''
 | 
			
		||||
    return send_from_directory(
 | 
			
		||||
        os.path.join(
 | 
			
		||||
            app.root_path,
 | 
			
		||||
            'static'
 | 
			
		||||
            ),
 | 
			
		||||
        'favicon.ico'
 | 
			
		||||
        )
 | 
			
		||||
    """Provides favicon."""
 | 
			
		||||
 | 
			
		||||
    return send_from_directory(os.path.join(app.root_path, "static"), "favicon.ico")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.errorhandler(404)
 | 
			
		||||
def page_not_found(_error):
 | 
			
		||||
    ''' Error Handling.
 | 
			
		||||
    """Error Handling.
 | 
			
		||||
    Error 404
 | 
			
		||||
    '''
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    return render_template("/status_code/404.html", colors=colors), 404
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.errorhandler(400)
 | 
			
		||||
def bad_request(_error):
 | 
			
		||||
    ''' Error Handling.
 | 
			
		||||
    """Error Handling.
 | 
			
		||||
    Error 400
 | 
			
		||||
    '''
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    return render_template("/status_code/400.html", colors=colors), 400
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.errorhandler(500)
 | 
			
		||||
def internal_server_error(_error):
 | 
			
		||||
    ''' Error Handling.
 | 
			
		||||
    """Error Handling.
 | 
			
		||||
    Error 500
 | 
			
		||||
    '''
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    return render_template("/status_code/500.html", colors=colors), 500
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 253 KiB  | 
| 
						 | 
				
			
			@ -1,2 +1,2 @@
 | 
			
		|||
<?xml version='1.0' encoding='UTF-8'?>
 | 
			
		||||
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"><channel><title>Website of Stefan Friese</title><link>https://stefan.works</link><description>test</description><atom:link href="https://stefan.works" rel="self"/><docs>http://www.rssboard.org/rss-specification</docs><generator>python-feedgen</generator><language>en-us</language><lastBuildDate>Wed, 11 Oct 2023 19:32:42 +0000</lastBuildDate><item><title>Restoring (NT)Backups From a SCSI Tape Drive</title><link>https://stefan.works/blog/Restoring (NT)Backups From a SCSI Tape Drive/index.html</link><guid isPermaLink="false">https://stefan.works/blog/Restoring (NT)Backups From a SCSI Tape Drive/index.html</guid><pubDate>Wed, 27 Sep 2023 00:00:00 +0200</pubDate></item><item><title>The Joy of One-Liners</title><link>https://stefan.works/blog/The Joy of One-Liners/index.html</link><guid isPermaLink="false">https://stefan.works/blog/The Joy of One-Liners/index.html</guid><pubDate>Sun, 29 May 2022 00:00:00 +0200</pubDate></item><item><title>Keep It Simple</title><link>https://stefan.works/blog/Keep It Simple/index.html</link><guid isPermaLink="false">https://stefan.works/blog/Keep It Simple/index.html</guid><pubDate>Tue, 01 Jun 2021 00:00:00 +0200</pubDate></item></channel></rss>
 | 
			
		||||
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"><channel><title>Website of Stefan Friese</title><link>https://stefan.works</link><description>test</description><atom:link href="https://stefan.works" rel="self"/><docs>http://www.rssboard.org/rss-specification</docs><generator>python-feedgen</generator><language>en-us</language><lastBuildDate>Sun, 20 Jul 2025 22:08:29 +0000</lastBuildDate><item><title>Directory Writeup — TryHackMe</title><link>https://stefan.works/blog/Directory Writeup — TryHackMe/index.html</link><guid isPermaLink="false">https://stefan.works/blog/Directory Writeup — TryHackMe/index.html</guid><pubDate>Sun, 20 Jul 2025 00:00:00 +0200</pubDate></item><item><title>Restoring (NT)Backups From a SCSI Tape Drive</title><link>https://stefan.works/blog/Restoring (NT)Backups From a SCSI Tape Drive/index.html</link><guid isPermaLink="false">https://stefan.works/blog/Restoring (NT)Backups From a SCSI Tape Drive/index.html</guid><pubDate>Wed, 27 Sep 2023 00:00:00 +0200</pubDate></item><item><title>The Joy of One-Liners</title><link>https://stefan.works/blog/The Joy of One-Liners/index.html</link><guid isPermaLink="false">https://stefan.works/blog/The Joy of One-Liners/index.html</guid><pubDate>Sun, 29 May 2022 00:00:00 +0200</pubDate></item><item><title>Keep It Simple</title><link>https://stefan.works/blog/Keep It Simple/index.html</link><guid isPermaLink="false">https://stefan.works/blog/Keep It Simple/index.html</guid><pubDate>Tue, 01 Jun 2021 00:00:00 +0200</pubDate></item></channel></rss>
 | 
			
		||||
| 
						 | 
				
			
			@ -4,7 +4,5 @@
 | 
			
		|||
    {{ super() }}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
{% block content %}
 | 
			
		||||
My name is Stefan Friese. I am fascinated by computers since I first saw my Dad working on the ZX Spectrumn. For me, the greatest thing is to learn something new. I like music, engineering, art, design and security CTFs. I write blog entries on my journey, so I’ll be able to look stuff up, remember and share it with you and students at work.<p></p><div class="contact";><script  src="https://tryhackme.com/badge/502760"></script><p></p></div>
 | 
			
		||||
My name is Stefan Etringer. I am fascinated by computers since I first saw my Dad working on the ZX Spectrumn. For me, the greatest thing is to learn something new. I like music, engineering, art, design and security CTFs. I write blog entries on my journey, so I’ll be able to look stuff up, remember and share it with you and students at work.<p></p><div class="contact";><script  src="https://tryhackme.com/badge/502760"></script><p></p></div>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,7 @@
 | 
			
		|||
        <title>{% block title %}Stefan's Blog{% endblock %}</title>
 | 
			
		||||
        <meta name="viewport" content="width=device-width, initial-scale=1">
 | 
			
		||||
    <div class="menu">
 | 
			
		||||
    <a href="{{ url_for('index') }}" style="text-decoration:none">Stefan Friese's Website</a>
 | 
			
		||||
    <a href="{{ url_for('index') }}" style="text-decoration:none">Stefan Etringer's Website</a>
 | 
			
		||||
    </div>
 | 
			
		||||
    <style>
 | 
			
		||||
        /* Stylesheet 1 */
 | 
			
		||||
| 
						 | 
				
			
			@ -44,7 +44,7 @@
 | 
			
		|||
    <hr/>
 | 
			
		||||
<p></p>
 | 
			
		||||
    <center>
 | 
			
		||||
            © Stefan Friese
 | 
			
		||||
            © Stefan Etringer
 | 
			
		||||
    </center>
 | 
			
		||||
            {% endblock %}
 | 
			
		||||
        </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue