1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
|
\documentclass[notes]{beamer}
\usetheme{Rochester}
\usecolortheme{seagull}
\usepackage{svg}
\usepackage[export]{adjustbox}
% \setbeameroption{show notes}
\title{CTF — GNU Guix storefile mistake}
\begin{document}
\frame{
\titlepage
\begin{figure}[h]
\includesvg[height=0.25\textheight]{Guix_logo_with_flag.svg}
\end{figure}
}
\begin{frame}{Functional package management in a pill}
\begin{itemize}
\item Dolstra, Eelco (2006). ``The Purely Functional Software Deployment
Model'' (Ph.D.). Utrecht University
\item pioneered by Nix \includesvg[height=\baselineskip]{Nix_logo.svg}
\item also employed by GNU Guix
\includesvg[height=\baselineskip]{Guix_logo.svg}
\item no Filesystem Hierarchy Standard (no /usr/bin, /usr/share, etc.)
\item packages live in a \textbf{store} directory, e.g.
\begin{itemize}
\item /gnu/store/y0d8ab1mi6lh0a3vpx5lyd4ksq9wbn4x-orc-0.4.32
\item /gnu/store/9pypr3c3y379shbwm9ilb4pik9mkfd83-mesa-22.2.4
\item /gnu/store/rv91v4s30kcjh7xq6k4l2njklk79frxk-freeglut-3.4.0
\item /gnu/store/30zfbjasrsk2wg8nhsd1xgi3q3n9796z-less-608
\end{itemize}
\item a daemon \includesvg[height=\baselineskip]{Awesome_Demon.svg} builds
packages from definitions and puts them in the store
\end{itemize}
\end{frame}
\note{
\begin{itemize}
\item we're using GNU Guix here (no, not the trademarked GUIX…)
\item store filename determine by hash of package inputs + definition
\item multiple versions of a package can coexist
\item per-project development environments
\item easy rollbacks
\item emphasis on reproducible builds
\end{itemize}
}
\begin{frame}[fragile]{Functional package management in a pill (sample package)}
\small
\begin{verbatim}
$ cd /gnu/store/30zfbjasrsk2wg8nhsd1xgi3q3n9796z-less-608/
$ find . -type f
./bin/less
./bin/lessecho
./bin/lesskey
./etc/ld.so.cache
./share/doc/less-608/LICENSE
./share/doc/less-608/COPYING
./share/man/man1/lessecho.1.gz
./share/man/man1/lesskey.1.gz
./share/man/man1/less.1.gz
$ ls -lh bin/less
-r-xr-xr-x 2 root root 192K Jan 1 1970 bin/less
\end{verbatim}
\end{frame}
\note{
\begin{itemize}
\item store is read-only (only Nix/Guix daemon can write)
\item store files are root-owned and world-readable => secrets must be managed
differently
\item dates set to Epoch (but ls -lch shows real creation time)
\item the same package won't be built twice, even if requested by multiple
users
\item a package will built again (or grafted) when one of its dependencies
gets updated
\item a package not in use can be garbage-collected
\item no support for quotas yet as of 2024
\end{itemize}
}
\begin{frame}[fragile]{Functional package management in a pill (declarative OS)}
\begin{itemize}
\item \textbf{packages} are defined declaratively
\pause
\item \textbf{services} are defined declaratively as well
\pause
\item service \textbf{configurations} are defined declaratively \textit{as
well}… {\small
\begin{verbatim}
(service httpd-service-type
(httpd-configuration
(config
(httpd-config-file
(server-name "www.example.com")
(document-root "/var/public_html")))))
\end{verbatim}
}
\begin{itemize}
\item …and result in store files like
/gnu/store/54ywa5x1b75simbvzhxqkfxsjk040ail-httpd.conf
\end{itemize}
\item Yay, we can replace Ansible! But what about secrets?
\begin{itemize}
\item option 1: keep private keys and passwords outside the store
\item option 2: put them encrypted in the store
\end{itemize}
\end{itemize}
\end{frame}
\note{
\begin{itemize}
\item GNU Guix and Nix have their DSLs (the first one is actually Scheme Lisp
+ some APIs)
\item on Guix/Nix server packages and configurations are immutable (we can
switch to different ones but not alter the existing ones) — convenient
\item an application may require database credentials, some API token, a
private key for TLS certificate, etc.
\item encrypted secrets in store — one master key kept outside the store
\end{itemize}
}
\begin{frame}{Sensitive information exposure scenario}
challenge — password hunt in /gnu/store\\~\\
\textit{``You're an employee of a secret government agency. Analysis of
wiretap recordings have lead the agency to believe that an individual known
as Abdul Al-Inh-Ohn-Ih has come into possession of highly classified
government documents. If this turn out true and Abdul blows the whistle on
information from those materials, years of intelligence efforts shall be
ruined.\\~\\}
\textit{Abdul has been using the Matrix protocol for some of his
communication. Your current task is to get access to his Matrix account.
Start your investigation by taking a look at his blog.''}
\end{frame}
\note{
A user of certain shared GNU Guix system has put a secret (a password) in
/gnu/store by mistake. The CTF competitioneer has to SSH into another account
on said system and find the password.
\begin{itemize}
\item we have some lore
\item real-world references might be intended or not…
\item no direct info about the exposures (one needs to figure this out)
\end{itemize}
}
\begin{frame}{Investigation (Abdul's blog)}
\includegraphics[
height=\dimexpr\textheight-0.5cm\relax,
center
]{screenshots/abdul-blog-index.png}
\end{frame}
\note{
\begin{itemize}
\item language — itself a hint Abdul is likely to make mistakes
\item only the few relevant blog entries (no misleading of competitioneers)
\item mechanics of Guix relevant to the challenge are touched in the posts
\item some extra effort required — obtaining a Gemini browser
\end{itemize}
}
\begin{frame}[fragile]{Investigation (peeking through Gemini)}
\includegraphics[
height=\dimexpr\textheight-0.5cm\relax,
center
]{screenshots/gemini-capsule.png}
\end{frame}
\note{
\begin{itemize}
\item most relevant parts of blog only accessible through Gemini (a lightweight
alternative to HTTP)
\item a Gemini browser ``Lagrage'' recommended in HTTP part of Abdul's blog
\end{itemize}
}
\begin{frame}[fragile]{Investigation (Spotting mistakes)}
configuration which hits a mistake is included in Abdul's blog
\footnotesize
\begin{verbatim}
;;; ...
(list (shepherd-service
(provision '(mattermost))
(modules '((shepherd support))) ;for '%user-log-dir'
(start #~(make-forkexec-constructor
'(#$(file-append matterbridge "/bin/matterbridge")
"--conf"
#$(local-file "config.toml"))
#:log-file (string-append %user-log-dir
"/matterbridge.log")))
(stop #~(make-kill-destructor))
(documentation "Start local matterbridge.")))))
;;; ...
\end{verbatim}
\end{frame}
\note{
\begin{itemize}
\item the config suggests Matrix password is in config.toml in /gnu/store
\end{itemize}
}
\begin{frame}{Investigation (Account creation)}
\includegraphics[
height=\dimexpr\textheight-0.5cm\relax,
center
]{screenshots/account-creation.png}
\end{frame}
\note{
\begin{itemize}
\item both Abdul's blog and the server's main website urge one to make an
account and log in to the tilde server with SSH
\item emails entered not actually used
\end{itemize}
}
\begin{frame}{Hint 1}
\includegraphics[
height=\dimexpr\textheight-0.5cm\relax,
center
]{screenshots/hint1.png}
\end{frame}
\note{
\begin{itemize}
\item page with the hint accessible through Gemini only
\end{itemize}
}
\begin{frame}{Hint 2}
\includegraphics[
height=\dimexpr\textheight-0.5cm\relax,
center
]{screenshots/hint2.png}
\end{frame}
\note{
\begin{itemize}
\item link to GNU Guix HTML documentation
\item suggestion that it has sth to do with the local-file macro (used in
Abdul's code)
\end{itemize}
}
\begin{frame}[fragile]{Finding the flag}
\begin{verbatim}
~$ (cd /gnu/store && ls -cht *config.toml*)
qmdh299prllp4fygw893w00lv9ypi5z2-config.toml
~$
\end{verbatim}
rather expected contents of qmdh299prllp4fygw893w00lv9ypi5z2-config.toml
\small
\begin{verbatim}
# ...
[matrix.noevil-pl]
Server="https://matrix.noevil.pl"
Login="abdul"
Password="fla\u0067{full_source-bootstrap}"
RemoteNickFormat="[{PROTOCOL}] <{NICK}> "
NoHomeServerSuffix=false
# ...
\end{verbatim}
\end{frame}
\note{
\begin{itemize}
\item ``g'' in flag replaced with unicode escape to make bypassing with
recursive grepping harder
\end{itemize}
}
\begin{frame}{Credits}
\begin{itemize}
\item GNU Guix logo — \copy 2015 Luis Felipe López Acevedo (CC BY-SA 4.0
International)
\item red flag — by Wikipedia user Wereon, uploaded 2007 (released into
public domain)
\item Nix logo — \copy 2016 Tim Cuthbertson (CC BY-SA 4.0 International)
\item Awesome Demon — by Openclipart user qubodup, uploaded 2014 (released
into public domain with CC Zero v1.0)
\end{itemize}
\end{frame}
\end{document}
|